diff --git a/.editorconfig b/.editorconfig index 519d33713d5..21fdeaf68ef 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,15 +9,16 @@ tab_width = 4 ij_continuation_indent_size = 8 ij_formatter_off_tag = @formatter:off ij_formatter_on_tag = @formatter:on -ij_formatter_tags_enabled = false +ij_formatter_tags_enabled = true ij_smart_tabs = false -ij_visual_guides = none +ij_visual_guides = ij_wrap_on_typing = 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_block_comment_add_space = false ij_css_brace_placement = end_of_line ij_css_enforce_quotes_on_format = false ij_css_hex_color_long_format = false @@ -33,17 +34,6 @@ ij_css_space_before_opening_brace = true ij_css_use_double_quotes = true ij_css_value_alignment = do_not_align -[*.feature] -indent_size = 2 -ij_gherkin_keep_indents_on_empty_lines = false - -[*.gsp] -ij_gsp_keep_indents_on_empty_lines = false - -[*.haml] -indent_size = 2 -ij_haml_keep_indents_on_empty_lines = false - [*.java] ij_java_align_consecutive_assignments = false ij_java_align_consecutive_variable_declarations = false @@ -53,6 +43,7 @@ ij_java_align_multiline_array_initializer_expression = false ij_java_align_multiline_assignment = false ij_java_align_multiline_binary_operation = false ij_java_align_multiline_chained_methods = false +ij_java_align_multiline_deconstruction_list_components = true ij_java_align_multiline_extends_list = false ij_java_align_multiline_for = true ij_java_align_multiline_method_parentheses = false @@ -66,6 +57,7 @@ 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_align_types_in_multi_catch = true ij_java_annotation_parameter_wrap = off ij_java_array_initializer_new_line_after_left_brace = false ij_java_array_initializer_right_brace_on_new_line = false @@ -90,7 +82,9 @@ 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_add_space = false ij_java_block_comment_at_first_column = true +ij_java_builder_methods = ij_java_call_parameters_new_line_after_left_paren = false ij_java_call_parameters_right_paren_on_new_line = false ij_java_call_parameters_wrap = off @@ -98,10 +92,12 @@ 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_count_to_use_import_on_demand = 9999 ij_java_class_names_in_javadoc = 1 +ij_java_deconstruction_list_wrap = normal ij_java_do_not_indent_top_level_class_members = false ij_java_do_not_wrap_after_single_annotation = false +ij_java_do_not_wrap_after_single_annotation_in_parameter = false ij_java_do_while_brace_force = never ij_java_doc_add_blank_line_after_description = true ij_java_doc_add_blank_line_after_param_comments = false @@ -122,18 +118,32 @@ 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_prefix = ij_java_entity_dd_suffix = EJB +ij_java_entity_eb_prefix = ij_java_entity_eb_suffix = Bean +ij_java_entity_hi_prefix = 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_li_suffix = ij_java_entity_pk_class = java.lang.String +ij_java_entity_ri_prefix = +ij_java_entity_ri_suffix = +ij_java_entity_vo_prefix = ij_java_entity_vo_suffix = VO ij_java_enum_constants_wrap = off +ij_java_enum_field_annotation_wrap = off ij_java_extends_keyword_wrap = off ij_java_extends_list_wrap = off ij_java_field_annotation_wrap = split_into_lines +ij_java_field_name_prefix = +ij_java_field_name_suffix = +ij_java_filter_class_prefix = +ij_java_filter_class_suffix = +ij_java_filter_dd_prefix = +ij_java_filter_dd_suffix = ij_java_finally_on_new_line = false ij_java_for_brace_force = never ij_java_for_statement_new_line_after_left_paren = false @@ -150,6 +160,7 @@ ij_java_keep_blank_lines_before_right_brace = 2 ij_java_keep_blank_lines_between_package_declaration_and_header = 2 ij_java_keep_blank_lines_in_code = 2 ij_java_keep_blank_lines_in_declarations = 2 +ij_java_keep_builder_methods_indents = false ij_java_keep_control_statement_in_one_line = true ij_java_keep_first_column_comment = true ij_java_keep_indents_on_empty_lines = false @@ -164,8 +175,15 @@ 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_add_space_on_reformat = false ij_java_line_comment_at_first_column = true +ij_java_listener_class_prefix = +ij_java_listener_class_suffix = +ij_java_local_variable_name_prefix = +ij_java_local_variable_name_suffix = +ij_java_message_dd_prefix = ij_java_message_dd_suffix = EJB +ij_java_message_eb_prefix = ij_java_message_eb_suffix = Bean ij_java_method_annotation_wrap = split_into_lines ij_java_method_brace_style = end_of_line @@ -174,16 +192,23 @@ ij_java_method_parameters_new_line_after_left_paren = false ij_java_method_parameters_right_paren_on_new_line = false ij_java_method_parameters_wrap = off ij_java_modifier_list_wrap = false +ij_java_multi_catch_types_wrap = normal ij_java_names_count_to_use_import_on_demand = 3 +ij_java_new_line_after_lparen_in_annotation = false +ij_java_new_line_after_lparen_in_deconstruction_pattern = true ij_java_new_line_after_lparen_in_record_header = false +ij_java_new_line_when_body_is_presented = false ij_java_packages_to_use_import_on_demand = java.awt.*,javax.swing.* ij_java_parameter_annotation_wrap = off +ij_java_parameter_name_prefix = +ij_java_parameter_name_suffix = ij_java_parentheses_expression_new_line_after_left_paren = false ij_java_parentheses_expression_right_paren_on_new_line = false ij_java_place_assignment_sign_on_next_line = false ij_java_prefer_longer_names = true ij_java_prefer_parameters_wrap = false ij_java_record_components_wrap = normal +ij_java_repeat_annotations = ij_java_repeat_synchronized = true ij_java_replace_instanceof_and_cast = false ij_java_replace_null_check = true @@ -191,13 +216,26 @@ ij_java_replace_sum_lambda_with_method_ref = true ij_java_resource_list_new_line_after_left_paren = false ij_java_resource_list_right_paren_on_new_line = false ij_java_resource_list_wrap = off +ij_java_rparen_on_new_line_in_annotation = false +ij_java_rparen_on_new_line_in_deconstruction_pattern = true ij_java_rparen_on_new_line_in_record_header = false +ij_java_servlet_class_prefix = +ij_java_servlet_class_suffix = +ij_java_servlet_dd_prefix = +ij_java_servlet_dd_suffix = +ij_java_session_dd_prefix = ij_java_session_dd_suffix = EJB +ij_java_session_eb_prefix = ij_java_session_eb_suffix = Bean +ij_java_session_hi_prefix = 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_li_suffix = +ij_java_session_ri_prefix = +ij_java_session_ri_suffix = +ij_java_session_si_prefix = ij_java_session_si_suffix = Service ij_java_space_after_closing_angle_bracket_in_type_argument = false ij_java_space_after_colon = true @@ -216,6 +254,7 @@ 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_deconstruction_list = false ij_java_space_before_do_left_brace = true ij_java_space_before_else_keyword = true ij_java_space_before_else_left_brace = true @@ -246,6 +285,7 @@ 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_annotation_eq = true ij_java_spaces_around_assignment_operators = true ij_java_spaces_around_bitwise_operators = true ij_java_spaces_around_equality_operators = true @@ -264,6 +304,7 @@ 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_deconstruction_list = false ij_java_spaces_within_for_parentheses = false ij_java_spaces_within_if_parentheses = false ij_java_spaces_within_method_call_parentheses = false @@ -275,9 +316,14 @@ 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_static_field_name_prefix = +ij_java_static_field_name_suffix = +ij_java_subclass_name_prefix = ij_java_subclass_name_suffix = Impl +ij_java_switch_expressions_wrap = normal ij_java_ternary_operation_signs_on_next_line = false ij_java_ternary_operation_wrap = off +ij_java_test_name_prefix = ij_java_test_name_suffix = Test ij_java_throws_keyword_wrap = off ij_java_throws_list_wrap = off @@ -292,12 +338,14 @@ ij_java_while_on_new_line = false ij_java_wrap_comments = false ij_java_wrap_first_method_in_call_chain = false ij_java_wrap_long_lines = false +ij_java_wrap_semicolon_after_call_chain = false [*.less] indent_size = 2 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_block_comment_add_space = false ij_less_brace_placement = 0 ij_less_enforce_quotes_on_format = false ij_less_hex_color_long_format = false @@ -307,12 +355,27 @@ 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_line_comment_add_space = false +ij_less_line_comment_at_first_column = 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 +[*.proto] +indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 4 +ij_protobuf_keep_blank_lines_in_code = 2 +ij_protobuf_keep_indents_on_empty_lines = false +ij_protobuf_keep_line_breaks = true +ij_protobuf_space_after_comma = true +ij_protobuf_space_before_comma = false +ij_protobuf_spaces_around_assignment_operators = true +ij_protobuf_spaces_within_braces = false +ij_protobuf_spaces_within_brackets = false + [*.sass] indent_size = 2 ij_sass_align_closing_brace_with_properties = false @@ -327,6 +390,8 @@ 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_line_comment_add_space = false +ij_sass_line_comment_at_first_column = 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 @@ -338,6 +403,7 @@ indent_size = 2 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_block_comment_add_space = false ij_scss_brace_placement = 0 ij_scss_enforce_quotes_on_format = false ij_scss_hex_color_long_format = false @@ -347,31 +413,24 @@ 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_line_comment_add_space = false +ij_scss_line_comment_at_first_column = 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] +[*.vue] indent_size = 2 -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 +tab_width = 2 +ij_continuation_indent_size = 4 +ij_vue_indent_children_of_top_level = template +ij_vue_interpolation_new_line_after_start_delimiter = true +ij_vue_interpolation_new_line_before_end_delimiter = true +ij_vue_interpolation_wrap = off +ij_vue_keep_indents_on_empty_lines = false +ij_vue_spaces_within_interpolation_expressions = true [.editorconfig] ij_editorconfig_align_group_field_declarations = false @@ -381,10 +440,11 @@ ij_editorconfig_space_before_colon = false ij_editorconfig_space_before_comma = false ij_editorconfig_spaces_around_assignment_operators = true -[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.pom,*.qrc,*.rng,*.tld,*.wadl,*.wsdd,*.wsdl,*.xjb,*.xml,*.xsd,*.xsl,*.xslt,*.xul}] +[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.pom,*.rng,*.tld,*.wadl,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul}] ij_xml_align_attributes = true ij_xml_align_text = false ij_xml_attribute_wrap = normal +ij_xml_block_comment_add_space = false ij_xml_block_comment_at_first_column = true ij_xml_keep_blank_lines = 2 ij_xml_keep_indents_on_empty_lines = false @@ -398,9 +458,8 @@ 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 = false -[{*.ats,*.ts}] +[{*.ats,*.cts,*.mts,*.ts}] ij_continuation_indent_size = 4 ij_typescript_align_imports = false ij_typescript_align_multiline_array_initializer_expression = false @@ -429,6 +488,8 @@ 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_block_comment_add_space = false +ij_typescript_block_comment_at_first_column = true 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 @@ -439,6 +500,7 @@ 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_enum_constants_wrap = on_every_item ij_typescript_extends_keyword_wrap = off ij_typescript_extends_list_wrap = off ij_typescript_field_prefix = _ @@ -477,6 +539,7 @@ 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_object_types_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 @@ -485,6 +548,7 @@ 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_property_prefix = ij_typescript_reformat_c_style_comments = false ij_typescript_space_after_colon = true ij_typescript_space_after_comma = true @@ -559,7 +623,8 @@ 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_explicit_js_extension = auto +ij_typescript_use_import_type = auto ij_typescript_use_path_mapping = always ij_typescript_use_public_modifier = false ij_typescript_use_semicolon_after_statement = true @@ -576,6 +641,7 @@ ij_shell_keep_column_alignment_padding = false ij_shell_minify_program = false ij_shell_redirect_followed_by_space = false ij_shell_switch_cases_indented = false +ij_shell_use_unix_line_separator = true [{*.cjs,*.js}] ij_continuation_indent_size = 4 @@ -604,6 +670,8 @@ 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_block_comment_add_space = false +ij_javascript_block_comment_at_first_column = true ij_javascript_call_parameters_new_line_after_left_paren = false ij_javascript_call_parameters_right_paren_on_new_line = false ij_javascript_call_parameters_wrap = off @@ -651,6 +719,7 @@ ij_javascript_method_parameters_new_line_after_left_paren = false ij_javascript_method_parameters_right_paren_on_new_line = false ij_javascript_method_parameters_wrap = off ij_javascript_object_literal_wrap = on_every_item +ij_javascript_object_types_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 @@ -659,6 +728,7 @@ 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_property_prefix = ij_javascript_reformat_c_style_comments = false ij_javascript_space_after_colon = true ij_javascript_space_after_comma = true @@ -733,7 +803,8 @@ ij_javascript_ternary_operation_wrap = off ij_javascript_union_types_wrap = on_every_item ij_javascript_use_chained_calls_group_indents = false ij_javascript_use_double_quotes = true -ij_javascript_use_explicit_js_extension = global +ij_javascript_use_explicit_js_extension = auto +ij_javascript_use_import_type = auto ij_javascript_use_path_mapping = always ij_javascript_use_public_modifier = false ij_javascript_use_semicolon_after_statement = true @@ -742,107 +813,16 @@ ij_javascript_while_brace_force = never ij_javascript_while_on_new_line = false ij_javascript_wrap_comments = false -[{*.cjsx,*.coffee}] +[{*.erb,*.rhtml}] indent_size = 2 tab_width = 2 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 +ij_rhtml_keep_indents_on_empty_lines = false [{*.ft,*.vm,*.vsl}] ij_vtl_keep_indents_on_empty_lines = false -[{*.gant,*.gradle,*.groovy,*.gson,*.gy}] +[{*.gant,*.groovy,*.gy}] ij_groovy_align_group_field_declarations = false ij_groovy_align_multiline_array_initializer_expression = false ij_groovy_align_multiline_assignment = false @@ -877,6 +857,7 @@ 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_add_space = false 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 @@ -887,6 +868,7 @@ 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_enable_groovydoc_formatting = true ij_groovy_enum_constants_wrap = off ij_groovy_extends_keyword_wrap = off ij_groovy_extends_list_wrap = off @@ -896,6 +878,12 @@ 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_ginq_general_clause_wrap_policy = 2 +ij_groovy_ginq_having_wrap_policy = 1 +ij_groovy_ginq_indent_having_clause = true +ij_groovy_ginq_indent_on_clause = true +ij_groovy_ginq_on_wrap_policy = 1 +ij_groovy_ginq_space_after_keyword = true ij_groovy_if_brace_force = never ij_groovy_import_annotation_wrap = 2 ij_groovy_imports_layout = *,|,javax.**,java.**,|,$* @@ -919,6 +907,7 @@ 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_add_space_on_reformat = 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 @@ -928,6 +917,7 @@ 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_packages_to_use_import_on_demand = java.awt.*,javax.swing.* 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 @@ -966,6 +956,7 @@ 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_record_parentheses = false ij_groovy_space_before_switch_left_brace = true ij_groovy_space_before_switch_parentheses = true ij_groovy_space_before_synchronized_left_brace = true @@ -1019,9 +1010,99 @@ ij_groovy_use_single_class_imports = true ij_groovy_variable_annotation_wrap = off ij_groovy_while_brace_force = never ij_groovy_while_on_new_line = false +ij_groovy_wrap_chain_calls_after_dot = false ij_groovy_wrap_long_lines = false -[{*.gradle.kts,*.kt,*.kts,*.main.kts}] +[{*.gemspec,*.jbuilder,*.rake,*.rb,*.rbi,*.rbw,*.ru,*.thor,.simplecov,capfile,gemfile,guardfile,isolate,rakefile,steepfile,vagrantfile}] +ij_ruby_align_group_field_declarations = false +ij_ruby_align_multiline_parameters = true +ij_ruby_blank_lines_around_class = 1 +ij_ruby_blank_lines_around_method = 1 +ij_ruby_chain_calls_alignment = 2 +ij_ruby_convert_brace_block_by_enter = true +ij_ruby_empty_declarations_style = 1 +ij_ruby_force_newlines_around_visibility_mods = true +ij_ruby_indent_private_methods = false +ij_ruby_indent_protected_methods = false +ij_ruby_indent_public_methods = false +ij_ruby_indent_visibility_modifiers = true +ij_ruby_indent_when_cases = false +ij_ruby_keep_blank_lines_in_code = 1 +ij_ruby_keep_blank_lines_in_declarations = 1 +ij_ruby_keep_line_breaks = true +ij_ruby_parentheses_around_method_arguments = true +ij_ruby_spaces_around_assignment_operators = true +ij_ruby_spaces_around_hashrocket = true +ij_ruby_spaces_around_other_operators = true +ij_ruby_spaces_around_pow_operators = true +ij_ruby_spaces_around_range_operators = false +ij_ruby_spaces_around_relational_operators = true +ij_ruby_spaces_within_array_initializer_braces = true +ij_ruby_spaces_within_braces = true +ij_ruby_spaces_within_pipes = false +ij_ruby_use_external_formatter = false + +[{*.har,*.jsb2,*.jsb3,*.json,*.jsonc,*.postman_collection,*.postman_collection.json,*.postman_environment,*.postman_environment.json,.babelrc,.eslintrc,.prettierrc,.stylelintrc,.ws-context,bowerrc,brakeman.ignore,jest.config}] +indent_size = 2 +ij_json_array_wrapping = split_into_lines +ij_json_keep_blank_lines_in_code = 0 +ij_json_keep_indents_on_empty_lines = false +ij_json_keep_line_breaks = true +ij_json_keep_trailing_comma = false +ij_json_object_wrapping = split_into_lines +ij_json_property_alignment = do_not_align +ij_json_space_after_colon = true +ij_json_space_after_comma = true +ij_json_space_before_colon = false +ij_json_space_before_comma = false +ij_json_spaces_within_braces = false +ij_json_spaces_within_brackets = false +ij_json_wrap_long_lines = false + +[{*.htm,*.html,*.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_add_space = false +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 + +[{*.http,*.rest}] +indent_size = 0 +ij_continuation_indent_size = 4 +ij_http-request_call_parameters_wrap = normal +ij_http-request_method_parameters_wrap = split_into_lines +ij_http-request_space_before_comma = true +ij_http-request_spaces_around_assignment_operators = true + +[{*.jsf,*.jsp,*.jspf,*.tag,*.tagf,*.xjsp}] +ij_jsp_jsp_prefer_comma_separated_import_list = false +ij_jsp_keep_indents_on_empty_lines = false + +[{*.jspx,*.tagx}] +ij_jspx_keep_indents_on_empty_lines = false + +[{*.kt,*.kts}] ij_kotlin_align_in_columns_case_branch = false ij_kotlin_align_multiline_binary_operation = false ij_kotlin_align_multiline_extends_list = false @@ -1030,29 +1111,30 @@ ij_kotlin_align_multiline_parameters = true ij_kotlin_align_multiline_parameters_in_calls = false ij_kotlin_allow_trailing_comma = false ij_kotlin_allow_trailing_comma_on_call_site = false -ij_kotlin_assignment_wrap = off +ij_kotlin_assignment_wrap = normal ij_kotlin_blank_lines_after_class_header = 0 ij_kotlin_blank_lines_around_block_when_branches = 0 ij_kotlin_blank_lines_before_declaration_with_comment_or_annotation_on_separate_line = 1 +ij_kotlin_block_comment_add_space = false ij_kotlin_block_comment_at_first_column = true -ij_kotlin_call_parameters_new_line_after_left_paren = false -ij_kotlin_call_parameters_right_paren_on_new_line = false -ij_kotlin_call_parameters_wrap = off +ij_kotlin_call_parameters_new_line_after_left_paren = true +ij_kotlin_call_parameters_right_paren_on_new_line = true +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_continuation_indent_for_chained_calls = false +ij_kotlin_continuation_indent_for_expression_bodies = false +ij_kotlin_continuation_indent_in_argument_lists = false +ij_kotlin_continuation_indent_in_elvis = false +ij_kotlin_continuation_indent_in_if_conditions = false +ij_kotlin_continuation_indent_in_parameter_lists = false +ij_kotlin_continuation_indent_in_supertype_lists = false ij_kotlin_else_on_new_line = false ij_kotlin_enum_constants_wrap = off -ij_kotlin_extends_list_wrap = off +ij_kotlin_extends_list_wrap = normal 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_if_rparen_on_new_line = true ij_kotlin_import_nested_classes = false ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^ ij_kotlin_insert_whitespaces_in_simple_one_line_method = true @@ -1063,13 +1145,15 @@ 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_break_after_multiline_when_entry = true ij_kotlin_line_comment_add_space = false +ij_kotlin_line_comment_add_space_on_reformat = false ij_kotlin_line_comment_at_first_column = true ij_kotlin_method_annotation_wrap = split_into_lines -ij_kotlin_method_call_chain_wrap = off -ij_kotlin_method_parameters_new_line_after_left_paren = false -ij_kotlin_method_parameters_right_paren_on_new_line = false -ij_kotlin_method_parameters_wrap = off +ij_kotlin_method_call_chain_wrap = normal +ij_kotlin_method_parameters_new_line_after_left_paren = true +ij_kotlin_method_parameters_right_paren_on_new_line = true +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_packages_to_use_import_on_demand = java.util.*,kotlinx.android.synthetic.**,io.ktor.** @@ -1099,69 +1183,40 @@ 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_expression_body_functions = 1 ij_kotlin_wrap_first_method_in_call_chain = false -[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,jest.config}] -indent_size = 2 -ij_json_keep_blank_lines_in_code = 0 -ij_json_keep_indents_on_empty_lines = false -ij_json_keep_line_breaks = true -ij_json_space_after_colon = true -ij_json_space_after_comma = true -ij_json_space_before_colon = true -ij_json_space_before_comma = false -ij_json_spaces_within_braces = false -ij_json_spaces_within_brackets = false -ij_json_wrap_long_lines = false - -[{*.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 -ij_html_uniform_ident = false - -[{*.jsf,*.jsp,*.jspf,*.tag,*.tagf,*.xjsp}] -ij_jsp_jsp_prefer_comma_separated_import_list = false -ij_jsp_keep_indents_on_empty_lines = false - -[{*.jspx,*.tagx}] -ij_jspx_keep_indents_on_empty_lines = false - [{*.markdown,*.md}] ij_markdown_force_one_space_after_blockquote_symbol = true ij_markdown_force_one_space_after_header_symbol = true ij_markdown_force_one_space_after_list_bullet = true ij_markdown_force_one_space_between_words = true +ij_markdown_format_tables = true +ij_markdown_insert_quote_arrows_on_wrap = true ij_markdown_keep_indents_on_empty_lines = false +ij_markdown_keep_line_breaks_inside_text_blocks = true ij_markdown_max_lines_around_block_elements = 1 ij_markdown_max_lines_around_header = 1 ij_markdown_max_lines_between_paragraphs = 1 ij_markdown_min_lines_around_block_elements = 1 ij_markdown_min_lines_around_header = 1 ij_markdown_min_lines_between_paragraphs = 1 +ij_markdown_wrap_text_if_long = true +ij_markdown_wrap_text_inside_blockquotes = true + +[{*.pb,*.textproto,*.txtpb}] +indent_size = 2 +tab_width = 2 +ij_continuation_indent_size = 4 +ij_prototext_keep_blank_lines_in_code = 2 +ij_prototext_keep_indents_on_empty_lines = false +ij_prototext_keep_line_breaks = true +ij_prototext_space_after_colon = true +ij_prototext_space_after_comma = true +ij_prototext_space_before_colon = false +ij_prototext_space_before_comma = false +ij_prototext_spaces_within_braces = true +ij_prototext_spaces_within_brackets = false [{*.properties,spring.handlers,spring.schemas}] ij_properties_align_group_field_declarations = false @@ -1169,70 +1224,11 @@ ij_properties_keep_blank_lines = false ij_properties_key_value_delimiter = equals ij_properties_spaces_around_key_value_delimiter = false -[{*.py,*.pyw}] -ij_python_align_collections_and_comprehensions = true -ij_python_align_multiline_imports = true -ij_python_align_multiline_parameters = true -ij_python_align_multiline_parameters_in_calls = true -ij_python_blank_line_at_file_end = true -ij_python_blank_lines_after_imports = 1 -ij_python_blank_lines_after_local_imports = 0 -ij_python_blank_lines_around_class = 1 -ij_python_blank_lines_around_method = 1 -ij_python_blank_lines_around_top_level_classes_functions = 2 -ij_python_blank_lines_before_first_method = 0 -ij_python_dict_alignment = 0 -ij_python_dict_new_line_after_left_brace = false -ij_python_dict_new_line_before_right_brace = false -ij_python_dict_wrapping = 1 -ij_python_from_import_new_line_after_left_parenthesis = false -ij_python_from_import_new_line_before_right_parenthesis = false -ij_python_from_import_parentheses_force_if_multiline = false -ij_python_from_import_trailing_comma_if_multiline = false -ij_python_from_import_wrapping = 1 -ij_python_hang_closing_brackets = false -ij_python_keep_blank_lines_in_code = 1 -ij_python_keep_blank_lines_in_declarations = 1 -ij_python_keep_indents_on_empty_lines = false -ij_python_keep_line_breaks = true -ij_python_new_line_after_colon = false -ij_python_new_line_after_colon_multi_clause = true -ij_python_optimize_imports_always_split_from_imports = false -ij_python_optimize_imports_case_insensitive_order = false -ij_python_optimize_imports_join_from_imports_with_same_source = false -ij_python_optimize_imports_sort_by_type_first = true -ij_python_optimize_imports_sort_imports = true -ij_python_optimize_imports_sort_names_in_from_imports = false -ij_python_space_after_comma = true -ij_python_space_after_number_sign = true -ij_python_space_after_py_colon = true -ij_python_space_before_backslash = true -ij_python_space_before_comma = false -ij_python_space_before_for_semicolon = false -ij_python_space_before_lbracket = false -ij_python_space_before_method_call_parentheses = false -ij_python_space_before_method_parentheses = false -ij_python_space_before_number_sign = true -ij_python_space_before_py_colon = false -ij_python_space_within_empty_method_call_parentheses = false -ij_python_space_within_empty_method_parentheses = false -ij_python_spaces_around_additive_operators = true -ij_python_spaces_around_assignment_operators = true -ij_python_spaces_around_bitwise_operators = true -ij_python_spaces_around_eq_in_keyword_argument = false -ij_python_spaces_around_eq_in_named_parameter = false -ij_python_spaces_around_equality_operators = true -ij_python_spaces_around_multiplicative_operators = true -ij_python_spaces_around_power_operator = true -ij_python_spaces_around_relational_operators = true -ij_python_spaces_around_shift_operators = true -ij_python_spaces_within_braces = false -ij_python_spaces_within_brackets = false -ij_python_spaces_within_method_call_parentheses = false -ij_python_spaces_within_method_parentheses = false -ij_python_use_continuation_indent_for_arguments = false -ij_python_use_continuation_indent_for_collection_and_comprehensions = false -ij_python_wrap_long_lines = false +[{*.qute.htm,*.qute.html,*.qute.json,*.qute.txt,*.qute.yaml,*.qute.yml}] +ij_qute_keep_indents_on_empty_lines = false + +[{*.toml,Cargo.lock,Cargo.toml.orig,Gopkg.lock,Pipfile,poetry.lock}] +ij_toml_keep_indents_on_empty_lines = false [{*.yaml,*.yml}] indent_size = 2 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000000..f1a85dfc0d3 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,2 @@ +* @OneLiteFeatherNET/microtus-core +/.github/CODEOWNERS @OneLiteFeatherNET/microtus-core diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 054b0ce92b6..d58243a1ad4 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,28 +1,27 @@ -## How to contribute to Minestom -#### **Did you find a bug?** -* Open a new GitHub issue if it's not already reported. +Contributing to Microtus +======================== -* Explain it clearly, with steps (or code) to reproduce it. +We (the Microtus team) would be very glad if you want to contribute to the project. +The process to contribute requires some guidelines that you need to follow. +These help us to improve the project and maintain a consistent style for each contributor -#### **Did you write some code that fixes a bug?** -* Open a new GitHub pull-request with the commits if it hasn't already been proposed. +## Use a Personal Fork and not an Organization -* Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable. +If you want to contribute to Microtus, please fork the repository to your personal account and not to an organization. +This is because GitHub does not allow to push as maintainer of our fork into a repository from an organization to another organization. +If you fork the repository to an organization, you can open a pr, but we want to accept it. -#### **Do you intend to add a new feature or change an existing one?** -* Do not open a pull-request on GitHub until you have collected positive feedback about the change from a maintainer. +We much prefer to have PRs show as merged, so please do not use repositories +on organizations for PRs. -#### **Do you have questions about the source code?** -* Ask any question about how to use Minestom in the GitHub issues section or the community portals. +See for more information on the +issue. -#### **Do you want to contribute to the Minestom documentation?** -* Feel free to do so! Just make sure to conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification when editing the README.md. +## Requirements -## General Contribution Rules -* By contributing to the Minestom project your code/contribution will be licensed under the [Apache Version 2.0](../LICENSE) license. +To get started with the contributing of change, you will need some additional software. +Most of them can be obtained in (most) package managers on different platforms. -Minestom is a community project. We encourage you to contribute! :) - -Thanks! :heart: :heart: :heart: - -~Minestom Community \ No newline at end of file +- `git` - Version control system +- A Java 21 or later JDK: + - [Adoptium](https://adoptium.net/) has builds for most operating systems \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml new file mode 100644 index 00000000000..118447ff135 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -0,0 +1,52 @@ +name: Report a bug +description: You found a bug? Let us know! +title: "[Bug]: " +labels: [ "type: Bug" ] +body: + - type: markdown + attributes: + value: | + Thank you for reporting a bug to Microtus! + Please fill out the information below to help us understand the issue. + - type: markdown + attributes: + value: | + Before filling in the form fields, please consider the following: + - Ensure that you are using the latest version of Microtus. + - Search for existing issues in the [issue tracker](https://github.com/OneLiteFeatherNET/Microtus/issues) + - type: textarea + attributes: + label: Describe the bug + description: | + A clear and concise description of what the bug is. + If you have a screenshot of the bug, please attach it below. + validations: + required: true + - type: textarea + attributes: + label: Steps to reproduce the bug + description: Tell us exactly how to reproduce the bug you are experiencing + placeholder: | + 1. ... + 2. ... + 3. ... + validations: + required: true + - type: textarea + attributes: + label: Code sample + description: | + Please create a reproducible sample to show us the bug in action and attach it below between the lines with the backticks. + This helps us to verify that the bug is valid and prevents us from having to ask you for a sample later. + + Without this we will unlikely be able to progress on the issue, and because of that + we regretfully will have to close it. + + **Note**: Please do not upload screenshots of text. Instead, use code blocks + or the above mentioned ways to upload your code sample. + value: | + ```java + [Paste your code here] + ``` + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000000..73934b49e28 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,6 @@ +blank_issues_enabled: false +contact_links: + - name: OneLiteFeather Discord + url: https://discord.onelitefeather.net/ + about: Please join our Discord server if you have any questions or concerns. + icon: https://github.com/simple-icons/simple-icons/blob/develop/icons/discord.svg \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml new file mode 100644 index 00000000000..b3dc844df47 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -0,0 +1,33 @@ +name: Feature Request +description: Suggest an idea for this project +title: "[Feature]: " +labels: [ "type: feature" ] +body: + - type: markdown + attributes: + value: | + Thank you for suggesting an idea to make Microtus better! + Please fill out the information below to help us understand your idea. + - type: textarea + attributes: + label: Is your feature request related to a problem? + description: Please give some context for this request. Why do you want it added? + validations: + required: true + - type: textarea + attributes: + label: Describe the solution you'd like + description: Give us a clear description of what you want + validations: + required: true + - type: textarea + attributes: + label: Describe alternatives you've considered + description: A clear and concise description of any alternative solutions or features you've considered. + validations: + required: false + - type: markdown + attributes: + value: | + Before submitting your feature request, please make sure you have done the following: + - [ ] Searched for existing feature requests \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/performance.yml b/.github/ISSUE_TEMPLATE/performance.yml new file mode 100644 index 00000000000..1dfa502cfc5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/performance.yml @@ -0,0 +1,40 @@ +name: Performance Problem +description: Report a performance problem which is related to Microtus +labels: [ "type: needs triage", "type: performance" ] +body: + - type: markdown + attributes: + value: | + Before creating an issue regarding to the performance, please reach out for support on our [Discord](https://discord.onelitefeather.net/) + or in the [Discussions](https://github.com/OneLiteFeatherNET/Microtus/discussions)! + + **Please be aware: Performance issues can sometimes depend on your specific implementation and not on Microtus itself. If the situation is clear and it's not a problem with the project, we will close the issue without any comment.** + - type: input + attributes: + label: Used Microtus version + description: Which version of Microtus are you using? + placeholder: 1.0.0 + validations: + required: true + - type: textarea + attributes: + label: Describe the performance problem + description: If applicable, please describe your issue. + validations: + required: false + - type: textarea + attributes: + label: Other + description: | + Please include other helpful links below. + The more information we receive, the quicker and more effective we can be at finding the solution to the issue. + validations: + required: false + - type: markdown + attributes: + value: | + Before submitting your issue, please make sure you have done the following: + + 1. You are running the latest version of Microtus from [Release page](https://github.com/OneLiteFeatherNET/Microtus/releases) + 2. You searched for and ensured there isn't already an open issue regarding this + 3. Your version of Minecraft is supported by Microtus diff --git a/.github/README.md b/.github/README.md index e5f7b353d05..4175b0ebf2d 100644 --- a/.github/README.md +++ b/.github/README.md @@ -1,112 +1,104 @@ -![banner](banner_dark.png#gh-dark-mode-only) -![banner](banner_light.png#gh-light-mode-only) +# Microtus -# Minestom +[![license](https://img.shields.io/github/license/OneLiteFeatherNET/Microtus?style=for-the-badge&color=b2204c)](../LICENSE) +[![wiki](https://img.shields.io/badge/documentation-wiki-74aad6?style=for-the-badge)](https://wiki.microtus.dev/) -[![license](https://img.shields.io/github/license/Minestom/Minestom?style=for-the-badge&color=b2204c)](../LICENSE) -[![standard-readme compliant](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=for-the-badge)](https://github.com/RichardLitt/standard-readme) -[![javadocs](https://img.shields.io/badge/documentation-javadocs-4d7a97?style=for-the-badge)](https://javadoc.minestom.net) -[![wiki](https://img.shields.io/badge/documentation-wiki-74aad6?style=for-the-badge)](https://wiki.minestom.net/) -[![discord-banner](https://img.shields.io/discord/706185253441634317?label=discord&style=for-the-badge&color=7289da)](https://discord.gg/pkFRvqB) +[Microtus](https://en.wikipedia.org/wiki/Microtus) is a fork of the original minestom. -Minestom is an open-source library that enables developers to create their own Minecraft server software, without any code from Mojang. +Our projects get names of animals but in latin. -The main difference between Mojang's vanilla server and a minestom-based server, is that ours does not contain any features by default! -However, we have a complete API which is designed to allow you to make anything possible, with ease. +Discord for discussion: [OneLiteFeather.net](https://discord.onelitefeather.net) -This is a developer API not meant to be used by end-users. Replacing Bukkit/Forge/Sponge with this **will not work** since we do not implement any of their APIs. +## Our goals +- Include patches from open pull requests on minestom repository +- Fixes issues from original minestom repository +- Make useful decisions + - Include new features + - Try to stay updated with original minecraft cycle +- Release cycle of we often we can (weekly, monthly, etc.) with a changelog, and it needed for the community -# Table of contents -- [Install](#install) -- [Usage](#usage) -- [Why Minestom?](#why-minestom) -- [Advantages & Disadvantages](#advantages-and-disadvantages) -- [API](#api) -- [Credits](#credits) -- [Contributing](#contributing) -- [License](#license) +## Project contribution: -# Install -Minestom is not installed like Bukkit/Forge/Sponge. -As Minestom is a Java library, it must be loaded the same way any other Java library may be loaded. -This means you need to add Minestom as a dependency, add your code and compile by yourself. +For details how you can contribute to the project please read our [Contributing](CONTRIBUTING.md). -Minestom is available on [Maven Central](https://mvnrepository.com/artifact/net.minestom/minestom-snapshots), -and can be installed like the following (Gradle/Groovy): +## Usage of microtus +Since 23.07.2023 we are now official on the maven central for releases and snapshots. +To use Microtus in your projects you need: +
+ Snapshot -```groovy +Please replace the `` with the right one. You can find the versions here: [Central](https://central.sonatype.com/search?q=microtus) +For example: `1.1.0-SNAPSHOT+9284d26` + +### Repositories Section +```kt repositories { - mavenCentral() - maven { url 'https://jitpack.io' } + mavenCentral() + maven("https://oss.sonatype.org/content/repositories/snapshots") } +``` +### Dependency Section +```kt dependencies { - implementation 'net.minestom:minestom-snapshots:' + implementation("net.onelitefeather.microtus:Minestom:1.3.2-SNAPSHOT") + testImplementation("net.onelitefeather.microtus.testing:testing:1.3.2-SNAPSHOT") } ``` +
-# Usage -An example of how to use the Minestom library is available [here](/demo). -Alternatively you can check the official [wiki](https://wiki.minestom.net/) or the [javadocs](https://minestom.github.io/Minestom/). - -# Why Minestom? -Minecraft has evolved a lot since its release, most of the servers today do not take advantage of vanilla features and even have to struggle because of them. -Our target audience is those who want to make a server that benefits little from vanilla features. e.g. creative, kitpvp. -The goal is to offer more performance for those who need it. -In other words, it makes sense to use Minestom when it takes less time to implement every missing vanilla feature you want than removing every vanilla feature that will slow you down. - -# Advantages and Disadvantages -Minestom isn't perfect, our choices make it much better for some cases, worse for some others. - -## Advantages -* Remove the overhead of vanilla features -* Multi-threaded -* Instance system (Collections of blocks and entities) which is much more scalable than worlds -* Open-source -* Modern API -* No more legacy NMS - -## Disadvantages -* Does not work with Bukkit/Forge/Sponge plugins or mods -* Does not work with older clients (using a proxy with ViaBackwards is possible) -* Bad for those who want a vanilla experience -* Longer to develop something playable -* Multi-threaded environments need extra consideration - -# API -Even if we do not include anything by default in the game, we simplify the way you add them, here is a preview. - -## Instances -It is our major concept, worlds are great for survival with friends, but when it scales up it can become unmanageable. The best examples can be found in Skyblock or minigames, not being able to separate each part properly and being forced to save everything in files, not to say the overhead caused by unnecessary data contained in them. Instances are a lightweight solution to it, being able to have every chunk in memory only, copying and sending it to another player in no time, with custom serialization and much more... - -Being able to create instances directly on the go is a must-have, we believe it can push many more projects forward. - -Instances also come with performance benefits, unlike some others which will be fully single-threaded or maybe using one thread per world we are using a set number of threads (pool) to manage all chunks independently from instances, meaning using more CPU power. - -## Blocks -Minestom by default does not know what is a chest, you will have to tell him that it opens an inventory. -Every "special blocks" (which aren't only visual) need a specialized handler. After applying this handler, you have a block that can be placed anywhere simply. -However, all blocks are visually there, they just won't have interaction by default. +
+ Release -## Entities -The terms "passive" or "aggressive" monsters do not exist, nobody stops you from making a flying chicken rushing into any players coming too close, doing so with NMS is a real mess because of obfuscation and the large inheritance. +Please replace the `` with the right one. You can find the versions here: [Central](https://central.sonatype.com/search?q=microtus) +For example: `1.1.0` +### Dependency Section +```kt +dependencies { + implementation("net.onelitefeather.microtus:Microtus:1.4.1") + testImplementation("net.onelitefeather.microtus.testing:testing:1.4.1") +} +``` +
+ +## Extension usage +### settings.gradle.kts +Read more about here: https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-gradle-registry +```kt +pluginManagement { + repositories { + gradlePluginPortal() + maven("https://maven.pkg.github.com/OneLiteFeatherNET/Microtus") { + credentials { + username = "Your username" + password = "your github token" + } + } + } +} +``` -## Inventories -It is a field where Minecraft evolved a lot, inventories are now used a lot as client<->server interface with clickable items and callback, we support these interactions natively without the need of programming your solution. +### build.gradle.kts +```kt +plugins { + id("net.onelitefeather.microtus.extension") version "0.0.1" +} -## Commands -Commands are the simplest way of communication between clients and server. Since 1.13 Minecraft has incorporated a new library denominated "Brigadier", we then integrated an API designed to use the full potential of args types. +dependencies { + extensionLibrary("com.fasterxml.jackson.module:jackson-module-kotlin:2.15.2") // Use the external dependencies function from minestom +} +extension { + authors = listOf("TheMeinerLP") + entrypoint = "net.onelitefeather.microtus.extension.ProjectEntry" + // dependencies = listOf("LuckPerms") // To generate dependencies + // version = "1.0.0" // Normally its use the project version + // name = "Example" // Normally its use the project name + // External dependencies are handled via `extensionLibrary("String")` from gradle +} +``` -# Credits -* The [contributors](https://github.com/Minestom/Minestom/graphs/contributors) of the project -* [The Minecraft Coalition](https://wiki.vg/) and [`#mcdevs`](https://github.com/mcdevs) - - protocol and file formats research. -* [The Minecraft Wiki](https://minecraft.wiki) for all their useful info -* [JProfiler](https://www.ej-technologies.com/products/jprofiler/overview.html) for their amazing Java profiler +--- -# Contributing -See [the contributing file](CONTRIBUTING.md)! -All WIP features are previewed as Draft PRs +[![YourKit-Logo](https://www.yourkit.com/images/yklogo.png)](https://www.yourkit.com/) -# License -This project is licensed under the [Apache License Version 2.0](../LICENSE). +[YourKit](https://www.yourkit.com/), makers of the outstanding java profiler, support open source projects of all kinds with their full featured [Java](https://www.yourkit.com/java/profiler) and [.NET](https://www.yourkit.com/.net/profiler) application profilers. We thank them for granting Microtus an OSS license so that we can make our software the best it can be. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000000..cb16465d000 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,53 @@ + + +## Proposed changes + +Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request. +If it fixes a bug or resolves a feature request, be sure to link to that issue. + +## Types of changes + +What types of changes does your code introduce to this project? +_Put an `x` in the boxes that apply_ + +- [ ] Bugfix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] Documentation Update (if none of the other choices apply) + +## Checklist + +_Put an `x` in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of +them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before +merging your code._ + +- [ ] I have read the CONTRIBUTING.md +- [ ] I have added tests that prove my fix is effective or that my feature works +- [ ] I have added necessary documentation (if appropriate) + +## Further comments + +If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you +did and what alternatives you considered, etc... \ No newline at end of file diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 00000000000..0d0b1c994dd --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1 @@ +_extends: .github diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 00000000000..6d4ba5a3a9a --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,49 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:base" + ], + "regexManagers": [ + { + "fileMatch": ["README.md"], + "matchStrings": ["implementation\\(\"net.onelitefeather.microtus:Minestom:(?.*?)\\\""], + "depNameTemplate": "net.onelitefeather.microtus:Minestom", + "datasourceTemplate": "maven" + }, + { + "fileMatch": ["README.md"], + "matchStrings": ["testImplementation\\(\"net.onelitefeather.microtus.testing:testing:(?.*?)\\\""], + "depNameTemplate": "net.onelitefeather.microtus:Minestom", + "datasourceTemplate": "maven" + } + ], + "packageRules": [ + { + "matchUpdateTypes": [ + "patch" + ], + "automerge": true, + "automergeType": "branch", + "groupName": "patch", + "schedule": [ + "after 10pm and before 6:00am every day" + ] + }, + { + "matchUpdateTypes": [ + "minor" + ], + "automerge": false, + "schedule": [ + "before 6:00am every friday" + ] + } + ], + "ignoreDeps": [], + "labels": ["Renovate"], + "rebaseWhen": "conflicted", + "vulnerabilityAlerts": { + "labels": ["Component::security"], + "automerge": true + } +} \ No newline at end of file diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 00000000000..547a79755d9 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,18 @@ +daysUntilStale: 30 +daysUntilClose: 7 +only: issues +exemptLabels: + - "Bug" + - "Enhancement" + - "Approved" + - "Priority" + - "Under investigation" +staleLabel: "resolution: stale" +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. If the issue is still present and can be reproduced, please let the team know. + Thank you for your contributions. +closeComment: > + This issue has been automatically closed because it has not had activity in + a long time. If the issue still applies to the most recent supported + version, please reply to this issue and the team will reopen it. \ No newline at end of file diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml new file mode 100644 index 00000000000..b73ddf5fb33 --- /dev/null +++ b/.github/workflows/build-pr.yml @@ -0,0 +1,36 @@ +name: Build PR +on: [pull_request] +jobs: + build_pr: + if: github.repository_owner == 'OneLiteFeatherNET' + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + - name: Validate Gradle Wrapper + uses: gradle/wrapper-validation-action@v3 + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 21 + - name: Cache SonarCloud packages + uses: actions/cache@v3 + with: + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + - name: Cache Gradle packages + uses: actions/cache@v3 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} + restore-keys: ${{ runner.os }}-gradle + - name: Build on ${{ matrix.os }} + run: ./gradlew test jacocoTestReport sonar --info + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000000..03bf5357e07 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,54 @@ +name: Build +on: + push: + branches: + - master +jobs: + build: + # Run on all label events (won't be duplicated) or all push events or on PR syncs not from the same repo + if: github.repository_owner == 'OneLiteFeatherNET' + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + - name: Validate Gradle Wrapper + uses: gradle/wrapper-validation-action@v3 + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: temurin + cache: gradle + java-version: 21 + - name: Cache SonarCloud packages + uses: actions/cache@v3 + with: + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + - name: Cache Gradle packages + uses: actions/cache@v3 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} + restore-keys: ${{ runner.os }}-gradle + - name: Clean Build + run: ./gradlew build sonar --info + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + - name: Publish to Central via Build + run: | + ./gradlew publishToSonatype :testing:publishToSonatype closeAndReleaseSonatypeStagingRepository -PforceSign=true + env: + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + GPG_PRIVATE_KEY: ${{ secrets.ONELITEFEATHER_GPG_KEY }} + GPG_PASSPHRASE: ${{ secrets.ONELITEFEATHER_GPG_PASSWORD }} + ORG_GRADLE_PROJECT_sonatypeUsername: "${{ secrets.SONATYPE_USERNAME }}" + ORG_GRADLE_PROJECT_sonatypePassword: "${{ secrets.SONATYPE_PASSWORD }}" + ORG_GRADLE_PROJECT_onelitefeatherSigningKey: "${{ secrets.ONELITEFEATHER_GPG_KEY }}" + ORG_GRADLE_PROJECT_onelitefeatherSigningPassword: "${{ secrets.ONELITEFEATHER_GPG_PASSWORD }}" + ORG_GRADLE_PROJECT_signingKey: "${{ secrets.ONELITEFEATHER_GPG_KEY }}" + ORG_GRADLE_PROJECT_signingPassword: "${{ secrets.ONELITEFEATHER_GPG_PASSWORD }}" + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/close_invalid_prs.yml b/.github/workflows/close_invalid_prs.yml index 44c763b6d0b..03b5e823ddb 100644 --- a/.github/workflows/close_invalid_prs.yml +++ b/.github/workflows/close_invalid_prs.yml @@ -1,4 +1,3 @@ -# Thanks paper: https://github.com/papermc/paper/blob/master/.github/workflows/close_invalid_prs.yml name: Close invalid PRs on: @@ -7,22 +6,9 @@ on: jobs: run: - if: | - github.repository != github.event.pull_request.head.repo.full_name && - ( - github.head_ref == 'master' || - github.event.pull_request.head.repo.owner.type != 'User' - ) + if: ${{ github.repository != github.event.pull_request.head.repo.full_name && github.head_ref == 'master' }} runs-on: ubuntu-latest steps: - uses: superbrothers/close-pull-request@v3 - id: "master_branch" - if: github.head_ref == 'master' with: - comment: "Please do not open pull requests from the `master` branch, create a new branch instead." - - - uses: superbrothers/close-pull-request@v3 - id: "org_account" - if: github.event.pull_request.head.repo.owner.type != 'User' && steps.master_branch.outcome == 'skipped' - with: - comment: "Please do not open pull requests from non-user accounts like organisations. Create a fork on a user account instead." + comment: "Please do not open pull requests from the `develop` branch, create a new branch instead." \ No newline at end of file diff --git a/.github/workflows/javadoc.yml b/.github/workflows/javadoc.yml index 92d41fb983a..8b632d3d179 100644 --- a/.github/workflows/javadoc.yml +++ b/.github/workflows/javadoc.yml @@ -10,15 +10,20 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Set up JDK 21 - uses: actions/setup-java@v1 + - uses: actions/checkout@v4 + - name: Set up JDK + uses: actions/setup-java@v4 with: + distribution: temurin + cache: gradle java-version: 21 - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build javadoc - run: ./gradlew javadoc + run: | + git config --global user.email "no-reply@github.com" + git config --global user.name "Github Actions" + ./gradlew javadoc - name: Deploy javadoc to its assigned branch uses: s0/git-publish-subdir-action@develop @@ -26,5 +31,4 @@ jobs: REPO: self BRANCH: javadoc FOLDER: build/docs/javadoc - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CLEAR_GLOBS_FILE: ".github/javadoc-publish-clear" \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml deleted file mode 100644 index 851212ef419..00000000000 --- a/.github/workflows/pr.yml +++ /dev/null @@ -1,59 +0,0 @@ -name: Build and test Minestom - -on: - pull_request: - branches: [ master ] - -jobs: - tests: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 21 - uses: actions/setup-java@v2 - with: - distribution: 'zulu' - java-version: 21 - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - name: Setup gradle cache - uses: burrunan/gradle-cache-action@v1 - with: - save-generated-gradle-jars: false - save-local-build-cache: false - save-gradle-dependencies-cache: true - save-maven-dependencies-cache: true - # Ignore some of the paths when caching Maven Local repository - maven-local-ignore-paths: | - net/minestom/ - - name: Build Minestom - run: ./gradlew classes testClasses - - name: Run Minestom tests - run: ./gradlew test - publish: - runs-on: ubuntu-latest - if: github.event.pull_request.head.repo.full_name == github.repository - env: - SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} - SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} - GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} - GPG_PASSPHRASE: ${{ secrets.GPG_PASSWORD }} - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 21 - uses: actions/setup-java@v2 - with: - java-version: '21' - distribution: 'temurin' - - name: Set outputs - id: vars - run: | - export ACTUAL=${{ github.event.pull_request.head.sha }} - echo "short_commit_hash=${ACTUAL::10}" >> $GITHUB_OUTPUT - - name: Publish to Sonatype - env: - MINESTOM_VERSION: ${{ github.head_ref }}-${{ steps.vars.outputs.short_commit_hash }} - MINESTOM_CHANNEL: snapshot - run: | - ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository - echo "Version: ${SHORT_COMMIT_HASH}" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml new file mode 100644 index 00000000000..9410396588b --- /dev/null +++ b/.github/workflows/release-drafter.yml @@ -0,0 +1,22 @@ +name: draft release +on: + push: + branches: + - master + pull_request: + types: [opened, reopened, synchronize] + pull_request_target: + types: [opened, reopened, synchronize] +permissions: + contents: read +jobs: + update_release_draft: + permissions: + contents: write + pull-requests: write + if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }} + runs-on: ubuntu-latest + steps: + - uses: release-drafter/release-drafter@v6 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000000..ec1ef71cc2d --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,50 @@ +name: Build +on: + push: + tags: + - '*' +jobs: + build: + # Run on all label events (won't be duplicated) or all push events or on PR syncs not from the same repo + if: github.repository_owner == 'OneLiteFeatherNET' + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + - name: Validate Gradle Wrapper + uses: gradle/wrapper-validation-action@v3 + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: temurin + cache: gradle + java-version: 21 + - uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + - name: Clean Build + run: | + git config --global user.email "no-reply@github.com" + git config --global user.name "Github Actions" + ./gradlew jar + - name: Publish to Central via Tag + run: | + ./gradlew publishToSonatype :testing:publishToSonatype closeAndReleaseSonatypeStagingRepository -PforceSign=true + env: + TAG_VERSION: ${{ github.ref_name }} + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + GPG_PRIVATE_KEY: ${{ secrets.ONELITEFEATHER_GPG_KEY }} + GPG_PASSPHRASE: ${{ secrets.ONELITEFEATHER_GPG_PASSWORD }} + ORG_GRADLE_PROJECT_sonatypeUsername: "${{ secrets.SONATYPE_USERNAME }}" + ORG_GRADLE_PROJECT_sonatypePassword: "${{ secrets.SONATYPE_PASSWORD }}" + ORG_GRADLE_PROJECT_onelitefeatherSigningKey: "${{ secrets.ONELITEFEATHER_GPG_KEY }}" + ORG_GRADLE_PROJECT_onelitefeatherSigningPassword: "${{ secrets.ONELITEFEATHER_GPG_PASSWORD }}" + ORG_GRADLE_PROJECT_signingKey: "${{ secrets.ONELITEFEATHER_GPG_KEY }}" + ORG_GRADLE_PROJECT_signingPassword: "${{ secrets.ONELITEFEATHER_GPG_PASSWORD }}" + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/snapshot-deploy.yaml b/.github/workflows/snapshot-deploy.yaml deleted file mode 100644 index cf032b8dab5..00000000000 --- a/.github/workflows/snapshot-deploy.yaml +++ /dev/null @@ -1,32 +0,0 @@ -name: Gradle Publish to Maven Central - -on: - push: - branches: [ master ] - -jobs: - build: - runs-on: ubuntu-latest - env: - SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} - SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} - GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} - GPG_PASSPHRASE: ${{ secrets.GPG_PASSWORD }} - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 21 - uses: actions/setup-java@v2 - with: - java-version: '21' - distribution: 'temurin' - - name: Set outputs - id: vars - run: | - echo "short_commit_hash=${GITHUB_SHA::10}" >> $GITHUB_OUTPUT - - name: Publish to Sonatype - env: - MINESTOM_VERSION: ${{ steps.vars.outputs.short_commit_hash }} - MINESTOM_CHANNEL: release - run: | - ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository - echo "Version: ${SHORT_COMMIT_HASH}" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/trigger-jitpack-build.yml b/.github/workflows/trigger-jitpack-build.yml deleted file mode 100644 index 8366c4f6fd6..00000000000 --- a/.github/workflows/trigger-jitpack-build.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: Trigger Jitpack Build -on: - push: - branches: [ master ] - - workflow_dispatch: -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Trigger Jitpack Build - run: curl "https://jitpack.io/com/github/Minestom/Minestom/${GITHUB_SHA:0:10}/build.log" diff --git a/.gitignore b/.gitignore index ac58d12e5d0..5a7e565c2f9 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,4 @@ gradle-app.setting # When saving the world in the demo we generate the world folder # Incase people are using IntelliJ to run the server, this will exclude the world folder. /demo/world +.bstats \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 00000000000..47835348cb4 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +microtus.onelitefeather.dev \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 261eeb9e9f8..00000000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000000..b9a592b9567 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,19 @@ +Microtus inherits its licensing from upstream projects. + +As such, Microtus is licensed under the +[Apache 2.0](licenses/apache_2_0.md); as it inherits it from Minestom. + +Any author who is _not_ listed below should be presumed to have released their work +under the original [Apache 2.0](licenses/apache_2_0.md) license. + +In the interest of promoting a better Minecraft platform for everyone, contributors +may choose to release their code under the more permissive [MIT License](licenses/MIT.md). + +The authors listed below have chosen to release their code under that more permissive +[MIT License](licenses/MIT.md). Any contributor who wants their name added below +should submit a pull request to this project to add their name. + +```text +Phillipp Glanz +Steffen Wonning +``` \ No newline at end of file diff --git a/bom/build.gradle.kts b/bom/build.gradle.kts new file mode 100644 index 00000000000..dcfc9fd2257 --- /dev/null +++ b/bom/build.gradle.kts @@ -0,0 +1,120 @@ +plugins { + `java-platform` + `maven-publish` + signing +} + +group = "net.onelitefeather.microtus" + +repositories { + maven("https://s01.oss.sonatype.org/content/repositories/snapshots") + mavenCentral() + maven(url = "https://jitpack.io") +} +dependencies { + constraints { + api(project(":testing")) + api(rootProject) + + // Logging + api(libs.bundles.logging) + // Libraries required for the terminal + api(libs.bundles.terminal) + + // Performance improving libraries + api(libs.caffeine) + api(libs.fastutil) + api(libs.bundles.flare) + + // Libraries + api(libs.gson) + api(libs.jcTools) + + // Adventure, for user-interface + api(libs.bundles.adventure) + + // Kotlin Libraries + api(libs.bundles.kotlin) + + api(libs.maven.resolver) + api(libs.maven.connector) + api(libs.maven.transport.http) + + // Minestom Data (From MinestomDataGenerator) + api(libs.minestomData) + + // BStats + api(libs.bstats.base) + } +} +javaPlatform { + allowDependencies() +} + +signing { + if (!project.hasProperty("skip.signing") && !version.toString().endsWith("-SNAPSHOT")) { + val signingKey: String? by project + val signingPassword: String? by project + useInMemoryPgpKeys(signingKey, signingPassword) + signing.isRequired + sign(publishing.publications) + } +} +publishing { + publications { + repositories { + maven { + name = "sonatype" + url = uri(if (version.toString().endsWith("SNAPSHOT")) { + "https://s01.oss.sonatype.org/content/repositories/snapshots/" + } else { + "https://s01.oss.sonatype.org/service/local/" + }) + + credentials { + username = project.findProperty("sonatypeUsername") as String? ?: "" + password = project.findProperty("sonatypePassword") as String? ?: "" + } + } + } + create("maven") { + from(components["javaPlatform"]) + pom { + name.set(project.name) + description.set("Bill of materials for Microtus projects.") + url.set("https://github.com/OneLiteFeatherNET/microtus") + + licenses { + license { + name.set("The MIT License") + url.set("https://opensource.org/licenses/MIT") + distribution.set("repo") + } + } + developers { + developer { + id.set("themeinerlp") + name.set("Phillipp Glanz") + email.set("p.glanz@madfix.me") + } + developer { + id.set("theEvilReaper") + name.set("Steffen Wonning") + email.set("steffenwx@gmail.com") + } + } + scm { + url.set("https://github.com/OneLiteFeatherNET/microtus") + connection.set("scm:git:https://github.com/OneLiteFeatherNET/microtus.git") + developerConnection.set("scm:git:git@github.com:OneLiteFeatherNET/microtus.git") + tag.set("${project.version}") + } + + issueManagement{ + system.set("GitHub") + url.set("https://github.com/OneLiteFeatherNET/microtus/issues") + } + } + } + } +} \ No newline at end of file diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts new file mode 100644 index 00000000000..78c0b62d906 --- /dev/null +++ b/build-logic/build.gradle.kts @@ -0,0 +1,18 @@ +plugins { + `kotlin-dsl` +} + +repositories { + mavenCentral() + gradlePluginPortal() +} + +dependencies { + val indraVersion = "3.1.3" + implementation("org.jetbrains.kotlin", "kotlin-gradle-plugin", "2.0.0") + implementation("net.kyori", "indra-common", indraVersion) + implementation("net.kyori", "indra-common", indraVersion) + implementation("net.kyori", "indra-publishing-sonatype", indraVersion) + implementation("org.graalvm.buildtools", "native-gradle-plugin", "0.9.28") + implementation("io.github.gradle-nexus", "publish-plugin", "2.0.0-rc-1") +} diff --git a/build-logic/src/main/kotlin/minestom.common-conventions.gradle.kts b/build-logic/src/main/kotlin/minestom.common-conventions.gradle.kts new file mode 100644 index 00000000000..6c56062ffab --- /dev/null +++ b/build-logic/src/main/kotlin/minestom.common-conventions.gradle.kts @@ -0,0 +1,28 @@ +plugins { + java +} + +// Always exclude checker-qual. This is the single most annoying thing that always reappears. +configurations.all { + // We only use Jetbrains Annotations + exclude("org.checkerframework", "checker-qual") +} + +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(21)) + } +} + +tasks { + withType { + // We are fully aware, that we should be suppressing these instead of ignoring them here, but man keep my terminal clean. + options.compilerArgs.addAll(listOf("-Xlint:none", "-Xlint:-deprecation", "-Xlint:-unchecked")) + } + withType { + useJUnitPlatform() + // Viewable packets make tracking harder. Could be re-enabled later. + jvmArgs("-Dminestom.viewable-packet=false") + jvmArgs("-Dminestom.inside-test=true") + } +} \ No newline at end of file diff --git a/build-logic/src/main/kotlin/minestom.native-conventions.gradle.kts b/build-logic/src/main/kotlin/minestom.native-conventions.gradle.kts new file mode 100644 index 00000000000..4a873e818bb --- /dev/null +++ b/build-logic/src/main/kotlin/minestom.native-conventions.gradle.kts @@ -0,0 +1,14 @@ +plugins { + id("minestom.common-conventions") + id("org.graalvm.buildtools.native") +} + +graalvmNative { + binaries { + named("main") { + buildArgs.add("--allow-incomplete-classpath") + // One day toolchains will support getting this automagically, but that day is not today. + toolchainDetection.set(false) + } + } +} \ No newline at end of file diff --git a/build-logic/src/main/kotlin/minestom.publishing-conventions.gradle.kts b/build-logic/src/main/kotlin/minestom.publishing-conventions.gradle.kts new file mode 100644 index 00000000000..305dd158be3 --- /dev/null +++ b/build-logic/src/main/kotlin/minestom.publishing-conventions.gradle.kts @@ -0,0 +1,40 @@ +plugins { + id("net.kyori.indra") + id("net.kyori.indra.publishing") + id("net.kyori.indra.publishing.sonatype") + id("io.github.gradle-nexus.publish-plugin") +} + +indra { + javaVersions { + target(21) + testWith(21) + } + + github("OneLiteFeatherNET", "Microtus") { + ci(true) + publishing(false) + } + mitLicense() + signWithKeyFromPrefixedProperties("onelitefeather") + configurePublications { + pom { + developers { + developer { + id.set("themeinerlp") + name.set("Phillipp Glanz") + email.set("p.glanz@madfix.me") + } + developer { + id.set("theEvilReaper") + name.set("Steffen Wonning") + email.set("steffenwx@gmail.com") + } + } + } + } +} + +indraSonatype { + useAlternateSonatypeOSSHost("s01") +} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index b9b55a567d6..a0e99a51bab 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,48 +1,72 @@ -import java.time.Duration +import java.util.* plugins { `java-library` + id("minestom.publishing-conventions") + id("minestom.native-conventions") alias(libs.plugins.blossom) - - `maven-publish` signing - alias(libs.plugins.nexuspublish) + jacoco + id("org.sonarqube") version "4.4.1.3373" } -// Read env vars (used for publishing generally) -version = System.getenv("MINESTOM_VERSION") ?: "dev" -val channel = System.getenv("MINESTOM_CHANNEL") ?: "local" // local, snapshot, release +group = "net.onelitefeather.microtus" -val shortDescription = "1.21 Lightweight Minecraft server" +version = System.getenv("TAG_VERSION") ?: "1.5.0-SNAPSHOT" allprojects { - apply(plugin = "java") - - group = "net.minestom" + group = "net.onelitefeather.microtus" version = rootProject.version - description = shortDescription - - repositories { - mavenCentral() - } + description = "Lightweight and multi-threaded Minecraft server implementation" +} - configurations.all { - // We only use Jetbrains Annotations - exclude("org.checkerframework", "checker-qual") +sourceSets { + main { + java { + srcDir(file("src/autogenerated/java")) + } + blossom { + javaSources { + val gitCommit = System.getenv("GIT_COMMIT") + val gitBranch = System.getenv("GIT_BRANCH") + val group = System.getenv("GROUP") + val artifact = System.getenv("ARTIFACT") + property("\"&COMMIT\"", if (gitCommit == null) "null" else "\"${gitCommit}\"") + property("\"&BRANCH\"", if (gitBranch == null) "null" else "\"${gitBranch}\"") + property("\"&GROUP\"", if (group == null) "null" else "\"${group}\"") + property("\"&ARTIFACT\"", if (artifact == null) "null" else "\"${artifact}\"") + } + } } +} - java { - withSourcesJar() - withJavadocJar() +java { + withJavadocJar() + withSourcesJar() +} - toolchain.languageVersion = JavaLanguageVersion.of(21) +tasks { + jar { + manifest { + attributes("Automatic-Module-Name" to "net.minestom.server") + } } + withType { + (options as? StandardJavadocDocletOptions)?.apply { + encoding = "UTF-8" - tasks.withType { + // Custom options + addBooleanOption("html5", true) + addStringOption("-release", "21") + // Links to external javadocs + links("https://docs.oracle.com/en/java/javase/21/docs/api/") + links("https://jd.advntr.dev/api/${libs.versions.adventure.get()}/") + } + } + withType { duplicatesStrategy = DuplicatesStrategy.EXCLUDE } - - tasks.withType { + withType { useJUnitPlatform() // Viewable packets make tracking harder. Could be re-enabled later. @@ -51,17 +75,12 @@ allprojects { minHeapSize = "512m" maxHeapSize = "1024m" } - - tasks.withType { - options.encoding = "UTF-8" + jacocoTestReport { + reports { + xml.required = true + } } -} -sourceSets { - main { - java.srcDir(file("src/main/java")) - java.srcDir(file("src/autogenerated/java")) - } } dependencies { @@ -71,128 +90,36 @@ dependencies { api(libs.bundles.adventure) implementation(libs.minestomData) - // Performance/data structures + // Logging + implementation(libs.bundles.logging) + // Libraries required for the terminal + implementation(libs.bundles.terminal) + + // Performance improving libraries implementation(libs.caffeine) api(libs.fastutil) implementation(libs.bundles.flare) + // BStats + api(libs.bstats.base) + // Maven + api(libs.maven.resolver) + api(libs.maven.connector) + api(libs.maven.transport.http) + + // Libraries api(libs.gson) implementation(libs.jcTools) // Testing testImplementation(libs.bundles.junit) testImplementation(project(":testing")) + // Only here to ensure J9 module support for extensions and our classloaders + testCompileOnly(libs.mockito.core) } - -tasks { - jar { - manifest { - attributes("Automatic-Module-Name" to "net.minestom.server") - } - } - withType { - (options as? StandardJavadocDocletOptions)?.apply { - encoding = "UTF-8" - - // Custom options - addBooleanOption("html5", true) - addStringOption("-release", "21") - // Links to external javadocs - links("https://docs.oracle.com/en/java/javase/21/docs/api/") - links("https://jd.advntr.dev/api/${libs.versions.adventure.get()}/") - } +sonar { + properties { + property("sonar.projectKey", "OneLiteFeatherNET_Microtus") + property("sonar.organization", "onelitefeathernet") + property("sonar.host.url", "https://sonarcloud.io") } - - blossom { - val gitFile = "src/main/java/net/minestom/server/Git.java" - - val gitCommit = System.getenv("GIT_COMMIT") - val gitBranch = System.getenv("GIT_BRANCH") - val group = System.getenv("GROUP") - val artifact = System.getenv("ARTIFACT") - - replaceToken("\"&COMMIT\"", if (gitCommit == null) "null" else "\"${gitCommit}\"", gitFile) - replaceToken("\"&BRANCH\"", if (gitBranch == null) "null" else "\"${gitBranch}\"", gitFile) - replaceToken("\"&GROUP\"", if (group == null) "null" else "\"${group}\"", gitFile) - replaceToken("\"&ARTIFACT\"", if (artifact == null) "null" else "\"${artifact}\"", gitFile) - } - - nexusPublishing{ - useStaging.set(true) - this.packageGroup.set("net.minestom") - - transitionCheckOptions { - maxRetries.set(360) // 1 hour - delayBetween.set(Duration.ofSeconds(10)) - } - - repositories.sonatype { - nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/")) - snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")) - - if (System.getenv("SONATYPE_USERNAME") != null) { - username.set(System.getenv("SONATYPE_USERNAME")) - password.set(System.getenv("SONATYPE_PASSWORD")) - } - } - } - - publishing.publications.create("maven") { - groupId = "net.minestom" - // todo: decide on publishing scheme - artifactId = if (channel == "snapshot") "minestom-snapshots" else "minestom-snapshots" - version = project.version.toString() - - from(project.components["java"]) - - pom { - name.set(this@create.artifactId) - description.set(shortDescription) - url.set("https://github.com/minestom/minestom") - - licenses { - license { - name.set("Apache 2.0") - url.set("https://github.com/minestom/minestom/blob/main/LICENSE") - } - } - - developers { - developer { - id.set("TheMode") - } - developer { - id.set("mworzala") - name.set("Matt Worzala") - email.set("matt@hollowcube.dev") - } - } - - issueManagement { - system.set("GitHub") - url.set("https://github.com/minestom/minestom/issues") - } - - scm { - connection.set("scm:git:git://github.com/minestom/minestom.git") - developerConnection.set("scm:git:git@github.com:minestom/minestom.git") - url.set("https://github.com/minestom/minestom") - tag.set("HEAD") - } - - ciManagement { - system.set("Github Actions") - url.set("https://github.com/minestom/minestom/actions") - } - } - } - - signing { - isRequired = System.getenv("CI") != null - - val privateKey = System.getenv("GPG_PRIVATE_KEY") - val keyPassphrase = System.getenv()["GPG_PASSPHRASE"] - useInMemoryPgpKeys(privateKey, keyPassphrase) - - sign(publishing.publications) - } -} +} \ No newline at end of file diff --git a/code-generators/build.gradle.kts b/code-generators/build.gradle.kts index 0ef2929b748..d403cfbbadb 100644 --- a/code-generators/build.gradle.kts +++ b/code-generators/build.gradle.kts @@ -2,6 +2,11 @@ plugins { application } +repositories { + mavenLocal() + mavenCentral() +} + dependencies { // Provides the input JSON to generate from implementation(libs.minestomData) diff --git a/code-generators/build/classes/java/main/net/minestom/codegen/CodeExporter.class b/code-generators/build/classes/java/main/net/minestom/codegen/CodeExporter.class new file mode 100644 index 00000000000..7aa13cdb2e4 Binary files /dev/null and b/code-generators/build/classes/java/main/net/minestom/codegen/CodeExporter.class differ diff --git a/code-generators/build/classes/java/main/net/minestom/codegen/CodeGenerator.class b/code-generators/build/classes/java/main/net/minestom/codegen/CodeGenerator.class new file mode 100644 index 00000000000..5ff50f707ab Binary files /dev/null and b/code-generators/build/classes/java/main/net/minestom/codegen/CodeGenerator.class differ diff --git a/code-generators/build/classes/java/main/net/minestom/codegen/ConstantsGenerator.class b/code-generators/build/classes/java/main/net/minestom/codegen/ConstantsGenerator.class new file mode 100644 index 00000000000..36a55d3832c Binary files /dev/null and b/code-generators/build/classes/java/main/net/minestom/codegen/ConstantsGenerator.class differ diff --git a/code-generators/build/classes/java/main/net/minestom/codegen/Generators.class b/code-generators/build/classes/java/main/net/minestom/codegen/Generators.class new file mode 100644 index 00000000000..e5879cdbbd8 Binary files /dev/null and b/code-generators/build/classes/java/main/net/minestom/codegen/Generators.class differ diff --git a/code-generators/build/classes/java/main/net/minestom/codegen/MinestomCodeGenerator.class b/code-generators/build/classes/java/main/net/minestom/codegen/MinestomCodeGenerator.class new file mode 100644 index 00000000000..9cea3a04ec9 Binary files /dev/null and b/code-generators/build/classes/java/main/net/minestom/codegen/MinestomCodeGenerator.class differ diff --git a/code-generators/build/classes/java/main/net/minestom/codegen/color/DyeColorGenerator.class b/code-generators/build/classes/java/main/net/minestom/codegen/color/DyeColorGenerator.class new file mode 100644 index 00000000000..8f94b089544 Binary files /dev/null and b/code-generators/build/classes/java/main/net/minestom/codegen/color/DyeColorGenerator.class differ diff --git a/code-generators/build/classes/java/main/net/minestom/codegen/particle/ParticleGenerator.class b/code-generators/build/classes/java/main/net/minestom/codegen/particle/ParticleGenerator.class new file mode 100644 index 00000000000..29462e30938 Binary files /dev/null and b/code-generators/build/classes/java/main/net/minestom/codegen/particle/ParticleGenerator.class differ diff --git a/code-generators/build/classes/java/main/net/minestom/codegen/recipe/RecipeTypeGenerator.class b/code-generators/build/classes/java/main/net/minestom/codegen/recipe/RecipeTypeGenerator.class new file mode 100644 index 00000000000..8c5fc57fba8 Binary files /dev/null and b/code-generators/build/classes/java/main/net/minestom/codegen/recipe/RecipeTypeGenerator.class differ diff --git a/code-generators/build/classes/java/main/net/minestom/codegen/util/GenerationHelper.class b/code-generators/build/classes/java/main/net/minestom/codegen/util/GenerationHelper.class new file mode 100644 index 00000000000..61569b078c0 Binary files /dev/null and b/code-generators/build/classes/java/main/net/minestom/codegen/util/GenerationHelper.class differ diff --git a/code-generators/build/distributions/code-generators-1.5.0-SNAPSHOT.tar b/code-generators/build/distributions/code-generators-1.5.0-SNAPSHOT.tar new file mode 100644 index 00000000000..e31e74517dd Binary files /dev/null and b/code-generators/build/distributions/code-generators-1.5.0-SNAPSHOT.tar differ diff --git a/code-generators/build/distributions/code-generators-1.5.0-SNAPSHOT.zip b/code-generators/build/distributions/code-generators-1.5.0-SNAPSHOT.zip new file mode 100644 index 00000000000..17746b595c8 Binary files /dev/null and b/code-generators/build/distributions/code-generators-1.5.0-SNAPSHOT.zip differ diff --git a/code-generators/build/libs/code-generators-1.5.0-SNAPSHOT.jar b/code-generators/build/libs/code-generators-1.5.0-SNAPSHOT.jar new file mode 100644 index 00000000000..446370d7dac Binary files /dev/null and b/code-generators/build/libs/code-generators-1.5.0-SNAPSHOT.jar differ diff --git a/code-generators/build/scripts/code-generators b/code-generators/build/scripts/code-generators new file mode 100755 index 00000000000..5b28c1d873a --- /dev/null +++ b/code-generators/build/scripts/code-generators @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# 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 +# +# https://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. +# + +############################################################################## +# +# code-generators start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh code-generators +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and CODE_GENERATORS_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}.." > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/lib/code-generators-1.5.0-SNAPSHOT.jar:$APP_HOME/lib/data-1.21-rv7.jar:$APP_HOME/lib/annotations-24.1.0.jar:$APP_HOME/lib/logback-classic-1.4.5.jar:$APP_HOME/lib/slf4j-api-2.0.7.jar:$APP_HOME/lib/gson-2.11.0.jar:$APP_HOME/lib/javapoet-1.13.0.jar:$APP_HOME/lib/logback-core-1.4.5.jar:$APP_HOME/lib/error_prone_annotations-2.27.0.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and CODE_GENERATORS_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and CODE_GENERATORS_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + -classpath "$CLASSPATH" \ + net.minestom.codegen.Generators \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $CODE_GENERATORS_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/code-generators/build/scripts/code-generators.bat b/code-generators/build/scripts/code-generators.bat new file mode 100644 index 00000000000..54ed1e7349d --- /dev/null +++ b/code-generators/build/scripts/code-generators.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem code-generators startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME%.. + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and CODE_GENERATORS_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\lib\code-generators-1.5.0-SNAPSHOT.jar;%APP_HOME%\lib\data-1.21-rv7.jar;%APP_HOME%\lib\annotations-24.1.0.jar;%APP_HOME%\lib\logback-classic-1.4.5.jar;%APP_HOME%\lib\slf4j-api-2.0.7.jar;%APP_HOME%\lib\gson-2.11.0.jar;%APP_HOME%\lib\javapoet-1.13.0.jar;%APP_HOME%\lib\logback-core-1.4.5.jar;%APP_HOME%\lib\error_prone_annotations-2.27.0.jar + + +@rem Execute code-generators +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %CODE_GENERATORS_OPTS% -classpath "%CLASSPATH%" net.minestom.codegen.Generators %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable CODE_GENERATORS_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%CODE_GENERATORS_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/code-generators/build/tmp/compileJava/compileTransaction/stash-dir/CodeGenerator.class.uniqueId2 b/code-generators/build/tmp/compileJava/compileTransaction/stash-dir/CodeGenerator.class.uniqueId2 new file mode 100644 index 00000000000..75f35e7e633 Binary files /dev/null and b/code-generators/build/tmp/compileJava/compileTransaction/stash-dir/CodeGenerator.class.uniqueId2 differ diff --git a/code-generators/build/tmp/compileJava/compileTransaction/stash-dir/Generators.class.uniqueId0 b/code-generators/build/tmp/compileJava/compileTransaction/stash-dir/Generators.class.uniqueId0 new file mode 100644 index 00000000000..4c4e72935a1 Binary files /dev/null and b/code-generators/build/tmp/compileJava/compileTransaction/stash-dir/Generators.class.uniqueId0 differ diff --git a/code-generators/build/tmp/compileJava/compileTransaction/stash-dir/RecipeTypeGenerator.class.uniqueId1 b/code-generators/build/tmp/compileJava/compileTransaction/stash-dir/RecipeTypeGenerator.class.uniqueId1 new file mode 100644 index 00000000000..d8c359edd83 Binary files /dev/null and b/code-generators/build/tmp/compileJava/compileTransaction/stash-dir/RecipeTypeGenerator.class.uniqueId1 differ diff --git a/code-generators/build/tmp/compileJava/previous-compilation-data.bin b/code-generators/build/tmp/compileJava/previous-compilation-data.bin new file mode 100644 index 00000000000..447b89b46fd Binary files /dev/null and b/code-generators/build/tmp/compileJava/previous-compilation-data.bin differ diff --git a/code-generators/build/tmp/jar/MANIFEST.MF b/code-generators/build/tmp/jar/MANIFEST.MF new file mode 100644 index 00000000000..59499bce4a2 --- /dev/null +++ b/code-generators/build/tmp/jar/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 + diff --git a/code-generators/src/main/java/net/minestom/codegen/CodeExporter.java b/code-generators/src/main/java/net/minestom/codegen/CodeExporter.java new file mode 100644 index 00000000000..8fe779599d5 --- /dev/null +++ b/code-generators/src/main/java/net/minestom/codegen/CodeExporter.java @@ -0,0 +1,46 @@ +package net.minestom.codegen; + +import com.squareup.javapoet.JavaFile; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +/** + * The class contains method which allows to write {@link JavaFile} to a given folder which is given as {@link java.nio.file.Path} reference. + * This class exists to reduce the amount of code duplication in the code generators. + * @version 1.0.0 + * @since 1.1.4 + */ +public interface CodeExporter { + + Logger LOGGER = LoggerFactory.getLogger(CodeExporter.class); + + /** + * Write a list of {@link JavaFile} objects to a given folder. + * @param fileList the list of files to write + * @param outputFolder the folder to write to + */ + default void writeFiles(@NotNull List fileList, File outputFolder) { + if (fileList.isEmpty()) return; + for (JavaFile javaFile : fileList) { + writeFile(javaFile, outputFolder); + } + } + + /** + * Write a single {@link JavaFile} to a given folder. + * @param javaFile the file to write + * @param outputFolder the folder to write to + */ + default void writeFile(@NotNull JavaFile javaFile, @NotNull File outputFolder) { + try { + javaFile.writeTo(outputFolder); + } catch (IOException e) { + LOGGER.error("An error occurred while writing source code to the file system.", e); + } + } +} diff --git a/code-generators/src/main/java/net/minestom/codegen/CodeGenerator.java b/code-generators/src/main/java/net/minestom/codegen/CodeGenerator.java index 8aa876ec201..72da0b8e567 100644 --- a/code-generators/src/main/java/net/minestom/codegen/CodeGenerator.java +++ b/code-generators/src/main/java/net/minestom/codegen/CodeGenerator.java @@ -4,20 +4,18 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import com.squareup.javapoet.*; -import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.lang.model.SourceVersion; import javax.lang.model.element.Modifier; import java.io.File; -import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.List; import java.util.Locale; -public class CodeGenerator { +public class CodeGenerator implements CodeExporter { protected static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(); private static final Logger LOGGER = LoggerFactory.getLogger(CodeGenerator.class); @@ -29,7 +27,7 @@ public CodeGenerator(File outputFolder) { public void generate(InputStream resourceFile, String packageName, String typeName, String loaderName, String generatedName) { if (resourceFile == null) { - LOGGER.error("Failed to find resource file for " + typeName); + LOGGER.error("Failed to find resource file for {}", typeName); return; } ClassName typeClass = ClassName.get(packageName, typeName); @@ -72,7 +70,7 @@ public void generate(InputStream resourceFile, String packageName, String typeNa public void generateKeys(InputStream resourceFile, String packageName, String typeName, String generatedName) { if (resourceFile == null) { - LOGGER.error("Failed to find resource file for " + typeName); + LOGGER.error("Failed to find resource file for {}", typeName); return; } @@ -117,14 +115,4 @@ public void generateKeys(InputStream resourceFile, String packageName, String ty .build()), outputFolder); } - - private void writeFiles(@NotNull List fileList, File outputFolder) { - for (JavaFile javaFile : fileList) { - try { - javaFile.writeTo(outputFolder); - } catch (IOException e) { - LOGGER.error("An error occured while writing source code to the file system.", e); - } - } - } } diff --git a/code-generators/src/main/java/net/minestom/codegen/ConstantsGenerator.java b/code-generators/src/main/java/net/minestom/codegen/ConstantsGenerator.java index 0ce81d41a30..1189cd9bc9e 100644 --- a/code-generators/src/main/java/net/minestom/codegen/ConstantsGenerator.java +++ b/code-generators/src/main/java/net/minestom/codegen/ConstantsGenerator.java @@ -71,7 +71,7 @@ public void generate() { writeFiles( List.of( JavaFile.builder("net.minestom.server", constantsInterface.build()) - .indent(" ") + .indent(DEFAULT_INDENT) .skipJavaLangImports(true) .build() ), diff --git a/code-generators/src/main/java/net/minestom/codegen/Generators.java b/code-generators/src/main/java/net/minestom/codegen/Generators.java index deddd0e9094..93bb0553fb8 100644 --- a/code-generators/src/main/java/net/minestom/codegen/Generators.java +++ b/code-generators/src/main/java/net/minestom/codegen/Generators.java @@ -1,7 +1,6 @@ package net.minestom.codegen; import net.minestom.codegen.color.DyeColorGenerator; -import net.minestom.codegen.fluid.FluidGenerator; import net.minestom.codegen.particle.ParticleGenerator; import net.minestom.codegen.recipe.RecipeTypeGenerator; import org.slf4j.Logger; @@ -31,6 +30,7 @@ public static void main(String[] args) { // Static registries generator.generate(resource("blocks.json"), "net.minestom.server.instance.block", "Block", "BlockImpl", "Blocks"); generator.generate(resource("items.json"), "net.minestom.server.item", "Material", "MaterialImpl", "Materials"); + generator.generate(resource("game_events.json"), "net.minestom.server.game", "GameEvent", "GameEventImpl", "GameEvents"); generator.generate(resource("entities.json"), "net.minestom.server.entity", "EntityType", "EntityTypeImpl", "EntityTypes"); generator.generate(resource("potion_effects.json"), "net.minestom.server.potion", "PotionEffect", "PotionEffectImpl", "PotionEffects"); generator.generate(resource("potions.json"), "net.minestom.server.potion", "PotionType", "PotionTypeImpl", "PotionTypes"); @@ -38,6 +38,9 @@ public static void main(String[] args) { generator.generate(resource("custom_statistics.json"), "net.minestom.server.statistic", "StatisticType", "StatisticTypeImpl", "StatisticTypes"); generator.generate(resource("attributes.json"), "net.minestom.server.entity.attribute", "Attribute", "AttributeImpl", "Attributes"); generator.generate(resource("feature_flags.json"), "net.minestom.server", "FeatureFlag", "FeatureFlagImpl", "FeatureFlags"); + generator.generate(resource("villager_professions.json"), "net.minestom.server.entity.villager", "VillagerProfession", "VillagerProfessionImpl", "VillagerProfessions"); + generator.generate(resource("villager_types.json"), "net.minestom.server.entity.villager", "VillagerType", "VillagerTypeImpl", "VillagerTypes"); + generator.generate(resource("fluids.json"), "net.minestom.server.fluid", "Fluid", "FluidImpl", "Fluids"); // Dynamic registries generator.generateKeys(resource("chat_types.json"), "net.minestom.server.message", "ChatType", "ChatTypes"); @@ -52,19 +55,6 @@ public static void main(String[] args) { generator.generateKeys(resource("painting_variants.json"), "net.minestom.server.entity.metadata.other", "PaintingMeta.Variant", "PaintingVariants"); generator.generateKeys(resource("jukebox_songs.json"), "net.minestom.server.instance.block.jukebox", "JukeboxSong", "JukeboxSongs"); - // Generate fluids - new FluidGenerator(resource("fluids.json"), outputFolder).generate(); - - // TODO: Generate villager professions -// new VillagerProfessionGenerator( -// new File(inputFolder, targetVersion + "_villager_professions.json"), -// outputFolder -// ).generate(); - // TODO: Generate villager types -// new VillagerTypeGenerator( -// new File(inputFolder, targetVersion + "_villager_types.json"), -// outputFolder -// ).generate(); LOGGER.info("Finished generating code"); } diff --git a/code-generators/src/main/java/net/minestom/codegen/MinestomCodeGenerator.java b/code-generators/src/main/java/net/minestom/codegen/MinestomCodeGenerator.java index a56248de382..e9429b548b6 100644 --- a/code-generators/src/main/java/net/minestom/codegen/MinestomCodeGenerator.java +++ b/code-generators/src/main/java/net/minestom/codegen/MinestomCodeGenerator.java @@ -2,32 +2,40 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.ClassName; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.io.File; -import java.io.IOException; -import java.util.List; +import javax.lang.model.element.Modifier; import java.util.Locale; +import java.util.Map; -public abstract class MinestomCodeGenerator { - private static final Logger LOGGER = LoggerFactory.getLogger(MinestomCodeGenerator.class); +@ApiStatus.Internal +public abstract class MinestomCodeGenerator implements CodeExporter { + public static final ClassName NAMESPACE_ID_CLASS = + ClassName.get("net.minestom.server.utils", "NamespaceID"); protected static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(); + protected static final ClassName REGISTRY_CLASS = + ClassName.get("net.minestom.server.registry", "Registries"); + protected static final ClassName KEYORI_ADVENTURE_KEY = + ClassName.get("net.kyori.adventure.key", "Keyed"); + protected static final Modifier[] CONSTANT_MODIFIERS = {Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL}; + protected static final Modifier[] PRIVATE_FINAL_MODIFIERS = {Modifier.PRIVATE, Modifier.FINAL}; + protected static final String DEFAULT_INDENT = " "; + + /** + * Creates a new code generator. + */ + protected MinestomCodeGenerator() { + } public abstract void generate(); - protected void writeFiles(@NotNull List fileList, File outputFolder) { - for (JavaFile javaFile : fileList) { - try { - javaFile.writeTo(outputFolder); - } catch (IOException e) { - LOGGER.error("An error occured while writing source code to the file system.", e); - } - } + protected static @NotNull String extractNamespace(@NotNull String namespace) { + return namespace.replace("minecraft:", "").toUpperCase(Locale.ROOT); } + protected static String toConstant(String namespace) { return namespace.replace("minecraft:", "").toUpperCase(Locale.ROOT); } diff --git a/code-generators/src/main/java/net/minestom/codegen/color/DyeColorGenerator.java b/code-generators/src/main/java/net/minestom/codegen/color/DyeColorGenerator.java index da85a1d66e5..ce556888e71 100644 --- a/code-generators/src/main/java/net/minestom/codegen/color/DyeColorGenerator.java +++ b/code-generators/src/main/java/net/minestom/codegen/color/DyeColorGenerator.java @@ -3,7 +3,16 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.squareup.javapoet.*; +import com.squareup.javapoet.AnnotationSpec; +import com.squareup.javapoet.ArrayTypeName; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.FieldSpec; +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterSpec; +import com.squareup.javapoet.ParameterizedTypeName; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; import net.minestom.codegen.MinestomCodeGenerator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -18,8 +27,16 @@ import java.util.List; import java.util.stream.StreamSupport; +import static net.minestom.codegen.util.GenerationHelper.VARIABLE_GETTER; +import static net.minestom.codegen.util.GenerationHelper.VARIABLE_SETTER; + public class DyeColorGenerator extends MinestomCodeGenerator { private static final Logger LOGGER = LoggerFactory.getLogger(DyeColorGenerator.class); + private static final String COLOR_PACKAGE = "net.minestom.server.color"; + private static final String TEXTURE_DIFFUSE_COLOR = "textureDiffuseColor"; + private static final String TEXT_COLOR = "textColor"; + private static final String FIREWORK_COLOR = "fireworkColor"; + private static final String MAP_COLOR_ID = "mapColorId"; private final InputStream dyeColorsFile; private final File outputFolder; @@ -40,10 +57,10 @@ public void generate() { return; } // Important classes we use alot - ClassName colorCN = ClassName.get("net.minestom.server.color", "Color"); + ClassName colorCN = ClassName.get(COLOR_PACKAGE, "Color"); JsonArray dyeColors = GSON.fromJson(new InputStreamReader(dyeColorsFile), JsonArray.class); - ClassName dyeColorCN = ClassName.get("net.minestom.server.color", "DyeColor"); + ClassName dyeColorCN = ClassName.get(COLOR_PACKAGE, "DyeColor"); // Dye Color Enum TypeSpec.Builder dyeColorEnum = TypeSpec.enumBuilder(dyeColorCN) .addSuperinterface(ClassName.get("net.kyori.adventure.util", "RGBLike")) @@ -57,19 +74,26 @@ public void generate() { // Fields dyeColorEnum.addFields( List.of( - FieldSpec.builder(networkBufferTypeCN, "NETWORK_TYPE", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) + FieldSpec.builder(networkBufferTypeCN, "NETWORK_TYPE", CONSTANT_MODIFIERS) .initializer("$T.Enum($T.class)", networkBufferCN, dyeColorCN) .build(), - FieldSpec.builder(binaryTagSerializerTypeCN, "NBT_TYPE", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) + FieldSpec.builder(binaryTagSerializerTypeCN, "NBT_TYPE", CONSTANT_MODIFIERS) .initializer("$T.fromEnumStringable($T.class)", binaryTagSerializerCN, dyeColorCN) .build(), - FieldSpec.builder(colorCN, "textureDiffuseColor", Modifier.PRIVATE, Modifier.FINAL).build(), - FieldSpec.builder(colorCN, "textColor", Modifier.PRIVATE, Modifier.FINAL).build(), - FieldSpec.builder(colorCN, "fireworkColor", Modifier.PRIVATE, Modifier.FINAL).build(), - FieldSpec.builder(TypeName.INT, "mapColorId", Modifier.PRIVATE, Modifier.FINAL).build() + FieldSpec.builder(colorCN, TEXTURE_DIFFUSE_COLOR, PRIVATE_FINAL_MODIFIERS).build(), + FieldSpec.builder(colorCN, TEXT_COLOR, PRIVATE_FINAL_MODIFIERS).build(), + FieldSpec.builder(colorCN, FIREWORK_COLOR, PRIVATE_FINAL_MODIFIERS).build(), + FieldSpec.builder(TypeName.INT, MAP_COLOR_ID, PRIVATE_FINAL_MODIFIERS).build() ) ); + dyeColorEnum.addField( + FieldSpec.builder(ArrayTypeName.of(dyeColorCN), "VALUES") + .addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL) + .initializer("values()") + .build() + ); + // Methods dyeColorEnum.addMethods( List.of( @@ -77,80 +101,85 @@ public void generate() { MethodSpec.constructorBuilder() .addParameters( List.of( - ParameterSpec.builder(colorCN, "textureDiffuseColor").addAnnotation(NotNull.class).build(), - ParameterSpec.builder(colorCN, "textColor").addAnnotation(NotNull.class).build(), - ParameterSpec.builder(colorCN, "fireworkColor").addAnnotation(NotNull.class).build(), - ParameterSpec.builder(TypeName.INT, "mapColorId").build() + ParameterSpec.builder(colorCN, TEXTURE_DIFFUSE_COLOR).addAnnotation(NotNull.class).build(), + ParameterSpec.builder(colorCN, TEXT_COLOR).addAnnotation(NotNull.class).build(), + ParameterSpec.builder(colorCN, FIREWORK_COLOR).addAnnotation(NotNull.class).build(), + ParameterSpec.builder(TypeName.INT, MAP_COLOR_ID).build() ) ) - .addStatement("this.textureDiffuseColor = textureDiffuseColor") - .addStatement("this.textColor = textColor") - .addStatement("this.fireworkColor = fireworkColor") - .addStatement("this.mapColorId = mapColorId") + .addStatement(VARIABLE_SETTER, TEXTURE_DIFFUSE_COLOR) + .addStatement(VARIABLE_SETTER, TEXT_COLOR) + .addStatement(VARIABLE_SETTER, FIREWORK_COLOR) + .addStatement(VARIABLE_SETTER, MAP_COLOR_ID) .build(), MethodSpec.methodBuilder("color") .addModifiers(Modifier.PUBLIC) .returns(colorCN.annotated(AnnotationSpec.builder(NotNull.class).build())) - .addStatement("return this.textureDiffuseColor") + .addStatement(VARIABLE_GETTER, TEXTURE_DIFFUSE_COLOR) .build(), - MethodSpec.methodBuilder("textColor") + MethodSpec.methodBuilder(TEXT_COLOR) .addModifiers(Modifier.PUBLIC) .returns(colorCN.annotated(AnnotationSpec.builder(NotNull.class).build())) - .addStatement("return this.textColor") + .addStatement(VARIABLE_GETTER, TEXT_COLOR) .build(), - MethodSpec.methodBuilder("fireworkColor") + MethodSpec.methodBuilder(FIREWORK_COLOR) .addModifiers(Modifier.PUBLIC) .returns(colorCN.annotated(AnnotationSpec.builder(NotNull.class).build())) - .addStatement("return this.fireworkColor") + .addStatement(VARIABLE_GETTER, FIREWORK_COLOR) .build(), MethodSpec.methodBuilder("red") .addModifiers(Modifier.PUBLIC) .returns(TypeName.INT) .addAnnotation(Override.class) - .addStatement("return this.textureDiffuseColor.red()") + .addStatement("return this.$L.red()", TEXTURE_DIFFUSE_COLOR) .build(), MethodSpec.methodBuilder("green") .returns(TypeName.INT) .addModifiers(Modifier.PUBLIC) .addAnnotation(Override.class) - .addStatement("return this.textureDiffuseColor.green()") + .addStatement("return this.$L.green()", TEXTURE_DIFFUSE_COLOR) .build(), MethodSpec.methodBuilder("blue") .returns(TypeName.INT) .addModifiers(Modifier.PUBLIC) .addAnnotation(Override.class) - .addStatement("return this.textureDiffuseColor.blue()") + .addStatement("return this.$L.blue()", TEXTURE_DIFFUSE_COLOR) .build(), - MethodSpec.methodBuilder("mapColorId") + MethodSpec.methodBuilder(MAP_COLOR_ID) .addModifiers(Modifier.PUBLIC) .returns(TypeName.INT) - .addStatement("return this.mapColorId") + .addStatement(VARIABLE_GETTER, MAP_COLOR_ID) .build() ) ); + dyeColorEnum.addMethod( + MethodSpec.methodBuilder("getValue") + .addParameter(ParameterSpec.builder(TypeName.INT, "id").build()) + .returns(dyeColorCN.annotated(AnnotationSpec.builder(Nullable.class).build())) + .addModifiers(Modifier.PUBLIC, Modifier.STATIC) + .addStatement("return $L", "VALUES[id]") + .build() + ); + // Use data for (JsonObject dyeColorObject : StreamSupport.stream(dyeColors.spliterator(), true).map(JsonElement::getAsJsonObject).sorted(Comparator.comparingInt(o -> o.get("id").getAsInt())).toList()) { String dyeColorName = dyeColorObject.get("name").getAsString(); dyeColorEnum.addEnumConstant(toConstant(dyeColorName), TypeSpec.anonymousClassBuilder( "new $T(0x$L), new $T(0x$L), new $T(0x$L), $L", - colorCN, Integer.toString(dyeColorObject.get("textureDiffuseColor").getAsInt(), 16), - colorCN, Integer.toString(dyeColorObject.get("textColor").getAsInt(), 16), - colorCN, Integer.toString(dyeColorObject.get("fireworkColor").getAsInt(), 16), - dyeColorObject.get("mapColorId").getAsInt() + colorCN, Integer.toString(dyeColorObject.get(TEXTURE_DIFFUSE_COLOR).getAsInt(), 16), + colorCN, Integer.toString(dyeColorObject.get(TEXT_COLOR).getAsInt(), 16), + colorCN, Integer.toString(dyeColorObject.get(FIREWORK_COLOR).getAsInt(), 16), + dyeColorObject.get(MAP_COLOR_ID).getAsInt() ).build() ); } // Write files to outputFolder - writeFiles( - List.of( - JavaFile.builder("net.minestom.server.color", dyeColorEnum.build()) - .indent(" ") - .skipJavaLangImports(true) - .build() - ), - outputFolder - ); + final JavaFile javaFile = JavaFile.builder(COLOR_PACKAGE, dyeColorEnum.build()) + .indent(DEFAULT_INDENT) + .skipJavaLangImports(true) + .build(); + writeFile(javaFile, outputFolder); } } diff --git a/code-generators/src/main/java/net/minestom/codegen/entity/VillagerProfessionGenerator.java b/code-generators/src/main/java/net/minestom/codegen/entity/VillagerProfessionGenerator.java deleted file mode 100644 index 54eaae59378..00000000000 --- a/code-generators/src/main/java/net/minestom/codegen/entity/VillagerProfessionGenerator.java +++ /dev/null @@ -1,212 +0,0 @@ -package net.minestom.codegen.entity; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.squareup.javapoet.*; -import net.minestom.codegen.MinestomCodeGenerator; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.lang.model.element.Modifier; -import java.io.File; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.List; - -public final class VillagerProfessionGenerator extends MinestomCodeGenerator { - private static final Logger LOGGER = LoggerFactory.getLogger(VillagerProfessionGenerator.class); - private final InputStream villagerProfessionsFile; - private final File outputFolder; - - - public VillagerProfessionGenerator(@Nullable InputStream villagerProfessionsFile, @NotNull File outputFolder) { - this.villagerProfessionsFile = villagerProfessionsFile; - this.outputFolder = outputFolder; - } - - @Override - public void generate() { - if (villagerProfessionsFile == null) { - LOGGER.error("Failed to find villager_professions.json."); - LOGGER.error("Stopped code generation for villager professions."); - return; - } - if (!outputFolder.exists() && !outputFolder.mkdirs()) { - LOGGER.error("Output folder for code generation does not exist and could not be created."); - return; - } - // Important classes we use alot - ClassName namespaceIDClassName = ClassName.get("net.minestom.server.utils", "NamespaceID"); - ClassName rawVillagerProfessionDataClassName = ClassName.get("net.minestom.server.raw_data", "RawVillagerProfessionData"); - ClassName registryClassName = ClassName.get("net.minestom.server.registry", "Registry"); - - JsonArray villagerProfessions = GSON.fromJson(new InputStreamReader(villagerProfessionsFile), JsonArray.class); - ClassName villagerProfessionClassName = ClassName.get("net.minestom.server.entity.metadata.villager", "VillagerProfession"); - - // Particle - TypeSpec.Builder villagerProfessionClass = TypeSpec.classBuilder(villagerProfessionClassName) - .addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed")) - .addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName()); - villagerProfessionClass.addField( - FieldSpec.builder(namespaceIDClassName, "id") - .addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build() - ); - villagerProfessionClass.addField( - FieldSpec.builder(rawVillagerProfessionDataClassName, "villagerProfessionData") - .addModifiers(Modifier.PRIVATE, Modifier.VOLATILE) - .addAnnotation(NotNull.class) - .build() - ); - villagerProfessionClass.addMethod( - MethodSpec.constructorBuilder() - .addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build()) - .addParameter(ParameterSpec.builder(rawVillagerProfessionDataClassName, "villagerProfessionData").addAnnotation(NotNull.class).build()) - .addStatement("this.id = id") - .addStatement("this.villagerProfessionData = villagerProfessionData") - .addModifiers(Modifier.PROTECTED) - .build() - ); - // Override key method (adventure) - villagerProfessionClass.addMethod( - MethodSpec.methodBuilder("key") - .returns(ClassName.get("net.kyori.adventure.key", "Key")) - .addAnnotation(Override.class) - .addAnnotation(NotNull.class) - .addStatement("return this.id") - .addModifiers(Modifier.PUBLIC) - .build() - ); - // getId method - villagerProfessionClass.addMethod( - MethodSpec.methodBuilder("getId") - .returns(namespaceIDClassName) - .addAnnotation(NotNull.class) - .addStatement("return this.id") - .addModifiers(Modifier.PUBLIC) - .build() - ); - // getVillagerProfessionData method - villagerProfessionClass.addMethod( - MethodSpec.methodBuilder("getVillagerProfessionData") - .returns(rawVillagerProfessionDataClassName) - .addAnnotation(NotNull.class) - .addStatement("return this.villagerProfessionData") - .addModifiers(Modifier.PUBLIC, Modifier.FINAL) - .build() - ); - // setVillagerProfessionData method - villagerProfessionClass.addMethod( - MethodSpec.methodBuilder("setVillagerProfessionData") - .addParameter(ParameterSpec.builder(rawVillagerProfessionDataClassName, "villagerProfessionData").addAnnotation(NotNull.class).build()) - .addStatement("this.villagerProfessionData = villagerProfessionData") - .addModifiers(Modifier.PUBLIC, Modifier.FINAL) - .build() - ); - // getNumericalId - villagerProfessionClass.addMethod( - MethodSpec.methodBuilder("getNumericalId") - .returns(TypeName.INT) - .addStatement("return $T.VILLAGER_PROFESSION_REGISTRY.getId(this)", registryClassName) - .addModifiers(Modifier.PUBLIC) - .build() - ); - // fromId Method - villagerProfessionClass.addMethod( - MethodSpec.methodBuilder("fromId") - .returns(villagerProfessionClassName) - .addAnnotation(Nullable.class) - .addParameter(TypeName.INT, "id") - .addStatement("return $T.VILLAGER_PROFESSION_REGISTRY.get((short) id)", registryClassName) - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .build() - ); - // fromId Method - villagerProfessionClass.addMethod( - MethodSpec.methodBuilder("fromId") - .returns(villagerProfessionClassName) - .addAnnotation(NotNull.class) - .addParameter(ClassName.get("net.kyori.adventure.key", "Key"), "id") - .addStatement("return $T.VILLAGER_PROFESSION_REGISTRY.get(id)", registryClassName) - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .build() - ); - // toString method - villagerProfessionClass.addMethod( - MethodSpec.methodBuilder("toString") - .addAnnotation(NotNull.class) - .addAnnotation(Override.class) - .returns(String.class) - // this resolves to [Namespace] - .addStatement("return \"[\" + this.id + \"]\"") - .addModifiers(Modifier.PUBLIC) - .build() - ); - // values method - villagerProfessionClass.addMethod( - MethodSpec.methodBuilder("values") - .addAnnotation(NotNull.class) - .returns(ParameterizedTypeName.get(ClassName.get(List.class), villagerProfessionClassName)) - .addStatement("return $T.VILLAGER_PROFESSION_REGISTRY.values()", registryClassName) - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .build() - ); - CodeBlock.Builder staticBlock = CodeBlock.builder(); - // Use data - for (JsonElement vp : villagerProfessions) { - JsonObject villagerProfession = vp.getAsJsonObject(); - - String villagerProfessionName = villagerProfession.get("name").getAsString(); - JsonElement workSound = villagerProfession.get("workSound"); - if (workSound == null) { - villagerProfessionClass.addField( - FieldSpec.builder( - villagerProfessionClassName, - villagerProfessionName - ).initializer( - "new $T($T.from($S), new $T(() -> null))", - villagerProfessionClassName, - namespaceIDClassName, - villagerProfession.get("id").getAsString(), - - rawVillagerProfessionDataClassName - ).addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).build() - ); - } else { - villagerProfessionClass.addField( - FieldSpec.builder( - villagerProfessionClassName, - villagerProfessionName - ).initializer( - "new $T($T.from($S), new $T(() -> $T.SOUND_EVENT_REGISTRY.get($S)))", - villagerProfessionClassName, - namespaceIDClassName, - villagerProfession.get("id").getAsString(), - - rawVillagerProfessionDataClassName, - registryClassName, - workSound.getAsString() - ).addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).build() - ); - } - - // Add to static init. - staticBlock.addStatement("$T.VILLAGER_PROFESSION_REGISTRY.register($N)", registryClassName, villagerProfessionName); - } - - villagerProfessionClass.addStaticBlock(staticBlock.build()); - - // Write files to outputFolder - writeFiles( - List.of( - JavaFile.builder("net.minestom.server.entity.metadata.villager", villagerProfessionClass.build()) - .indent(" ") - .skipJavaLangImports(true) - .build() - ), - outputFolder - ); - } -} diff --git a/code-generators/src/main/java/net/minestom/codegen/entity/VillagerTypeGenerator.java b/code-generators/src/main/java/net/minestom/codegen/entity/VillagerTypeGenerator.java deleted file mode 100644 index 8defb024319..00000000000 --- a/code-generators/src/main/java/net/minestom/codegen/entity/VillagerTypeGenerator.java +++ /dev/null @@ -1,164 +0,0 @@ -package net.minestom.codegen.entity; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.squareup.javapoet.*; -import net.minestom.codegen.MinestomCodeGenerator; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.lang.model.element.Modifier; -import java.io.File; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.List; - -public final class VillagerTypeGenerator extends MinestomCodeGenerator { - private static final Logger LOGGER = LoggerFactory.getLogger(VillagerTypeGenerator.class); - private final InputStream villagerTypesFile; - private final File outputFolder; - - public VillagerTypeGenerator(@Nullable InputStream villagerTypesFile, @NotNull File outputFolder) { - this.villagerTypesFile = villagerTypesFile; - this.outputFolder = outputFolder; - } - - @Override - public void generate() { - if (villagerTypesFile == null) { - LOGGER.error("Failed to find villager_types.json."); - LOGGER.error("Stopped code generation for villager types."); - return; - } - if (!outputFolder.exists() && !outputFolder.mkdirs()) { - LOGGER.error("Output folder for code generation does not exist and could not be created."); - return; - } - // Important classes we use alot - ClassName namespaceIDClassName = ClassName.get("net.minestom.server.utils", "NamespaceID"); - ClassName registryClassName = ClassName.get("net.minestom.server.registry", "Registry"); - - JsonArray villagerTypes = GSON.fromJson(new InputStreamReader(villagerTypesFile), JsonArray.class); - ClassName villagerTypeClassName = ClassName.get("net.minestom.server.entity.metadata.villager", "VillagerType"); - - // Particle - TypeSpec.Builder villagerTypeClass = TypeSpec.classBuilder(villagerTypeClassName) - .addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed")) - .addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName()); - villagerTypeClass.addField( - FieldSpec.builder(namespaceIDClassName, "id") - .addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build() - ); - villagerTypeClass.addMethod( - MethodSpec.constructorBuilder() - .addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build()) - .addStatement("this.id = id") - .addModifiers(Modifier.PROTECTED) - .build() - ); - // Override key method (adventure) - villagerTypeClass.addMethod( - MethodSpec.methodBuilder("key") - .returns(ClassName.get("net.kyori.adventure.key", "Key")) - .addAnnotation(Override.class) - .addAnnotation(NotNull.class) - .addStatement("return this.id") - .addModifiers(Modifier.PUBLIC) - .build() - ); - // getId method - villagerTypeClass.addMethod( - MethodSpec.methodBuilder("getId") - .returns(namespaceIDClassName) - .addAnnotation(NotNull.class) - .addStatement("return this.id") - .addModifiers(Modifier.PUBLIC) - .build() - ); - // getNumericalId - villagerTypeClass.addMethod( - MethodSpec.methodBuilder("getNumericalId") - .returns(TypeName.INT) - .addStatement("return $T.VILLAGER_TYPE_REGISTRY.getId(this)", registryClassName) - .addModifiers(Modifier.PUBLIC) - .build() - ); - // fromId Method - villagerTypeClass.addMethod( - MethodSpec.methodBuilder("fromId") - .returns(villagerTypeClassName) - .addAnnotation(Nullable.class) - .addParameter(TypeName.INT, "id") - .addStatement("return $T.VILLAGER_TYPE_REGISTRY.get((short) id)", registryClassName) - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .build() - ); - // fromId Method - villagerTypeClass.addMethod( - MethodSpec.methodBuilder("fromId") - .returns(villagerTypeClassName) - .addAnnotation(NotNull.class) - .addParameter(ClassName.get("net.kyori.adventure.key", "Key"), "id") - .addStatement("return $T.VILLAGER_TYPE_REGISTRY.get(id)", registryClassName) - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .build() - ); - // toString method - villagerTypeClass.addMethod( - MethodSpec.methodBuilder("toString") - .addAnnotation(NotNull.class) - .addAnnotation(Override.class) - .returns(String.class) - // this resolves to [Namespace] - .addStatement("return \"[\" + this.id + \"]\"") - .addModifiers(Modifier.PUBLIC) - .build() - ); - // values method - villagerTypeClass.addMethod( - MethodSpec.methodBuilder("values") - .addAnnotation(NotNull.class) - .returns(ParameterizedTypeName.get(ClassName.get(List.class), villagerTypeClassName)) - .addStatement("return $T.VILLAGER_TYPE_REGISTRY.values()", registryClassName) - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .build() - ); - CodeBlock.Builder staticBlock = CodeBlock.builder(); - // Use data - for (JsonElement vp : villagerTypes) { - JsonObject villagerProfession = vp.getAsJsonObject(); - - String villagerProfessionName = villagerProfession.get("name").getAsString(); - - villagerTypeClass.addField( - FieldSpec.builder( - villagerTypeClassName, - villagerProfessionName - ).initializer( - "new $T($T.from($S))", - villagerTypeClassName, - namespaceIDClassName, - villagerProfession.get("id").getAsString() - ).addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).build() - ); - // Add to static init. - staticBlock.addStatement("$T.VILLAGER_TYPE_REGISTRY.register($N)", registryClassName, villagerProfessionName); - } - - villagerTypeClass.addStaticBlock(staticBlock.build()); - - // Write files to outputFolder - writeFiles( - List.of( - JavaFile.builder("net.minestom.server.entity.metadata.villager", villagerTypeClass.build()) - .indent(" ") - .skipJavaLangImports(true) - .build() - ), - outputFolder - ); - } -} diff --git a/code-generators/src/main/java/net/minestom/codegen/fluid/FluidGenerator.java b/code-generators/src/main/java/net/minestom/codegen/fluid/FluidGenerator.java deleted file mode 100644 index 642489970cf..00000000000 --- a/code-generators/src/main/java/net/minestom/codegen/fluid/FluidGenerator.java +++ /dev/null @@ -1,144 +0,0 @@ -package net.minestom.codegen.fluid; - -import com.google.gson.JsonObject; -import com.squareup.javapoet.*; -import net.minestom.codegen.MinestomCodeGenerator; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.lang.model.element.Modifier; -import java.io.File; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.List; - -public final class FluidGenerator extends MinestomCodeGenerator { - private static final Logger LOGGER = LoggerFactory.getLogger(FluidGenerator.class); - private final InputStream fluidsFile; - private final File outputFolder; - - public FluidGenerator(@Nullable InputStream fluidsFile, @NotNull File outputFolder) { - this.fluidsFile = fluidsFile; - this.outputFolder = outputFolder; - } - - @Override - public void generate() { - if (fluidsFile == null) { - LOGGER.error("Failed to find fluids.json."); - LOGGER.error("Stopped code generation for fluids."); - return; - } - if (!outputFolder.exists() && !outputFolder.mkdirs()) { - LOGGER.error("Output folder for code generation does not exist and could not be created."); - return; - } - // Important classes we use alot - ClassName namespaceIDClassName = ClassName.get("net.minestom.server.utils", "NamespaceID"); - ClassName registriesClassName = ClassName.get("net.minestom.server.registry", "FluidRegistries"); - - JsonObject fluids = GSON.fromJson(new InputStreamReader(fluidsFile), JsonObject.class); - ClassName fluidClassName = ClassName.get("net.minestom.server.fluid", "Fluid"); - - // Particle - TypeSpec.Builder fluidClass = TypeSpec.enumBuilder(fluidClassName) - .addSuperinterface(ClassName.get("net.kyori.adventure.key", "Keyed")) - .addModifiers(Modifier.PUBLIC).addJavadoc("AUTOGENERATED by " + getClass().getSimpleName()); - - fluidClass.addField( - FieldSpec.builder(namespaceIDClassName, "id") - .addModifiers(Modifier.PRIVATE, Modifier.FINAL).addAnnotation(NotNull.class).build() - ); - // static field - fluidClass.addField( - FieldSpec.builder(ArrayTypeName.of(fluidClassName), "VALUES") - .addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL) - .initializer("values()") - .build() - ); - - fluidClass.addMethod( - MethodSpec.constructorBuilder() - .addParameter(ParameterSpec.builder(namespaceIDClassName, "id").addAnnotation(NotNull.class).build()) - .addStatement("this.id = id") - .addStatement("$T.fluids.put(id, this)", registriesClassName) - .build() - ); - // Override key method (adventure) - fluidClass.addMethod( - MethodSpec.methodBuilder("key") - .returns(ClassName.get("net.kyori.adventure.key", "Key")) - .addAnnotation(Override.class) - .addAnnotation(NotNull.class) - .addStatement("return this.id") - .addModifiers(Modifier.PUBLIC) - .build() - ); - // getId method - fluidClass.addMethod( - MethodSpec.methodBuilder("getId") - .returns(TypeName.SHORT) - .addStatement("return (short) ordinal()") - .addModifiers(Modifier.PUBLIC) - .build() - ); - // getNamespaceID method - fluidClass.addMethod( - MethodSpec.methodBuilder("getNamespaceID") - .returns(namespaceIDClassName) - .addAnnotation(NotNull.class) - .addStatement("return this.id") - .addModifiers(Modifier.PUBLIC) - .build() - ); - // toString method - fluidClass.addMethod( - MethodSpec.methodBuilder("toString") - .addAnnotation(NotNull.class) - .addAnnotation(Override.class) - .returns(String.class) - // this resolves to [Namespace] - .addStatement("return \"[\" + this.id + \"]\"") - .addModifiers(Modifier.PUBLIC) - .build() - ); - - // fromId Method - fluidClass.addMethod( - MethodSpec.methodBuilder("fromId") - .returns(fluidClassName) - .addAnnotation(Nullable.class) - .addParameter(TypeName.SHORT, "id") - .beginControlFlow("if(id >= 0 && id < VALUES.length)") - .addStatement("return VALUES[id]") - .endControlFlow() - .addStatement("return null") - .addModifiers(Modifier.PUBLIC, Modifier.STATIC) - .build() - ); - - // Use data - fluids.entrySet().forEach(entry -> { - final String fluidName = entry.getKey(); - fluidClass.addEnumConstant(toConstant(fluidName), TypeSpec.anonymousClassBuilder( - "$T.from($S)", - namespaceIDClassName, - fluidName - ).build() - ); - }); - - // Write files to outputFolder - writeFiles( - List.of( - JavaFile.builder("net.minestom.server.fluid", fluidClass.build()) - .indent(" ") - .skipJavaLangImports(true) - .build() - ), - outputFolder - ); - } -} diff --git a/code-generators/src/main/java/net/minestom/codegen/particle/ParticleGenerator.java b/code-generators/src/main/java/net/minestom/codegen/particle/ParticleGenerator.java index 14b13e3e0a4..d0ca3f1f328 100644 --- a/code-generators/src/main/java/net/minestom/codegen/particle/ParticleGenerator.java +++ b/code-generators/src/main/java/net/minestom/codegen/particle/ParticleGenerator.java @@ -12,7 +12,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.lang.model.element.Modifier; import java.io.File; import java.io.InputStream; import java.io.InputStreamReader; @@ -23,7 +22,8 @@ public class ParticleGenerator extends MinestomCodeGenerator { private static final Logger LOGGER = LoggerFactory.getLogger(ParticleGenerator.class); - + private static final String PARTICLE_PACKAGE = "net.minestom.server.particle"; + private static final Pattern PASCAL_PATTERN = Pattern.compile("_([a-z])"); private final InputStream particlesFile; private final File outputFolder; @@ -45,8 +45,8 @@ public void generate() { } // Important classes we use alot - ClassName particleCN = ClassName.get("net.minestom.server.particle", "Particle"); - ClassName particleImplCN = ClassName.get("net.minestom.server.particle", "ParticleImpl"); + ClassName particleCN = ClassName.get(PARTICLE_PACKAGE, "Particle"); + ClassName particleImplCN = ClassName.get(PARTICLE_PACKAGE, "ParticleImpl"); JsonObject particleObject = GSON.fromJson(new InputStreamReader(particlesFile), JsonObject.class); List> orderedParticleIdObjectEntries = particleObject.entrySet().stream() @@ -54,7 +54,7 @@ public void generate() { // Start code gen - ClassName particlesCN = ClassName.get("net.minestom.server.particle", "Particles"); + ClassName particlesCN = ClassName.get(PARTICLE_PACKAGE, "Particles"); TypeSpec.Builder particlesInterface = TypeSpec.interfaceBuilder(particlesCN) .addJavadoc("AUTOGENERATED by " + getClass().getSimpleName()); @@ -65,7 +65,7 @@ public void generate() { ClassName fieldCN = particleCN; if (value.get("hasData").getAsBoolean()) { // This particle has data, use the particle implementation class - fieldCN = ClassName.get("net.minestom.server.particle", "Particle", + fieldCN = ClassName.get(PARTICLE_PACKAGE, "Particle", toPascalCase(key.replace("minecraft:", ""))); } @@ -78,20 +78,19 @@ public void generate() { String fieldName = key.replace("minecraft:", "").toUpperCase(); particlesInterface.addField(FieldSpec.builder(fieldCN, fieldName) - .addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) + .addModifiers(CONSTANT_MODIFIERS) .initializer("$L$T.get($S)", cast, particleImplCN, key).build()); } - writeFiles( - List.of(JavaFile.builder("net.minestom.server.particle", particlesInterface.build()) - .indent(" ") - .skipJavaLangImports(true) - .build()), - outputFolder); + final JavaFile javaFile = JavaFile.builder(PARTICLE_PACKAGE, particlesInterface.build()) + .indent(DEFAULT_INDENT) + .skipJavaLangImports(true) + .build(); + writeFile(javaFile, outputFolder); } - private static String toPascalCase(@NotNull String input) { - String camelCase = Pattern.compile("_([a-z])") + private static @NotNull String toPascalCase(@NotNull String input) { + String camelCase = PASCAL_PATTERN .matcher(input) .replaceAll(m -> m.group(1).toUpperCase()); return camelCase.substring(0, 1).toUpperCase() + camelCase.substring(1); diff --git a/code-generators/src/main/java/net/minestom/codegen/recipe/RecipeTypeGenerator.java b/code-generators/src/main/java/net/minestom/codegen/recipe/RecipeTypeGenerator.java index 749dfc091aa..ca7f3a440f8 100644 --- a/code-generators/src/main/java/net/minestom/codegen/recipe/RecipeTypeGenerator.java +++ b/code-generators/src/main/java/net/minestom/codegen/recipe/RecipeTypeGenerator.java @@ -5,6 +5,7 @@ import com.google.gson.JsonObject; import com.squareup.javapoet.*; import net.minestom.codegen.MinestomCodeGenerator; +import net.minestom.codegen.util.GenerationHelper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @@ -18,8 +19,11 @@ import java.util.List; import java.util.stream.StreamSupport; +import static net.minestom.codegen.util.GenerationHelper.VARIABLE_GETTER; + public class RecipeTypeGenerator extends MinestomCodeGenerator { private static final Logger LOGGER = LoggerFactory.getLogger(RecipeTypeGenerator.class); + private static final String NAMESPACE = "namespace"; private final InputStream recipeTypesFile; private final File outputFolder; @@ -54,10 +58,10 @@ public void generate() { // Fields recipeTypeEnum.addFields( List.of( - FieldSpec.builder(networkBufferTypeCN, "NETWORK_TYPE", Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) + FieldSpec.builder(networkBufferTypeCN, "NETWORK_TYPE", CONSTANT_MODIFIERS) .initializer("$T.Enum($T.class)", networkBufferCN, recipeTypeCN) .build(), - FieldSpec.builder(namespaceIdCN, "namespace", Modifier.PRIVATE, Modifier.FINAL).build() + FieldSpec.builder(namespaceIdCN, NAMESPACE, PRIVATE_FINAL_MODIFIERS).build() ) ); @@ -66,21 +70,21 @@ public void generate() { List.of( // Constructor MethodSpec.constructorBuilder() - .addParameter(ParameterSpec.builder(namespaceIdCN, "namespace").addAnnotation(NotNull.class).build()) - .addStatement("this.namespace = namespace") + .addParameter(ParameterSpec.builder(namespaceIdCN, NAMESPACE).addAnnotation(NotNull.class).build()) + .addStatement(GenerationHelper.VARIABLE_SETTER, NAMESPACE) .build(), - MethodSpec.methodBuilder("namespace") + MethodSpec.methodBuilder(NAMESPACE) .addModifiers(Modifier.PUBLIC) .addAnnotation(NotNull.class) .addAnnotation(Override.class) .returns(namespaceIdCN) - .addStatement("return this.namespace") + .addStatement(VARIABLE_GETTER, NAMESPACE) .build(), MethodSpec.methodBuilder("id") .addModifiers(Modifier.PUBLIC) .returns(TypeName.INT) .addAnnotation(Override.class) - .addStatement("return this.ordinal()") + .addStatement(VARIABLE_GETTER, "ordinal()") .build() ) ); @@ -96,15 +100,11 @@ public void generate() { } // Write files to outputFolder - writeFiles( - List.of( - JavaFile.builder("net.minestom.server.recipe", recipeTypeEnum.build()) - .indent(" ") - .skipJavaLangImports(true) - .build() - ), - outputFolder - ); + final JavaFile javaFile = JavaFile.builder("net.minestom.server.recipe", recipeTypeEnum.build()) + .indent(DEFAULT_INDENT) + .skipJavaLangImports(true) + .build(); + writeFile(javaFile, outputFolder); } private static @NotNull String recipeTypeConstantName(@NotNull String name) { diff --git a/code-generators/src/main/java/net/minestom/codegen/util/GenerationHelper.java b/code-generators/src/main/java/net/minestom/codegen/util/GenerationHelper.java new file mode 100644 index 00000000000..08f8eb7a9da --- /dev/null +++ b/code-generators/src/main/java/net/minestom/codegen/util/GenerationHelper.java @@ -0,0 +1,48 @@ +package net.minestom.codegen.util; + +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.MethodSpec; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +import javax.lang.model.element.Modifier; + +import static net.minestom.codegen.MinestomCodeGenerator.NAMESPACE_ID_CLASS; + +@ApiStatus.Internal +@ApiStatus.NonExtendable +public final class GenerationHelper { + + public static final ClassName ADVENTURE_KEY = ClassName.get("net.kyori.adventure.key", "Key"); + public static final MethodSpec ID_GETTER; + public static final MethodSpec ADVENTURE_KEY_METHOD; + public static final MethodSpec TO_STRING; + public static final String VARIABLE_SETTER = "this.$1L = $1L"; + public static final String VARIABLE_GETTER = "return this.$1L"; + + static { + ID_GETTER = MethodSpec.methodBuilder("getId") + .returns(NAMESPACE_ID_CLASS) + .addAnnotation(NotNull.class) + .addStatement(VARIABLE_GETTER, "id") + .addModifiers(Modifier.PUBLIC) + .build(); + ADVENTURE_KEY_METHOD = MethodSpec.methodBuilder("key") + .returns(ADVENTURE_KEY) + .addAnnotation(Override.class) + .addAnnotation(NotNull.class) + .addStatement(VARIABLE_GETTER, "id") + .addModifiers(Modifier.PUBLIC) + .build(); + TO_STRING = MethodSpec.methodBuilder("toString") + .addAnnotation(NotNull.class) + .addAnnotation(Override.class) + .returns(String.class) + // this resolves to [Namespace] + .addStatement("return \"[\" + this.id + \"]\"") + .addModifiers(Modifier.PUBLIC) + .build(); + } + + private GenerationHelper() { } +} diff --git a/demo/build.gradle.kts b/demo/build.gradle.kts index 2e5671e61f4..e4af107a603 100644 --- a/demo/build.gradle.kts +++ b/demo/build.gradle.kts @@ -2,21 +2,28 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar plugins { application - alias(libs.plugins.shadow) + id("minestom.common-conventions") + id("minestom.native-conventions") + id("com.github.johnrengelman.shadow") version ("7.1.2") +// id("net.onelitefeather.microtus.extension") +} + +application { + mainClass.set("net.minestom.demo.Main") + // This is included because Shadow is buggy. Wait for https://github.com/johnrengelman/shadow/issues/613 to befixed. } dependencies { +// extensionLibrary("com.fasterxml.jackson.module:jackson-module-kotlin:2.15.2") implementation(rootProject) - - runtimeOnly(libs.bundles.logback) + implementation(libs.jNoise) } -tasks { - application { - mainClass.set("net.minestom.demo.Main") - } +tasks.withType { + archiveFileName.set("minestom-demo.jar") +} - withType { - archiveFileName.set("minestom-demo.jar") - } -} \ No newline at end of file +/*extension { + authors = listOf("yolo") + entrypoint = "net.onelitefeather.microtus.extension.Test" +}*/ \ No newline at end of file diff --git a/demo/src/main/java/net/minestom/demo/PlayerInit.java b/demo/src/main/java/net/minestom/demo/PlayerInit.java index 0369ae9da70..9311673fd6b 100644 --- a/demo/src/main/java/net/minestom/demo/PlayerInit.java +++ b/demo/src/main/java/net/minestom/demo/PlayerInit.java @@ -5,8 +5,6 @@ import net.minestom.server.FeatureFlag; import net.minestom.server.MinecraftServer; import net.minestom.server.advancements.FrameType; -import net.minestom.server.advancements.notifications.Notification; -import net.minestom.server.advancements.notifications.NotificationCenter; import net.minestom.server.adventure.MinestomAdventure; import net.minestom.server.adventure.audience.Audiences; import net.minestom.server.coordinate.Pos; @@ -24,7 +22,16 @@ import net.minestom.server.event.entity.EntityAttackEvent; import net.minestom.server.event.item.ItemDropEvent; import net.minestom.server.event.item.PickupItemEvent; -import net.minestom.server.event.player.*; +import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; +import net.minestom.server.event.player.PlayerBlockInteractEvent; +import net.minestom.server.event.player.PlayerBlockPlaceEvent; +import net.minestom.server.event.player.PlayerDeathEvent; +import net.minestom.server.event.player.PlayerDisconnectEvent; +import net.minestom.server.event.player.PlayerHandAnimationEvent; +import net.minestom.server.event.player.PlayerPacketEvent; +import net.minestom.server.event.player.PlayerPacketOutEvent; +import net.minestom.server.event.player.PlayerSpawnEvent; +import net.minestom.server.event.player.PlayerUseItemOnBlockEvent; import net.minestom.server.event.server.ServerTickMonitorEvent; import net.minestom.server.instance.Instance; import net.minestom.server.instance.InstanceContainer; @@ -47,9 +54,11 @@ import net.minestom.server.monitoring.TickMonitor; import net.minestom.server.network.packet.server.common.CustomReportDetailsPacket; import net.minestom.server.network.packet.server.common.ServerLinksPacket; +import net.minestom.server.notifications.Notification; import net.minestom.server.potion.CustomPotionEffect; import net.minestom.server.potion.PotionEffect; import net.minestom.server.sound.SoundEvent; +import net.minestom.server.notifications.Notification; import net.minestom.server.utils.MathUtils; import net.minestom.server.utils.NamespaceID; import net.minestom.server.utils.time.TimeUnit; @@ -183,13 +192,11 @@ class A { if (event.isFirstSpawn()) { - Notification notification = new Notification( - Component.text("Welcome!"), - FrameType.TASK, - Material.IRON_SWORD - ); - NotificationCenter.send(notification, event.getPlayer()); - + Notification notification = Notification.builder() + .frameType(FrameType.TASK) + .title(Component.text("Welcome!")) + .icon(Material.IRON_SWORD).build(); + notification.send(player); player.playSound(Sound.sound(SoundEvent.ENTITY_EXPERIENCE_ORB_PICKUP, Sound.Source.PLAYER, 0.5f, 1f)); } }) diff --git a/demo/src/main/java/net/minestom/demo/commands/NotificationCommand.java b/demo/src/main/java/net/minestom/demo/commands/NotificationCommand.java index d5fc7453ed1..e5667972278 100644 --- a/demo/src/main/java/net/minestom/demo/commands/NotificationCommand.java +++ b/demo/src/main/java/net/minestom/demo/commands/NotificationCommand.java @@ -2,12 +2,9 @@ import net.kyori.adventure.text.Component; import net.minestom.server.advancements.FrameType; -import net.minestom.server.advancements.notifications.Notification; -import net.minestom.server.advancements.notifications.NotificationCenter; import net.minestom.server.command.builder.Command; import net.minestom.server.entity.Player; import net.minestom.server.item.Material; -import org.jetbrains.annotations.NotNull; public class NotificationCommand extends Command { public NotificationCommand() { @@ -15,9 +12,12 @@ public NotificationCommand() { setDefaultExecutor((sender, context) -> { var player = (Player) sender; - - var notification = new Notification(Component.text("Hello World!"), FrameType.GOAL, Material.DIAMOND_AXE); - NotificationCenter.send(notification, player); + var notification = net.minestom.server.notifications.Notification.builder() + .title(Component.text("Hello World!")) + .frameType(FrameType.GOAL) + .icon(Material.DIAMOND_AXE) + .build(); + notification.send(player); }); } } diff --git a/demo/src/main/java/net/minestom/demo/commands/TestCommand.java b/demo/src/main/java/net/minestom/demo/commands/TestCommand.java index 75482a6787f..185a8d4d31a 100644 --- a/demo/src/main/java/net/minestom/demo/commands/TestCommand.java +++ b/demo/src/main/java/net/minestom/demo/commands/TestCommand.java @@ -8,6 +8,7 @@ import net.minestom.server.command.builder.Command; import net.minestom.server.command.builder.CommandContext; import net.minestom.server.command.builder.arguments.ArgumentType; +import net.minestom.server.entity.Player; import net.minestom.server.sound.SoundEvent; public class TestCommand extends Command { @@ -21,7 +22,9 @@ public TestCommand() { setDefaultExecutor((sender, context) -> { sender.playSound(Sound.sound(Key.key("item.trumpet.doot"), Sound.Source.PLAYER, 1, 1)); - AdventurePacketConvertor.createSoundPacket(Sound.sound(Key.key(SoundEvent.BLOCK_ANVIL_HIT.name()), Sound.Source.HOSTILE, 1, 1), sender.asPlayer()); + if (sender instanceof Player player) { + AdventurePacketConvertor.createSoundPacket(Sound.sound(Key.key(SoundEvent.BLOCK_ANVIL_HIT.name()), Sound.Source.HOSTILE, 1, 1), player); + } }); addSyntax((sender, context) -> System.out.println("executed"), block); diff --git a/extension/build.gradle.kts b/extension/build.gradle.kts new file mode 100644 index 00000000000..08854349d3c --- /dev/null +++ b/extension/build.gradle.kts @@ -0,0 +1,86 @@ +import java.time.Duration +import java.util.* + +plugins { + `java-gradle-plugin` + `kotlin-dsl` + id("com.gradle.plugin-publish") version "1.2.1" + id("org.cadixdev.licenser") version "0.6.1" + id("io.github.gradle-nexus.publish-plugin") version "2.0.0-rc-1" + signing +} + +var baseVersion by extra("1.0.1") +var snapshot by extra("-SNAPSHOT") + +group = "net.onelitefeather.microtus" + + +version = "%s%s".format(Locale.ROOT, baseVersion, snapshot) + +repositories { + mavenCentral() + gradlePluginPortal() +} + +dependencies { + implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.15.2") { + exclude(group = "org.jetbrains.kotlin") + } + testImplementation(platform("org.junit:junit-bom:5.10.1")) + testImplementation("org.junit.jupiter:junit-jupiter:5.10.1") +} +gradlePlugin { + // website.set("https://github.com/OneLiteFeatherNET/Microtus") + // vcsUrl.set("https://github.com/OneLiteFeatherNET/Microtus") + plugins { + register("extension") { + id = "net.onelitefeather.microtus.extension" + displayName = "Extension (Minestom)" + description = "Generate extension.json for Minestom extensions based on the Gradle project" + implementationClass = "net.onelitefeather.microtus.ExtensionPlugin" + // tags.set(listOf("minestom", "microtus", "extension")) + } + } +} + +nexusPublishing{ + useStaging.set(true) + + transitionCheckOptions { + maxRetries.set(360) // 1 hour + delayBetween.set(Duration.ofSeconds(10)) + } + + repositories.sonatype { + nexusUrl.set(uri("https://s01.oss.sonatype.org/service/local/")) + snapshotRepositoryUrl.set(uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")) + + if (System.getenv("SONATYPE_USERNAME") != null) { + username.set(System.getenv("SONATYPE_USERNAME")) + password.set(System.getenv("SONATYPE_PASSWORD")) + } + } +} + +publishing { + repositories { + maven { + url = uri("https://maven.pkg.github.com/OneLiteFeatherNET/Microtus") + credentials { + username = System.getenv("GITHUB_ACTOR") + password = System.getenv("GITHUB_TOKEN") + } + } + } +} + +signing { + isRequired = System.getenv("CI") != null + + val privateKey = System.getenv("GPG_PRIVATE_KEY") + val keyPassphrase = System.getenv()["GPG_PASSPHRASE"] + useInMemoryPgpKeys(privateKey, keyPassphrase) + + sign(publishing.publications) +} \ No newline at end of file diff --git a/extension/src/main/kotlin/net/onelitefeather/microtus/ExtensionPlugin.kt b/extension/src/main/kotlin/net/onelitefeather/microtus/ExtensionPlugin.kt new file mode 100644 index 00000000000..e02e9d94396 --- /dev/null +++ b/extension/src/main/kotlin/net/onelitefeather/microtus/ExtensionPlugin.kt @@ -0,0 +1,76 @@ +package net.onelitefeather.microtus + +import net.onelitefeather.microtus.models.Extension +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.plugins.JavaPlugin +import org.gradle.api.tasks.SourceSet +import org.gradle.api.tasks.SourceSetContainer +import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.register +import org.gradle.kotlin.dsl.withType + +/** + * Represents the gradle plugin extension which can be integrated into a `build.gradle.kts` file to define the properties of the extension. + * The usage of this plugin is as follows: + * + * ```kotlin + * plugins { + * id("net.onelitefeather.microtus.extension") version "" + * // ... + * } + * + * extension { + * //... use the properties of the extension here + * } + * ``` + * + * @since 1.2.0 + * @author TheMeinerLP + */ +class ExtensionPlugin : Plugin { + + private val fileName = "extension.json" + + /** + * Applies the plugin to the project. + * @param target the project to apply the plugin to + */ + override fun apply(target: Project) { + target.run { + val generatedResourcesDirectory = layout.buildDirectory.dir("generated/extension") + val extension = Extension() + extensions.add("extension", extension) + + val library = project.configurations.maybeCreate("library") + val libraries = project.configurations.create("extensionLibrary").extendsFrom(library) + + val generateTask = tasks.register("generateExtension") { + group = "minestom" + + fileName.set(this@ExtensionPlugin.fileName) + librariesRootComponent.set(libraries.incoming.resolutionResult.root) + outputDirectory.set(generatedResourcesDirectory) + this.extension.set(provider { + setDefaults(project, extension) + extension + }) + } + plugins.withType { + extensions.getByType().named(SourceSet.MAIN_SOURCE_SET_NAME) { + resources.srcDir(generateTask) + } + } + } + } + + /** + * Sets some default variables to a [Extension] object. + * @param project the project to get the name and version from + * @param extension the extension to set the variables to + */ + private fun setDefaults(project: Project, extension: Extension) { + extension.name = extension.name ?: project.name + extension.version = extension.version ?: project.version.toString() + } +} \ No newline at end of file diff --git a/extension/src/main/kotlin/net/onelitefeather/microtus/GenerateExtension.kt b/extension/src/main/kotlin/net/onelitefeather/microtus/GenerateExtension.kt new file mode 100644 index 00000000000..0df18c5afb0 --- /dev/null +++ b/extension/src/main/kotlin/net/onelitefeather/microtus/GenerateExtension.kt @@ -0,0 +1,79 @@ +package net.onelitefeather.microtus + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.databind.module.SimpleModule +import com.fasterxml.jackson.module.kotlin.registerKotlinModule +import net.onelitefeather.microtus.models.Extension +import org.gradle.api.DefaultTask +import org.gradle.api.artifacts.repositories.MavenArtifactRepository +import org.gradle.api.artifacts.result.ResolvedComponentResult +import org.gradle.api.artifacts.result.ResolvedDependencyResult +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.* +import kotlin.jvm.Throws + +/** + * Defines the task which generates the required extension.json file for Minestom. + * @since 1.2.0 + * @author TheMeinerLP + */ +abstract class GenerateExtension : DefaultTask() { + @get:Input + abstract val fileName: Property + + @get:Nested + abstract val extension: Property + + @get:OutputDirectory + abstract val outputDirectory: DirectoryProperty + + @get:Input + @get:Optional + abstract val librariesRootComponent: Property + + /** + * Generates an extension.json file based on the given properties. + */ + @TaskAction + fun generate() { + val module = SimpleModule() + val mapper = ObjectMapper() + .registerKotlinModule() + .registerModule(module) + .setSerializationInclusion(JsonInclude.Include.NON_EMPTY) + val extension = extension.get() + val dependencies = librariesRootComponent.orNull.collectLibraries() + val repos = this.project.repositories.withType(MavenArtifactRepository::class.java) + val externalDependencies = Extension.ExternalDependencies() + externalDependencies.artifacts = dependencies.toList() + val mavenCentral = Extension.Repository() + mavenCentral.url = "https://repo.maven.apache.org/maven2/" + mavenCentral.name = "mavenCentral" + val mappedRepos = repos.map { + val repo = Extension.Repository() + repo.url = it.url.toString() + repo.name = it.name + repo + }.toList() + externalDependencies.repositories = if (mappedRepos.isNotEmpty() || dependencies.isNotEmpty()) { + mappedRepos + listOf(mavenCentral) + } else { + listOf() + } + extension.externalDependencies = externalDependencies + mapper.writeValue(outputDirectory.file(fileName).get().asFile, extension) + } + + /** + * Collects all libraries from the root component and the additional libraries. + * @param additional the additional libraries to add + */ + private fun ResolvedComponentResult?.collectLibraries(additional: List? = null): List { + val resolved = this?.dependencies?.map { dependencyResult -> + (dependencyResult as? ResolvedDependencyResult)?.selected?.moduleVersion?.toString() ?: error("No moduleVersion for $dependencyResult") + } + return ((additional ?: listOf()) + (resolved ?: listOf())).distinct() + } +} \ No newline at end of file diff --git a/extension/src/main/kotlin/net/onelitefeather/microtus/models/Extension.kt b/extension/src/main/kotlin/net/onelitefeather/microtus/models/Extension.kt new file mode 100644 index 00000000000..3e8976c5970 --- /dev/null +++ b/extension/src/main/kotlin/net/onelitefeather/microtus/models/Extension.kt @@ -0,0 +1,76 @@ +package net.onelitefeather.microtus.models + +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Optional +import org.gradle.internal.impldep.com.fasterxml.jackson.annotation.JsonProperty + +/** + * Represents the allowed data fields for an extension.json file which is required from Minestom to load an extension. + * The following fields are allowed (fields with a * are required): + * + * - name: The name of the extension (*) + * - version: The version of the extension (*) + * - entrypoint: The entrypoint of the extension (*) + * - authors: The authors of the extension + * - dependencies: The dependencies of the extension + * - externalDependencies: The external dependencies of the extension + * @since 1.2.0 + * @author TheMeinerLP + */ +class Extension() { + @Input + var name: String? = null + + @Input + var version: String? = null + + @Input + var entrypoint: String? = null + + @Input + @Optional + @JsonProperty("authors") + var authors: List? = null + + @Input + @Optional + @JsonProperty("dependencies") + var dependencies: List? = null + + @Input + @Optional + @JsonProperty("externalDependencies") + var externalDependencies: ExternalDependencies? = null + + /** + * Represents the external dependencies which is required for the extension to work. + * @since 1.2.0 + * @author TheMeinerLP + */ + class ExternalDependencies { + @JsonProperty("repositories") + var repositories: List? = null + + @Input + @Optional + @JsonProperty("artifacts") + var artifacts: List? = null + + } + + /** + * Represents a repository which is used by an extension to load external dependencies. + * @since 1.2.0 + * @author TheMeinerLP + * @see ExternalDependencies + */ + class Repository { + @Input + @JsonProperty("name") + var name: String? = null + + @Input + @JsonProperty("url") + var url: String? = null + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d75cacb1ef2..e69de29bb2d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,87 +0,0 @@ -metadata.format.version = "1.1" - -[versions] - -# Important dependencies -data = "1.21-rv3" -adventure = "4.17.0" -jetbrainsAnnotations = "24.1.0" -slf4j = "2.0.7" - -# Performance / Data Structures -caffeine = "3.1.8" -fastutil = "8.5.14" -flare = "2.0.1" -gson = "2.11.0" -jcTools = "4.0.5" - -# Quality -junit-jupiter = "5.9.3" -junit-platform = "1.9.3" -jmh = "1.36" -jcstress = "0.16" - -# Code Generation -javaPoet = "1.13.0" - -# Log impl (for demo & codegen) -logback = "1.4.5" - -# Gradle plugins -blossom = "1.3.0" -shadow = "8.1.1" -nexuspublish = "1.3.0" - -[libraries] - -# Important Dependencies -# Adventure -adventure-api = { group = "net.kyori", name = "adventure-api", version.ref = "adventure" } -adventure-nbt = { group = "net.kyori", name = "adventure-nbt", version.ref = "adventure" } -adventure-serializer-gson = { group = "net.kyori", name = "adventure-text-serializer-gson", version.ref = "adventure" } -adventure-serializer-legacy = { group = "net.kyori", name = "adventure-text-serializer-legacy", version.ref = "adventure" } -adventure-serializer-plain = { group = "net.kyori", name = "adventure-text-serializer-plain", version.ref = "adventure" } -adventure-text-logger-slf4j = { group = "net.kyori", name = "adventure-text-logger-slf4j", version.ref = "adventure" } - -# Miscellaneous -minestomData = { group = "net.minestom", name = "data", version.ref = "data" } -jetbrainsAnnotations = { group = "org.jetbrains", name = "annotations", version.ref = "jetbrainsAnnotations" } -slf4j = { group = "org.slf4j", name = "slf4j-api", version.ref = "slf4j"} - -# Performance / Data Structures -caffeine = { group = "com.github.ben-manes.caffeine", name = "caffeine", version.ref = "caffeine" } -fastutil = { group = "it.unimi.dsi", name = "fastutil", version.ref = "fastutil" } -flare = { group = "space.vectrix.flare", name = "flare", version.ref = "flare" } -flare-fastutil = { group = "space.vectrix.flare", name = "flare-fastutil", version.ref = "flare" } -gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } -jcTools = { group = "org.jctools", name = "jctools-core", version.ref = "jcTools" } - -# Code quality -junit-api = { group = "org.junit.jupiter", name = "junit-jupiter-api", version.ref = "junit-jupiter" } -junit-engine = { group = "org.junit.jupiter", name = "junit-jupiter-engine", version.ref = "junit-jupiter" } -junit-params = { group = "org.junit.jupiter", name = "junit-jupiter-params", version.ref = "junit-jupiter" } -junit-suite-api = { group = "org.junit.platform", name = "junit-platform-suite-api", version.ref = "junit-platform" } -junit-suite-engine = { group = "org.junit.platform", name = "junit-platform-suite-engine", version.ref = "junit-platform" } -jmh-core = { group = "org.openjdk.jmh", name = "jmh-core", version.ref = "jmh" } -jmh-annotationprocessor = { group = "org.openjdk.jmh", name = "jmh-generator-annprocess", version.ref = "jmh" } -jcstress-core = { group = "org.openjdk.jcstress", name = "jcstress-core", version.ref = "jcstress" } - -# Code Generation -javaPoet = { group = "com.squareup", name = "javapoet", version.ref = "javaPoet" } - -# Log impl (for demo & codegen) -logback-core = { group = "ch.qos.logback", name = "logback-core", version.ref = "logback" } -logback-classic = { group = "ch.qos.logback", name = "logback-classic", version.ref = "logback" } - -[bundles] - -flare = ["flare", "flare-fastutil"] -adventure = ["adventure-api", "adventure-nbt", "adventure-serializer-gson", "adventure-serializer-legacy", "adventure-serializer-plain", "adventure-text-logger-slf4j"] -junit = ["junit-api", "junit-engine", "junit-params", "junit-suite-api", "junit-suite-engine"] -logback = ["logback-core", "logback-classic"] - -[plugins] - -blossom = { id = "net.kyori.blossom", version.ref = "blossom" } -shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } -nexuspublish = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "nexuspublish" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd491770..e6441136f3d 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a80b22ce5cf..6f7a6eb33e8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a42690..b740cf13397 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. diff --git a/jcstress-tests/build.gradle.kts b/jcstress-tests/build.gradle.kts index 6f1943f8128..b2fda1d37d2 100644 --- a/jcstress-tests/build.gradle.kts +++ b/jcstress-tests/build.gradle.kts @@ -1,5 +1,6 @@ plugins { id("io.github.reyerizo.gradle.jcstress") version "0.8.15" + id("minestom.common-conventions") } dependencies { diff --git a/jitpack.yml b/jitpack.yml deleted file mode 100644 index a2027925630..00000000000 --- a/jitpack.yml +++ /dev/null @@ -1,2 +0,0 @@ -jdk: - - openjdk21 \ No newline at end of file diff --git a/licenses/MIT.md b/licenses/MIT.md new file mode 100644 index 00000000000..e7e2f7a0d37 --- /dev/null +++ b/licenses/MIT.md @@ -0,0 +1,23 @@ +The MIT License (MIT) +===================== + +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. \ No newline at end of file diff --git a/licenses/apache_2_0.md b/licenses/apache_2_0.md new file mode 100644 index 00000000000..3e91a212221 --- /dev/null +++ b/licenses/apache_2_0.md @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +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. \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 486c51ef5e4..b306354c05e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,8 +1,149 @@ -rootProject.name = "minestom" +dependencyResolutionManagement { + repositories { + maven("https://s01.oss.sonatype.org/content/repositories/snapshots") + maven("https://jitpack.io") + mavenCentral() + } + versionCatalogs { + create("libs") { + // Important dependencies + version("adventure", "4.17.0") + version("kotlin", "2.0.0") + version("data", "1.21-rv3") + version("jetbrainsAnnotations", "24.1.0") + version("logback", "1.4.5") + version("slf4j", "2.0.7") + version("maven-resolver", "1.9.18") + version("maven-resolver-provider", "3.9.6") -include("testing") + // Terminal / Logging + version("tinylog", "2.6.2") + version("jline", "3.25.1") + + // Performance / Data Structures + version("caffeine", "3.1.8") + version("fastutil", "8.5.12") + version("flare", "2.0.1") + version("gson", "2.11.0") + version("jcTools", "4.0.2") + + // Test + version("junit-jupiter", "5.10.1") + version("junit-platform", "1.10.1") + version("mockito", "5.12.0") + + // Code Generation + version("javaPoet", "1.13.0") + + // Demo + version("jNoise", "b93008e35e") + + // JMH + version("jmh", "1.37") + + // JCStress + version("jcstress", "0.16") + + // Gradle plugins + version("blossom", "2.1.0") + + // BStats + version("bstats", "3.0.2") + + // Libs + library("adventure-api", "net.kyori", "adventure-api").versionRef("adventure") + library("adventure-nbt", "net.kyori", "adventure-nbt").versionRef("adventure") + library("adventure-serializer-gson", "net.kyori", "adventure-text-serializer-gson").versionRef("adventure") + library("adventure-serializer-legacy", "net.kyori", "adventure-text-serializer-legacy").versionRef("adventure") + library("adventure-serializer-plain", "net.kyori", "adventure-text-serializer-plain").versionRef("adventure") + library("adventure-text-logger-slf4j", "net.kyori", "adventure-text-logger-slf4j").versionRef("adventure") + library("adventure-mini-message", "net.kyori", "adventure-text-minimessage").versionRef("adventure") + + // Maven + library("maven.connector", "org.apache.maven.resolver", "maven-resolver-connector-basic").versionRef("maven-resolver") + library("maven.transport.http", "org.apache.maven.resolver", "maven-resolver-transport-http").versionRef("maven-resolver") + library("maven.resolver", "org.apache.maven", "maven-resolver-provider").versionRef("maven-resolver-provider") + + // Kotlin + library("kotlin-reflect", "org.jetbrains.kotlin", "kotlin-reflect").versionRef("kotlin") + library("kotlin-stdlib-jdk8", "org.jetbrains.kotlin", "kotlin-stdlib-jdk8").versionRef("kotlin") + + // Miscellaneous + library("minestomData", "net.minestom", "data").versionRef("data") + library("jetbrainsAnnotations", "org.jetbrains", "annotations").versionRef("jetbrainsAnnotations"); + + // Logging + library("tinylog-api", "org.tinylog", "tinylog-api").versionRef("tinylog") + library("tinylog-impl", "org.tinylog", "tinylog-impl").versionRef("tinylog") + library("tinylog-slf4j", "org.tinylog", "slf4j-tinylog").versionRef("tinylog") + library("slf4j", "org.slf4j", "slf4j-api").versionRef("slf4j") + library("logback-core", "ch.qos.logback", "logback-core").versionRef("logback") + library("logback-classic", "ch.qos.logback", "logback-classic").versionRef("logback") + + // Terminal + library("jline", "org.jline", "jline").versionRef("jline") + library("jline-jansi", "org.jline", "jline-terminal-jansi").versionRef("jline") + + // Performance / Data Structures + library("caffeine", "com.github.ben-manes.caffeine", "caffeine").versionRef("caffeine") + library("fastutil", "it.unimi.dsi", "fastutil").versionRef("fastutil") + library("flare", "space.vectrix.flare", "flare").versionRef("flare") + library("flare-fastutil", "space.vectrix.flare", "flare-fastutil").versionRef("flare") + library("gson", "com.google.code.gson", "gson").versionRef("gson") + library("jcTools", "org.jctools", "jctools-core").versionRef("jcTools") + + // Tests + library("junit-api", "org.junit.jupiter", "junit-jupiter-api").versionRef("junit-jupiter") + library("junit-engine", "org.junit.jupiter", "junit-jupiter-engine").versionRef("junit-jupiter") + library("junit-params", "org.junit.jupiter", "junit-jupiter-params").versionRef("junit-jupiter") + library("junit-suite-api", "org.junit.platform", "junit-platform-suite-api").versionRef("junit-platform") + library("junit-suite-engine", "org.junit.platform", "junit-platform-suite-engine").versionRef("junit-platform") + library("mockito-core", "org.mockito", "mockito-core").versionRef("mockito") + + // Code Generation + library("javaPoet", "com.squareup", "javapoet").versionRef("javaPoet") + + // Demo + library("jNoise", "com.github.Articdive.JNoise", "jnoise-pipeline").versionRef("jNoise") + + // JMH + library("jmh-core", "org.openjdk.jmh", "jmh-core").versionRef("jmh") + library("jmh-annotationprocessor", "org.openjdk.jmh", "jmh-generator-annprocess").versionRef("jmh") + + // JCStress + library("jcstress-core", "org.openjdk.jcstress", "jcstress-core").versionRef("jcstress") + + // BStats + library("bstats-base", "org.bstats", "bstats-base").versionRef("bstats") + + bundle("kotlin", listOf("kotlin-stdlib-jdk8", "kotlin-reflect")) + bundle("flare", listOf("flare", "flare-fastutil")) + bundle("adventure", listOf("adventure-api", "adventure-nbt", "adventure-mini-message", "adventure-serializer-gson", "adventure-serializer-legacy", "adventure-serializer-plain", "adventure-text-logger-slf4j")) + bundle("logging", listOf("tinylog-api", "tinylog-impl", "tinylog-slf4j")) + bundle("terminal", listOf("jline", "jline-jansi")) + bundle("logback", listOf("logback-core", "logback-classic")) + bundle("junit", listOf("junit-api", "junit-engine", "junit-params", "junit-suite-api", "junit-suite-engine")) + + plugin("blossom", "net.kyori.blossom").versionRef("blossom") + + } + } +} + +pluginManagement { + repositories { + mavenCentral() + gradlePluginPortal() + maven("https://files.minecraftforge.net/maven/") + } + includeBuild("build-logic") + includeBuild("extension") +} + +rootProject.name = "Microtus" include("code-generators") include("jmh-benchmarks") -include("jcstress-tests") - +// include("jcstress-tests") +include("testing") +include("bom") include("demo") diff --git a/src/autogenerated/java/net/minestom/server/color/DyeColor.java b/src/autogenerated/java/net/minestom/server/color/DyeColor.java index ff16c321eba..4091cc1fa1b 100644 --- a/src/autogenerated/java/net/minestom/server/color/DyeColor.java +++ b/src/autogenerated/java/net/minestom/server/color/DyeColor.java @@ -4,6 +4,7 @@ import net.minestom.server.network.NetworkBuffer; import net.minestom.server.utils.nbt.BinaryTagSerializer; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * AUTOGENERATED by DyeColorGenerator @@ -45,6 +46,8 @@ public enum DyeColor implements RGBLike { public static final BinaryTagSerializer NBT_TYPE = BinaryTagSerializer.fromEnumStringable(DyeColor.class); + private static final DyeColor[] VALUES = values(); + private final Color textureDiffuseColor; private final Color textColor; @@ -91,4 +94,8 @@ public int blue() { public int mapColorId() { return this.mapColorId; } + + public static @Nullable DyeColor getValue(int id) { + return VALUES[id]; + } } diff --git a/src/autogenerated/java/net/minestom/server/entity/villager/VillagerProfessions.java b/src/autogenerated/java/net/minestom/server/entity/villager/VillagerProfessions.java new file mode 100644 index 00000000000..0f47b8b5050 --- /dev/null +++ b/src/autogenerated/java/net/minestom/server/entity/villager/VillagerProfessions.java @@ -0,0 +1,37 @@ +package net.minestom.server.entity.villager; + +/** + * Code autogenerated, do not edit! + */ +@SuppressWarnings("unused") +interface VillagerProfessions { + VillagerProfession NONE = VillagerProfessionImpl.get("minecraft:none"); + + VillagerProfession ARMORER = VillagerProfessionImpl.get("minecraft:armorer"); + + VillagerProfession BUTCHER = VillagerProfessionImpl.get("minecraft:butcher"); + + VillagerProfession CARTOGRAPHER = VillagerProfessionImpl.get("minecraft:cartographer"); + + VillagerProfession CLERIC = VillagerProfessionImpl.get("minecraft:cleric"); + + VillagerProfession FARMER = VillagerProfessionImpl.get("minecraft:farmer"); + + VillagerProfession FISHERMAN = VillagerProfessionImpl.get("minecraft:fisherman"); + + VillagerProfession FLETCHER = VillagerProfessionImpl.get("minecraft:fletcher"); + + VillagerProfession LEATHERWORKER = VillagerProfessionImpl.get("minecraft:leatherworker"); + + VillagerProfession LIBRARIAN = VillagerProfessionImpl.get("minecraft:librarian"); + + VillagerProfession MASON = VillagerProfessionImpl.get("minecraft:mason"); + + VillagerProfession NITWIT = VillagerProfessionImpl.get("minecraft:nitwit"); + + VillagerProfession SHEPHERD = VillagerProfessionImpl.get("minecraft:shepherd"); + + VillagerProfession TOOLSMITH = VillagerProfessionImpl.get("minecraft:toolsmith"); + + VillagerProfession WEAPONSMITH = VillagerProfessionImpl.get("minecraft:weaponsmith"); +} diff --git a/src/autogenerated/java/net/minestom/server/entity/villager/VillagerTypes.java b/src/autogenerated/java/net/minestom/server/entity/villager/VillagerTypes.java new file mode 100644 index 00000000000..681ce44c1d3 --- /dev/null +++ b/src/autogenerated/java/net/minestom/server/entity/villager/VillagerTypes.java @@ -0,0 +1,21 @@ +package net.minestom.server.entity.villager; + +/** + * Code autogenerated, do not edit! + */ +@SuppressWarnings("unused") +interface VillagerTypes { + VillagerType DESERT = VillagerTypeImpl.get("minecraft:desert"); + + VillagerType JUNGLE = VillagerTypeImpl.get("minecraft:jungle"); + + VillagerType PLAINS = VillagerTypeImpl.get("minecraft:plains"); + + VillagerType SAVANNA = VillagerTypeImpl.get("minecraft:savanna"); + + VillagerType SNOW = VillagerTypeImpl.get("minecraft:snow"); + + VillagerType SWAMP = VillagerTypeImpl.get("minecraft:swamp"); + + VillagerType TAIGA = VillagerTypeImpl.get("minecraft:taiga"); +} diff --git a/src/autogenerated/java/net/minestom/server/feature/FeatureFlags.java b/src/autogenerated/java/net/minestom/server/feature/FeatureFlags.java new file mode 100644 index 00000000000..983bd307419 --- /dev/null +++ b/src/autogenerated/java/net/minestom/server/feature/FeatureFlags.java @@ -0,0 +1,35 @@ +package net.minestom.server.feature; + +import net.minestom.server.utils.NamespaceID; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * AUTOGENERATED by FeatureFlagGenerator + */ +public enum FeatureFlags { + UPDATE_1_21(NamespaceID.from("minecraft:update_1_21")), + + BUNDLE(NamespaceID.from("minecraft:bundle")), + + VANILLA(NamespaceID.from("minecraft:vanilla")), + + TRADE_REBALANCE(NamespaceID.from("minecraft:trade_rebalance")); + + private static final FeatureFlags[] VALUES = FeatureFlags.values(); + + private final NamespaceID feature; + + FeatureFlags(@NotNull NamespaceID feature) { + this.feature = feature; + } + + public @NotNull NamespaceID feature() { + return this.feature; + } + + @Nullable + public static FeatureFlags getValue(int id) { + return VALUES[id]; + } +} diff --git a/src/autogenerated/java/net/minestom/server/fluid/Fluid.java b/src/autogenerated/java/net/minestom/server/fluid/Fluid.java deleted file mode 100644 index e00575f9bbc..00000000000 --- a/src/autogenerated/java/net/minestom/server/fluid/Fluid.java +++ /dev/null @@ -1,62 +0,0 @@ -package net.minestom.server.fluid; - -import net.kyori.adventure.key.Key; -import net.kyori.adventure.key.Keyed; -import net.minestom.server.registry.FluidRegistries; -import net.minestom.server.utils.NamespaceID; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * AUTOGENERATED by FluidGenerator - */ -public enum Fluid implements Keyed { - EMPTY(NamespaceID.from("minecraft:empty")), - - FLOWING_WATER(NamespaceID.from("minecraft:flowing_water")), - - WATER(NamespaceID.from("minecraft:water")), - - FLOWING_LAVA(NamespaceID.from("minecraft:flowing_lava")), - - LAVA(NamespaceID.from("minecraft:lava")); - - private static final Fluid[] VALUES = values(); - - @NotNull - private final NamespaceID id; - - Fluid(@NotNull NamespaceID id) { - this.id = id; - FluidRegistries.fluids.put(id, this); - } - - @Override - @NotNull - public Key key() { - return this.id; - } - - public short getId() { - return (short) ordinal(); - } - - @NotNull - public NamespaceID getNamespaceID() { - return this.id; - } - - @NotNull - @Override - public String toString() { - return "[" + this.id + "]"; - } - - @Nullable - public static Fluid fromId(short id) { - if(id >= 0 && id < VALUES.length) { - return VALUES[id]; - } - return null; - } -} diff --git a/src/autogenerated/java/net/minestom/server/fluid/Fluids.java b/src/autogenerated/java/net/minestom/server/fluid/Fluids.java new file mode 100644 index 00000000000..27157009e9e --- /dev/null +++ b/src/autogenerated/java/net/minestom/server/fluid/Fluids.java @@ -0,0 +1,17 @@ +package net.minestom.server.fluid; + +/** + * Code autogenerated, do not edit! + */ +@SuppressWarnings("unused") +interface Fluids { + Fluid EMPTY = FluidImpl.get("minecraft:empty"); + + Fluid FLOWING_WATER = FluidImpl.get("minecraft:flowing_water"); + + Fluid WATER = FluidImpl.get("minecraft:water"); + + Fluid FLOWING_LAVA = FluidImpl.get("minecraft:flowing_lava"); + + Fluid LAVA = FluidImpl.get("minecraft:lava"); +} diff --git a/src/autogenerated/java/net/minestom/server/game/GameEvents.java b/src/autogenerated/java/net/minestom/server/game/GameEvents.java new file mode 100644 index 00000000000..44e09b862d1 --- /dev/null +++ b/src/autogenerated/java/net/minestom/server/game/GameEvents.java @@ -0,0 +1,127 @@ +package net.minestom.server.game; + +/** + * Code autogenerated, do not edit! + */ +@SuppressWarnings("unused") +interface GameEvents { + GameEvent BLOCK_ACTIVATE = GameEventImpl.get("minecraft:block_activate"); + + GameEvent BLOCK_ATTACH = GameEventImpl.get("minecraft:block_attach"); + + GameEvent BLOCK_CHANGE = GameEventImpl.get("minecraft:block_change"); + + GameEvent BLOCK_CLOSE = GameEventImpl.get("minecraft:block_close"); + + GameEvent BLOCK_DEACTIVATE = GameEventImpl.get("minecraft:block_deactivate"); + + GameEvent BLOCK_DESTROY = GameEventImpl.get("minecraft:block_destroy"); + + GameEvent BLOCK_DETACH = GameEventImpl.get("minecraft:block_detach"); + + GameEvent BLOCK_OPEN = GameEventImpl.get("minecraft:block_open"); + + GameEvent BLOCK_PLACE = GameEventImpl.get("minecraft:block_place"); + + GameEvent CONTAINER_CLOSE = GameEventImpl.get("minecraft:container_close"); + + GameEvent CONTAINER_OPEN = GameEventImpl.get("minecraft:container_open"); + + GameEvent DRINK = GameEventImpl.get("minecraft:drink"); + + GameEvent EAT = GameEventImpl.get("minecraft:eat"); + + GameEvent ELYTRA_GLIDE = GameEventImpl.get("minecraft:elytra_glide"); + + GameEvent ENTITY_DAMAGE = GameEventImpl.get("minecraft:entity_damage"); + + GameEvent ENTITY_DIE = GameEventImpl.get("minecraft:entity_die"); + + GameEvent ENTITY_DISMOUNT = GameEventImpl.get("minecraft:entity_dismount"); + + GameEvent ENTITY_INTERACT = GameEventImpl.get("minecraft:entity_interact"); + + GameEvent ENTITY_MOUNT = GameEventImpl.get("minecraft:entity_mount"); + + GameEvent ENTITY_PLACE = GameEventImpl.get("minecraft:entity_place"); + + GameEvent ENTITY_ACTION = GameEventImpl.get("minecraft:entity_action"); + + GameEvent EQUIP = GameEventImpl.get("minecraft:equip"); + + GameEvent EXPLODE = GameEventImpl.get("minecraft:explode"); + + GameEvent FLAP = GameEventImpl.get("minecraft:flap"); + + GameEvent FLUID_PICKUP = GameEventImpl.get("minecraft:fluid_pickup"); + + GameEvent FLUID_PLACE = GameEventImpl.get("minecraft:fluid_place"); + + GameEvent HIT_GROUND = GameEventImpl.get("minecraft:hit_ground"); + + GameEvent INSTRUMENT_PLAY = GameEventImpl.get("minecraft:instrument_play"); + + GameEvent ITEM_INTERACT_FINISH = GameEventImpl.get("minecraft:item_interact_finish"); + + GameEvent ITEM_INTERACT_START = GameEventImpl.get("minecraft:item_interact_start"); + + GameEvent JUKEBOX_PLAY = GameEventImpl.get("minecraft:jukebox_play"); + + GameEvent JUKEBOX_STOP_PLAY = GameEventImpl.get("minecraft:jukebox_stop_play"); + + GameEvent LIGHTNING_STRIKE = GameEventImpl.get("minecraft:lightning_strike"); + + GameEvent NOTE_BLOCK_PLAY = GameEventImpl.get("minecraft:note_block_play"); + + GameEvent PRIME_FUSE = GameEventImpl.get("minecraft:prime_fuse"); + + GameEvent PROJECTILE_LAND = GameEventImpl.get("minecraft:projectile_land"); + + GameEvent PROJECTILE_SHOOT = GameEventImpl.get("minecraft:projectile_shoot"); + + GameEvent SCULK_SENSOR_TENDRILS_CLICKING = GameEventImpl.get("minecraft:sculk_sensor_tendrils_clicking"); + + GameEvent SHEAR = GameEventImpl.get("minecraft:shear"); + + GameEvent SHRIEK = GameEventImpl.get("minecraft:shriek"); + + GameEvent SPLASH = GameEventImpl.get("minecraft:splash"); + + GameEvent STEP = GameEventImpl.get("minecraft:step"); + + GameEvent SWIM = GameEventImpl.get("minecraft:swim"); + + GameEvent TELEPORT = GameEventImpl.get("minecraft:teleport"); + + GameEvent UNEQUIP = GameEventImpl.get("minecraft:unequip"); + + GameEvent RESONATE_1 = GameEventImpl.get("minecraft:resonate_1"); + + GameEvent RESONATE_2 = GameEventImpl.get("minecraft:resonate_2"); + + GameEvent RESONATE_3 = GameEventImpl.get("minecraft:resonate_3"); + + GameEvent RESONATE_4 = GameEventImpl.get("minecraft:resonate_4"); + + GameEvent RESONATE_5 = GameEventImpl.get("minecraft:resonate_5"); + + GameEvent RESONATE_6 = GameEventImpl.get("minecraft:resonate_6"); + + GameEvent RESONATE_7 = GameEventImpl.get("minecraft:resonate_7"); + + GameEvent RESONATE_8 = GameEventImpl.get("minecraft:resonate_8"); + + GameEvent RESONATE_9 = GameEventImpl.get("minecraft:resonate_9"); + + GameEvent RESONATE_10 = GameEventImpl.get("minecraft:resonate_10"); + + GameEvent RESONATE_11 = GameEventImpl.get("minecraft:resonate_11"); + + GameEvent RESONATE_12 = GameEventImpl.get("minecraft:resonate_12"); + + GameEvent RESONATE_13 = GameEventImpl.get("minecraft:resonate_13"); + + GameEvent RESONATE_14 = GameEventImpl.get("minecraft:resonate_14"); + + GameEvent RESONATE_15 = GameEventImpl.get("minecraft:resonate_15"); +} diff --git a/src/autogenerated/java/net/minestom/server/item/banner/BannerPatterns.java b/src/autogenerated/java/net/minestom/server/item/banner/BannerPatterns.java new file mode 100644 index 00000000000..b53f30b6e26 --- /dev/null +++ b/src/autogenerated/java/net/minestom/server/item/banner/BannerPatterns.java @@ -0,0 +1,89 @@ +package net.minestom.server.item.banner; + +/** + * Code autogenerated, do not edit! + */ +@SuppressWarnings("unused") +interface BannerPatterns { + BannerPattern BASE = BannerPatternImpl.get("minecraft:base"); + + BannerPattern SQUARE_BOTTOM_LEFT = BannerPatternImpl.get("minecraft:square_bottom_left"); + + BannerPattern SQUARE_BOTTOM_RIGHT = BannerPatternImpl.get("minecraft:square_bottom_right"); + + BannerPattern SQUARE_TOP_LEFT = BannerPatternImpl.get("minecraft:square_top_left"); + + BannerPattern SQUARE_TOP_RIGHT = BannerPatternImpl.get("minecraft:square_top_right"); + + BannerPattern STRIPE_BOTTOM = BannerPatternImpl.get("minecraft:stripe_bottom"); + + BannerPattern STRIPE_TOP = BannerPatternImpl.get("minecraft:stripe_top"); + + BannerPattern STRIPE_LEFT = BannerPatternImpl.get("minecraft:stripe_left"); + + BannerPattern STRIPE_RIGHT = BannerPatternImpl.get("minecraft:stripe_right"); + + BannerPattern STRIPE_CENTER = BannerPatternImpl.get("minecraft:stripe_center"); + + BannerPattern STRIPE_MIDDLE = BannerPatternImpl.get("minecraft:stripe_middle"); + + BannerPattern STRIPE_DOWNRIGHT = BannerPatternImpl.get("minecraft:stripe_downright"); + + BannerPattern STRIPE_DOWNLEFT = BannerPatternImpl.get("minecraft:stripe_downleft"); + + BannerPattern SMALL_STRIPES = BannerPatternImpl.get("minecraft:small_stripes"); + + BannerPattern CROSS = BannerPatternImpl.get("minecraft:cross"); + + BannerPattern STRAIGHT_CROSS = BannerPatternImpl.get("minecraft:straight_cross"); + + BannerPattern TRIANGLE_BOTTOM = BannerPatternImpl.get("minecraft:triangle_bottom"); + + BannerPattern TRIANGLE_TOP = BannerPatternImpl.get("minecraft:triangle_top"); + + BannerPattern TRIANGLES_BOTTOM = BannerPatternImpl.get("minecraft:triangles_bottom"); + + BannerPattern TRIANGLES_TOP = BannerPatternImpl.get("minecraft:triangles_top"); + + BannerPattern DIAGONAL_LEFT = BannerPatternImpl.get("minecraft:diagonal_left"); + + BannerPattern DIAGONAL_UP_RIGHT = BannerPatternImpl.get("minecraft:diagonal_up_right"); + + BannerPattern DIAGONAL_UP_LEFT = BannerPatternImpl.get("minecraft:diagonal_up_left"); + + BannerPattern DIAGONAL_RIGHT = BannerPatternImpl.get("minecraft:diagonal_right"); + + BannerPattern CIRCLE = BannerPatternImpl.get("minecraft:circle"); + + BannerPattern RHOMBUS = BannerPatternImpl.get("minecraft:rhombus"); + + BannerPattern HALF_VERTICAL = BannerPatternImpl.get("minecraft:half_vertical"); + + BannerPattern HALF_HORIZONTAL = BannerPatternImpl.get("minecraft:half_horizontal"); + + BannerPattern HALF_VERTICAL_RIGHT = BannerPatternImpl.get("minecraft:half_vertical_right"); + + BannerPattern HALF_HORIZONTAL_BOTTOM = BannerPatternImpl.get("minecraft:half_horizontal_bottom"); + + BannerPattern BORDER = BannerPatternImpl.get("minecraft:border"); + + BannerPattern CURLY_BORDER = BannerPatternImpl.get("minecraft:curly_border"); + + BannerPattern GRADIENT = BannerPatternImpl.get("minecraft:gradient"); + + BannerPattern GRADIENT_UP = BannerPatternImpl.get("minecraft:gradient_up"); + + BannerPattern BRICKS = BannerPatternImpl.get("minecraft:bricks"); + + BannerPattern GLOBE = BannerPatternImpl.get("minecraft:globe"); + + BannerPattern CREEPER = BannerPatternImpl.get("minecraft:creeper"); + + BannerPattern SKULL = BannerPatternImpl.get("minecraft:skull"); + + BannerPattern FLOWER = BannerPatternImpl.get("minecraft:flower"); + + BannerPattern MOJANG = BannerPatternImpl.get("minecraft:mojang"); + + BannerPattern PIGLIN = BannerPatternImpl.get("minecraft:piglin"); +} diff --git a/src/autogenerated/java/net/minestom/server/registry/FluidRegistries.java b/src/autogenerated/java/net/minestom/server/registry/FluidRegistries.java deleted file mode 100644 index f6e23118b11..00000000000 --- a/src/autogenerated/java/net/minestom/server/registry/FluidRegistries.java +++ /dev/null @@ -1,45 +0,0 @@ -// AUTOGENERATED by net.minestom.codegen.RegistriesGenerator -package net.minestom.server.registry; - -import net.kyori.adventure.key.Key; -import net.minestom.server.fluid.Fluid; -import net.minestom.server.utils.NamespaceID; -import org.jetbrains.annotations.NotNull; - -import java.util.HashMap; - -/** - * AUTOGENERATED - */ -public final class FluidRegistries { - - /** - * Should only be used for internal code, please use the get* methods. - */ - @Deprecated - public static final HashMap fluids = new HashMap<>(); - - /** - * Returns the corresponding Fluid matching the given id. Returns 'EMPTY' if none match. - */ - @NotNull - public static Fluid getFluid(String id) { - return getFluid(NamespaceID.from(id)); - } - - /** - * Returns the corresponding Fluid matching the given id. Returns 'EMPTY' if none match. - */ - @NotNull - public static Fluid getFluid(NamespaceID id) { - return fluids.getOrDefault(id, Fluid.EMPTY); - } - - /** - * Returns the corresponding Fluid matching the given key. Returns 'EMPTY' if none match. - */ - @NotNull - public static Fluid getFluid(Key key) { - return getFluid(NamespaceID.from(key)); - } -} diff --git a/src/main/java/net/minestom/server/Metrics.java b/src/main/java/net/minestom/server/Metrics.java new file mode 100644 index 00000000000..56cb113053d --- /dev/null +++ b/src/main/java/net/minestom/server/Metrics.java @@ -0,0 +1,146 @@ +package net.minestom.server; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import net.minestom.server.extras.MojangAuth; +import net.minestom.server.extras.bungee.BungeeCordProxy; +import net.minestom.server.extras.velocity.VelocityProxy; +import org.bstats.MetricsBase; +import org.bstats.charts.DrilldownPie; +import org.bstats.charts.SimplePie; +import org.bstats.charts.SingleLineChart; +import org.bstats.json.JsonObjectBuilder; + +public class Metrics { + private static String bStatsUuid = System.getProperty("minestom.bstats.id"); + private final static int SERVICE_ID = 20684; + private MetricsBase metrics; + + public void start() { + MinecraftServer.LOGGER.info("Enable bstats."); + String serverUUID = bStatsUuid; + if (serverUUID == null) { + Path bStatsFile = Path.of(".bstats"); + if (Files.notExists(bStatsFile)) { + try { + Files.createFile(bStatsFile); + } catch (IOException e) { + MinecraftServer.LOGGER.error("BStats file cannot created."); + return; + } + try { + Files.writeString(bStatsFile, UUID.randomUUID().toString()); + } catch (IOException e) { + MinecraftServer.LOGGER.error("BStats file cannot be written."); + return; + } + } + try { + serverUUID = Files.readString(bStatsFile); + } catch (IOException e) { + MinecraftServer.LOGGER.error("BStats file cannot be readed."); + return; + } + } + System.setProperty("bstats.relocatecheck", "false"); + metrics = new MetricsBase("server-implementation", serverUUID, SERVICE_ID,true, this::getServerData, jsonObjectBuilder -> {}, null, () -> true, MinecraftServer.LOGGER::error,MinecraftServer.LOGGER::info, + ServerFlag.INSIDE_TEST, ServerFlag.INSIDE_TEST,ServerFlag.INSIDE_TEST); + + metrics.addCustomChart(new SimplePie("minecraft_version", () -> { + String minecraftVersion = MinecraftServer.VERSION_NAME; + minecraftVersion = minecraftVersion.substring(minecraftVersion.indexOf("MC: ") + 4, minecraftVersion.length() - 1); + return minecraftVersion; + })); + + metrics.addCustomChart(new SingleLineChart("players", () -> MinecraftServer.getConnectionManager().getOnlinePlayers().size())); + metrics.addCustomChart(new SimplePie("online_mode", () -> { + if (MojangAuth.isEnabled()) { + return "online"; + } else if (VelocityProxy.isEnabled() || BungeeCordProxy.isEnabled()) { + return "proxied"; + } else { + return "offline"; + } + })); + final String version = "%s-%s-@%s".formatted(MinecraftServer.VERSION_NAME,Git.branch(), Git.commit()); + metrics.addCustomChart(new SimplePie("minestom_version", () -> version)); + metrics.addCustomChart(new DrilldownPie("java_version", () -> { + Map> map = new HashMap<>(); + String javaVersion = System.getProperty("java.version"); + Map entry = new HashMap<>(); + entry.put(javaVersion, 1); + + // http://openjdk.java.net/jeps/223 + // Java decided to change their versioning scheme and in doing so modified the java.version system + // property to return $major[.$minor][.$secuity][-ea], as opposed to 1.$major.0_$identifier + // we can handle pre-9 by checking if the "major" is equal to "1", otherwise, 9+ + String majorVersion = javaVersion.split("\\.")[0]; + String release; + + int indexOf = javaVersion.lastIndexOf('.'); + + if (majorVersion.equals("1")) { + release = "Java " + javaVersion.substring(0, indexOf); + } else { + // of course, it really wouldn't be all that simple if they didn't add a quirk, now would it + // valid strings for the major may potentially include values such as -ea to deannotate a pre release + Matcher versionMatcher = Pattern.compile("\\d+").matcher(majorVersion); + if (versionMatcher.find()) { + majorVersion = versionMatcher.group(0); + } + release = "Java " + majorVersion; + } + map.put(release, entry); + + return map; + })); + + metrics.addCustomChart(new DrilldownPie("extensions", () -> { + Map> map = new HashMap<>(); + + // count legacy plugins + int extensions = MinecraftServer.getExtensionManager().getExtensions().size(); + + // insert real value as lower dimension + Map entry = new HashMap<>(); + entry.put(String.valueOf(extensions), 1); + + // create buckets as higher dimension + if (extensions == 0) { + map.put("0 \uD83D\uDE0E", entry); // :sunglasses: + } else if (extensions <= 5) { + map.put("1-5", entry); + } else if (extensions <= 10) { + map.put("6-10", entry); + } else if (extensions <= 25) { + map.put("11-25", entry); + } else if (extensions <= 50) { + map.put("26-50", entry); + } else { + map.put("50+ \uD83D\uDE2D", entry); // :cry: + } + + return map; + })); + } + + public void shutdown() { + if (this.metrics != null) { + this.metrics.shutdown(); + } + } + + private void getServerData(JsonObjectBuilder builder) { + builder.appendField("osName", System.getProperty("os.name")); + builder.appendField("osArch", System.getProperty("os.arch")); + builder.appendField("osVersion", System.getProperty("os.version")); + builder.appendField("coreCount", Runtime.getRuntime().availableProcessors()); + } + +} diff --git a/src/main/java/net/minestom/server/MinecraftServer.java b/src/main/java/net/minestom/server/MinecraftServer.java index 065ca08324c..65ac14695b0 100644 --- a/src/main/java/net/minestom/server/MinecraftServer.java +++ b/src/main/java/net/minestom/server/MinecraftServer.java @@ -9,6 +9,7 @@ import net.minestom.server.entity.metadata.other.PaintingMeta; import net.minestom.server.event.GlobalEventHandler; import net.minestom.server.exception.ExceptionManager; +import net.minestom.server.extensions.ExtensionManager; import net.minestom.server.gamedata.tags.TagManager; import net.minestom.server.instance.InstanceManager; import net.minestom.server.instance.block.BlockManager; @@ -30,6 +31,7 @@ import net.minestom.server.scoreboard.TeamManager; import net.minestom.server.thread.TickSchedulerThread; import net.minestom.server.timer.SchedulerManager; +import net.minestom.server.utils.MathUtils; import net.minestom.server.utils.PacketUtils; import net.minestom.server.utils.nbt.BinaryTagSerializer; import net.minestom.server.utils.validate.Check; @@ -38,6 +40,7 @@ import net.minestom.server.world.biome.Biome; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnknownNullability; import java.io.IOException; @@ -250,6 +253,10 @@ public static AdvancementManager getAdvancementManager() { return serverProcess.advancement(); } + public static @Nullable ExtensionManager getExtensionManager() { + return serverProcess.extension(); + } + public static TagManager getTagManager() { return serverProcess.tag(); } diff --git a/src/main/java/net/minestom/server/ServerFlag.java b/src/main/java/net/minestom/server/ServerFlag.java index c1a3e9dc0e8..4f5bd6cf47a 100644 --- a/src/main/java/net/minestom/server/ServerFlag.java +++ b/src/main/java/net/minestom/server/ServerFlag.java @@ -27,6 +27,8 @@ public final class ServerFlag { public static final int POOLED_BUFFER_SIZE = intProperty("minestom.pooled-buffer-size", 262_143); public static final int SEND_LIGHT_AFTER_BLOCK_PLACEMENT_DELAY = intProperty("minestom.send-light-after-block-placement-delay", 100); public static final long LOGIN_PLUGIN_MESSAGE_TIMEOUT = longProperty("minestom.login-plugin-message-timeout", 5_000); + public static final int EXPLOSION_SEND_DISTANCE = intProperty("minestom.explosion-send-distance", 100); + public static final int SERVER_LINK_AMOUNT = intProperty("minestom.server-link-amount", 100); // Network rate limiting public static final int PLAYER_PACKET_PER_TICK = intProperty("minestom.packet-per-tick", 50); @@ -54,6 +56,18 @@ public final class ServerFlag { // World public static final int WORLD_BORDER_SIZE = intProperty("minestom.world-border-size", 29999984); + // Terminal + public static final boolean TERMINAL_ENABLED = System.getProperty("minestom.terminal.disabled") == null; + public static final boolean TERMINAL_SUPPORT_HEX_COLOR = Boolean.getBoolean("minestom.terminal.support-hex-color"); + public static final boolean TERMINAL_SUPPORT_COLOR = Boolean.getBoolean("minestom.terminal.support-color"); + // Extensions todo use enabled flag + public static final boolean EXTENSIONS_ENABLED = Boolean.getBoolean("minestom.extension.enabled"); + public static final @NotNull String EXTENSIONS_FOLDER = System.getProperty("minestom.extension.folder", "extensions"); + public static final @Nullable String EXTENSIONS_DEV_CLASSES = System.getProperty("minestom.extension.indevfolder.classes"); + public static final @Nullable String EXTENSIONS_DEV_RESOURCES = System.getProperty("minestom.extension.indevfolder.resources"); + + // Attributes + public static final boolean ATTRIBUTES_ENABLED = System.getProperty("minestom.attributes.disabled") == null; // Maps public static final @NotNull String MAP_RGB_MAPPING = stringProperty("minestom.map.rgbmapping", "lazy"); public static final @Nullable String MAP_RGB_REDUCTION = stringProperty("minestom.map.rgbreduction"); // Only used if rgb mapping is "approximate" diff --git a/src/main/java/net/minestom/server/ServerProcess.java b/src/main/java/net/minestom/server/ServerProcess.java index 9b058bab25c..c700f316410 100644 --- a/src/main/java/net/minestom/server/ServerProcess.java +++ b/src/main/java/net/minestom/server/ServerProcess.java @@ -5,6 +5,7 @@ import net.minestom.server.command.CommandManager; import net.minestom.server.event.GlobalEventHandler; import net.minestom.server.exception.ExceptionManager; +import net.minestom.server.extensions.ExtensionManager; import net.minestom.server.gamedata.tags.TagManager; import net.minestom.server.instance.Chunk; import net.minestom.server.instance.InstanceManager; @@ -23,6 +24,7 @@ import net.minestom.server.timer.SchedulerManager; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.net.SocketAddress; @@ -83,6 +85,11 @@ public interface ServerProcess extends Registries, Snapshotable { */ @NotNull BossBarManager bossBar(); + /** + * Loads and handle extensions. + */ + @Nullable ExtensionManager extension(); + /** * Handles registry tags. */ diff --git a/src/main/java/net/minestom/server/ServerProcessImpl.java b/src/main/java/net/minestom/server/ServerProcessImpl.java index 3d6aa9263ff..9040c041827 100644 --- a/src/main/java/net/minestom/server/ServerProcessImpl.java +++ b/src/main/java/net/minestom/server/ServerProcessImpl.java @@ -1,6 +1,12 @@ package net.minestom.server; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import java.io.IOException; +import java.net.SocketAddress; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import net.minestom.server.advancements.AdvancementManager; import net.minestom.server.adventure.bossbar.BossBarManager; import net.minestom.server.command.CommandManager; @@ -12,6 +18,7 @@ import net.minestom.server.event.GlobalEventHandler; import net.minestom.server.event.server.ServerTickMonitorEvent; import net.minestom.server.exception.ExceptionManager; +import net.minestom.server.extensions.ExtensionManager; import net.minestom.server.gamedata.tags.TagManager; import net.minestom.server.instance.Chunk; import net.minestom.server.instance.Instance; @@ -33,6 +40,7 @@ import net.minestom.server.registry.DynamicRegistry; import net.minestom.server.scoreboard.TeamManager; import net.minestom.server.snapshot.*; +import net.minestom.server.terminal.MinestomTerminal; import net.minestom.server.thread.Acquirable; import net.minestom.server.thread.ThreadDispatcher; import net.minestom.server.thread.ThreadProvider; @@ -46,13 +54,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.net.SocketAddress; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; - final class ServerProcessImpl implements ServerProcess { private static final Logger LOGGER = LoggerFactory.getLogger(ServerProcessImpl.class); @@ -75,6 +76,7 @@ final class ServerProcessImpl implements ServerProcess { private final DynamicRegistry paintingVariant; private final DynamicRegistry jukeboxSong; + private final ExtensionManager extension; private final ConnectionManager connection; private final PacketListenerManager packetListener; private final PacketProcessor packetProcessor; @@ -91,6 +93,7 @@ final class ServerProcessImpl implements ServerProcess { private final TagManager tag; private final Server server; + private final Metrics metrics; private final ThreadDispatcher dispatcher; private final Ticker ticker; @@ -98,11 +101,13 @@ final class ServerProcessImpl implements ServerProcess { private final AtomicBoolean started = new AtomicBoolean(); private final AtomicBoolean stopped = new AtomicBoolean(); + private static boolean bstatsEnabled = System.getProperty("minestom.bstats.enabled") == null; + + public ServerProcessImpl() throws IOException { this.exception = new ExceptionManager(); - + this.extension = new ExtensionManager(this); // The order of initialization here is relevant, we must load the enchantment util registries before the vanilla data is loaded. - this.enchantmentLevelBasedValues = LevelBasedValue.createDefaultRegistry(); this.enchantmentValueEffects = ValueEffect.createDefaultRegistry(); this.enchantmentEntityEffects = EntityEffect.createDefaultRegistry(); @@ -139,6 +144,7 @@ public ServerProcessImpl() throws IOException { this.dispatcher = ThreadDispatcher.of(ThreadProvider.counter(), ServerFlag.DISPATCHER_THREADS); this.ticker = new TickerImpl(); + this.metrics = new Metrics(); } @Override @@ -261,6 +267,11 @@ public ServerProcessImpl() throws IOException { return bossBar; } + @Override + public @NotNull ExtensionManager extension() { + return extension; + } + @Override public @NotNull TagManager tag() { return tag; @@ -312,8 +323,13 @@ public void start(@NotNull SocketAddress socketAddress) { throw new IllegalStateException("Server already started"); } + extension.start(); + extension.gotoPreInit(); + LOGGER.info("Starting " + MinecraftServer.getBrandName() + " server."); + extension.gotoInit(); + // Init server try { server.init(socketAddress); @@ -325,8 +341,17 @@ public void start(@NotNull SocketAddress socketAddress) { // Start server server.start(); + extension.gotoPostInit(); + LOGGER.info(MinecraftServer.getBrandName() + " server started successfully."); + if (ServerFlag.TERMINAL_ENABLED) { + MinestomTerminal.start(); + } + if (bstatsEnabled) { + this.metrics.start(); + } + // Stop the server on SIGINT if (ServerFlag.SHUTDOWN_ON_SIGNAL) Runtime.getRuntime().addShutdownHook(new Thread(this::stop)); } @@ -336,12 +361,16 @@ public void stop() { if (!stopped.compareAndSet(false, true)) return; LOGGER.info("Stopping " + MinecraftServer.getBrandName() + " server."); + LOGGER.info("Unloading all extensions."); + extension.shutdown(); scheduler.shutdown(); connection.shutdown(); server.stop(); LOGGER.info("Shutting down all thread pools."); benchmark.disable(); + MinestomTerminal.stop(); dispatcher.shutdown(); + this.metrics.shutdown(); LOGGER.info(MinecraftServer.getBrandName() + " server stopped successfully."); } diff --git a/src/main/java/net/minestom/server/advancements/AdvancementTab.java b/src/main/java/net/minestom/server/advancements/AdvancementTab.java index 8228a5ddd1e..0f39baf1431 100644 --- a/src/main/java/net/minestom/server/advancements/AdvancementTab.java +++ b/src/main/java/net/minestom/server/advancements/AdvancementTab.java @@ -155,10 +155,8 @@ private void addPlayer(@NotNull Player player) { */ private void removePlayer(@NotNull Player player) { final UUID uuid = player.getUuid(); - if (!PLAYER_TAB_MAP.containsKey(uuid)) { - return; - } Set tabs = PLAYER_TAB_MAP.get(uuid); + if (tabs == null) return; tabs.remove(this); if (tabs.isEmpty()) { PLAYER_TAB_MAP.remove(uuid); diff --git a/src/main/java/net/minestom/server/advancements/notifications/Notification.java b/src/main/java/net/minestom/server/advancements/notifications/Notification.java deleted file mode 100644 index 90660466e83..00000000000 --- a/src/main/java/net/minestom/server/advancements/notifications/Notification.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.minestom.server.advancements.notifications; - -import net.kyori.adventure.text.Component; -import net.minestom.server.advancements.FrameType; -import net.minestom.server.item.ItemStack; -import net.minestom.server.item.Material; -import org.jetbrains.annotations.NotNull; - -/** - * Represents a message which can be sent using the {@link NotificationCenter}. - */ -public record Notification(@NotNull Component title, @NotNull FrameType frameType, @NotNull ItemStack icon) { - public Notification(@NotNull Component title, @NotNull FrameType frameType, @NotNull Material icon) { - this(title, frameType, ItemStack.of(icon)); - } - - @Deprecated - public @NotNull Component getTitle() { - return title; - } - - @Deprecated - public @NotNull FrameType getFrameType() { - return frameType; - } -} diff --git a/src/main/java/net/minestom/server/advancements/notifications/NotificationCenter.java b/src/main/java/net/minestom/server/advancements/notifications/NotificationCenter.java deleted file mode 100644 index 5c5326b3c35..00000000000 --- a/src/main/java/net/minestom/server/advancements/notifications/NotificationCenter.java +++ /dev/null @@ -1,77 +0,0 @@ -package net.minestom.server.advancements.notifications; - -import net.kyori.adventure.text.Component; -import net.minestom.server.entity.Player; -import net.minestom.server.network.packet.server.play.AdvancementsPacket; -import org.jetbrains.annotations.NotNull; - -import java.util.Collection; -import java.util.List; - -/** - * Used to send one or multiples {@link Notification}. - *

- * Works by sending a completed advancement and remove it immediately. - *

- * You can simply create a {@link Notification} object and call {@link #send(Notification, Player)}. - */ -public final class NotificationCenter { - private static final String IDENTIFIER = "minestom:notification"; - private static final AdvancementsPacket REMOVE_PACKET = new AdvancementsPacket(false, List.of(), List.of(IDENTIFIER), List.of()); - - /** - * Can't create an instance, use the static methods instead. - */ - private NotificationCenter() { - } - - /** - * Send a {@link Notification} to one player. - * - * @param notification the {@link Notification} to send - * @param player the player to send the notification to - */ - public static void send(@NotNull Notification notification, @NotNull Player player) { - player.sendPacket(createPacket(notification)); - player.sendPacket(REMOVE_PACKET); - } - - /** - * Send a {@link Notification} to a collection of players. - * - * @param notification the {@link Notification} to send - * @param players the collection of players to send the notification to - */ - public static void send(@NotNull Notification notification, @NotNull Collection players) { - // Can't use PacketWriterUtils because we need the packets to come in the correct order - players.forEach(player -> send(notification, player)); - } - - /** - * Create the {@link AdvancementsPacket} responsible for showing the Toast to players - * - * @param notification the notification - * @return the packet used to show the Toast - */ - private static AdvancementsPacket createPacket(Notification notification) { - // For An advancement to be shown, it must have all of its criteria achieved (progress 100%) - // Create a Criteria that we can set to 100% achieved. - final var displayData = new AdvancementsPacket.DisplayData( - notification.title(), Component.text("Articdive was here. #Minestom"), - notification.icon(), notification.frameType(), - 0x6, null, 0f, 0f); - - final var criteria = new AdvancementsPacket.Criteria("minestom:some_criteria", - new AdvancementsPacket.CriterionProgress(System.currentTimeMillis())); - - final var advancement = new AdvancementsPacket.Advancement(null, displayData, - List.of(new AdvancementsPacket.Requirement(List.of(criteria.criterionIdentifier()))), - false); - - final var mapping = new AdvancementsPacket.AdvancementMapping(IDENTIFIER, advancement); - final var progressMapping = new AdvancementsPacket.ProgressMapping(IDENTIFIER, - new AdvancementsPacket.AdvancementProgress(List.of(criteria))); - - return new AdvancementsPacket(false, List.of(mapping), List.of(), List.of(progressMapping)); - } -} diff --git a/src/main/java/net/minestom/server/adventure/AdventurePacketConvertor.java b/src/main/java/net/minestom/server/adventure/AdventurePacketConvertor.java index 893ae6ce241..4acc71e5ade 100644 --- a/src/main/java/net/minestom/server/adventure/AdventurePacketConvertor.java +++ b/src/main/java/net/minestom/server/adventure/AdventurePacketConvertor.java @@ -46,6 +46,8 @@ public class AdventurePacketConvertor { NAMED_TEXT_COLOR_ID_MAP.put(NamedTextColor.WHITE, 15); } + private AdventurePacketConvertor() { } //Microtus - update java keyword usage + /** * Gets the int value of a boss bar overlay. * @@ -141,19 +143,6 @@ public static int getNamedTextColorValue(@NotNull NamedTextColor color) { return new EntitySoundEffectPacket(minestomSound, sound.source(), entity.getEntityId(), sound.volume(), sound.pitch(), seed); } - /** - * Creates an entity sound packet from an Adventure sound. - * - * @param sound the sound - * @param entity the entity the sound is coming from - * @return the packet - * @deprecated Use {@link #createSoundPacket(Sound, Sound.Emitter)} - */ - @Deprecated(forRemoval = true) - public static ServerPacket createEntitySoundPacket(@NotNull Sound sound, @NotNull Entity entity) { - return createSoundPacket(sound, entity); - } - /** * Creates a sound stop packet from a sound stop. * diff --git a/src/main/java/net/minestom/server/collision/ShapeImpl.java b/src/main/java/net/minestom/server/collision/ShapeImpl.java index 82b1ea497b6..f6c097c40ce 100644 --- a/src/main/java/net/minestom/server/collision/ShapeImpl.java +++ b/src/main/java/net/minestom/server/collision/ShapeImpl.java @@ -208,7 +208,7 @@ private static CollisionData collisionData(List collisionBoundingBo } byte fullCollisionFaces = 0; - for (BlockFace f : BlockFace.values()) { + for (BlockFace f : BlockFace.getValues()) { final byte res = isFaceCovered(computeOcclusionSet(f, collisionBoundingBoxes)); fullCollisionFaces |= ((res == 2) ? 0b1 : 0b0) << (byte) f.ordinal(); } @@ -219,7 +219,7 @@ private static CollisionData collisionData(List collisionBoundingBo private static LightData lightData(List occlusionBoundingBoxes, int lightEmission) { byte fullFaces = 0; byte airFaces = 0; - for (BlockFace f : BlockFace.values()) { + for (BlockFace f : BlockFace.getValues()) { final byte res = isFaceCovered(computeOcclusionSet(f, occlusionBoundingBoxes)); fullFaces |= ((res == 2) ? 0b1 : 0b0) << (byte) f.ordinal(); airFaces |= ((res == 0) ? 0b1 : 0b0) << (byte) f.ordinal(); diff --git a/src/main/java/net/minestom/server/command/CommandManager.java b/src/main/java/net/minestom/server/command/CommandManager.java index cdb5fd232d7..bcb140f5a35 100644 --- a/src/main/java/net/minestom/server/command/CommandManager.java +++ b/src/main/java/net/minestom/server/command/CommandManager.java @@ -60,18 +60,6 @@ public synchronized void register(@NotNull Command command) { invalidateGraphCache(); } - /** - * Register multiple {@link Command}s. - * - * @param commands the array of commands - * @throws IllegalStateException if a command with the same name already exists - */ - public synchronized void register(@NotNull Command... commands) { - for (Command command : commands) { - register(command); - } - } - /** * Removes a command from the currently registered commands. * Does nothing if the command was not registered before diff --git a/src/main/java/net/minestom/server/command/CommandSender.java b/src/main/java/net/minestom/server/command/CommandSender.java index 20a22bac01f..a0c10efbbc2 100644 --- a/src/main/java/net/minestom/server/command/CommandSender.java +++ b/src/main/java/net/minestom/server/command/CommandSender.java @@ -34,52 +34,4 @@ default void sendMessage(@NotNull String @NotNull [] messages) { sendMessage(message); } } - - /** - * Gets if the sender is a {@link Player}. - *

- * Consider using {@code instanceof} instead. - * - * @return true if 'this' is a player, false otherwise - */ - @Deprecated - default boolean isPlayer() { - return false; - } - - /** - * Gets if the sender is a {@link ConsoleSender}. - *

- * Consider using {@code instanceof} instead. - * - * @return true if 'this' is the console, false otherwise - */ - @Deprecated - default boolean isConsole() { - return false; - } - - /** - * Casts this object to a {@link Player}. - * No checks are performed, {@link ClassCastException} can very much happen. - * - * @throws ClassCastException if 'this' is not a player - * @see #isPlayer() - */ - @Deprecated - default Player asPlayer() { - throw new ClassCastException("CommandSender is not a Player"); - } - - /** - * Casts this object to a {@link ConsoleSender}. - * No checks are performed, {@link ClassCastException} can very much happen. - * - * @throws ClassCastException if 'this' is not a console sender - * @see #isConsole() - */ - @Deprecated - default ConsoleSender asConsole() { - throw new ClassCastException("CommandSender is not the ConsoleSender"); - } } diff --git a/src/main/java/net/minestom/server/command/ConsoleSender.java b/src/main/java/net/minestom/server/command/ConsoleSender.java index d97bc82ae1c..c8f7392ec3f 100644 --- a/src/main/java/net/minestom/server/command/ConsoleSender.java +++ b/src/main/java/net/minestom/server/command/ConsoleSender.java @@ -45,16 +45,6 @@ public Set getAllPermissions() { return permissions; } - @Override - public boolean isConsole() { - return true; - } - - @Override - public ConsoleSender asConsole() { - return this; - } - @Override public @NotNull TagHandler tagHandler() { return tagHandler; diff --git a/src/main/java/net/minestom/server/command/builder/arguments/Argument.java b/src/main/java/net/minestom/server/command/builder/arguments/Argument.java index 497924a2e4a..f6d705585aa 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/Argument.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/Argument.java @@ -30,8 +30,11 @@ */ public abstract class Argument { @ApiStatus.Internal - public static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.COMMAND_ARGUMENTS, - (namespace, properties) -> new ArgumentImpl(NamespaceID.from(namespace), properties.getInt("id"))); + public static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.COMMAND_ARGUMENTS, Argument::createImpl); + + private static ArgumentImpl createImpl(String namespace, Registry.Properties properties) { + return new ArgumentImpl(NamespaceID.from(namespace), properties.getInt("id")); + } record ArgumentImpl(NamespaceID namespace, int id) implements StaticProtocolObject { @Override diff --git a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentEnum.java b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentEnum.java index da100c8c5b8..b849ef7bee5 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentEnum.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentEnum.java @@ -12,7 +12,7 @@ @SuppressWarnings("rawtypes") public class ArgumentEnum extends Argument { - public final static int NOT_ENUM_VALUE_ERROR = 1; + public static final int NOT_ENUM_VALUE_ERROR = 1; //Microtus - update java keyword usage private final Class enumClass; private final E[] values; diff --git a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentRange.java b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentRange.java index 5f53f6e8146..5316768207c 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentRange.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/ArgumentRange.java @@ -23,7 +23,7 @@ public abstract class ArgumentRange, N extends Number> extend private final Function parser; private final BiFunction rangeConstructor; - public ArgumentRange(@NotNull String id, N min, N max, Function parser, BiFunction rangeConstructor) { + ArgumentRange(@NotNull String id, N min, N max, Function parser, BiFunction rangeConstructor) { super(id); this.min = min; this.max = max; diff --git a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/registry/ArgumentRegistry.java b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/registry/ArgumentRegistry.java index 00dd4a9af15..3b39ee67505 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/minecraft/registry/ArgumentRegistry.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/minecraft/registry/ArgumentRegistry.java @@ -9,9 +9,9 @@ public abstract class ArgumentRegistry extends Argument { public static final int INVALID_NAME = -2; - public ArgumentRegistry(String id) { + ArgumentRegistry(String id) { super(id); - } + } //Microtus - update java keyword usage public abstract T getRegistry(@NotNull String value); diff --git a/src/main/java/net/minestom/server/command/builder/arguments/relative/ArgumentRelativeVec.java b/src/main/java/net/minestom/server/command/builder/arguments/relative/ArgumentRelativeVec.java index 08374caa1ba..2e76a2bafd8 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/relative/ArgumentRelativeVec.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/relative/ArgumentRelativeVec.java @@ -28,7 +28,7 @@ abstract class ArgumentRelativeVec extends Argument { private final int numberCount; - public ArgumentRelativeVec(@NotNull String id, int numberCount) { + ArgumentRelativeVec(@NotNull String id, int numberCount) { //Microtus - update java keyword usage super(id, true); this.numberCount = numberCount; } diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index 0fc87f342b6..0b9744a216a 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -293,12 +293,7 @@ public void editEntityMeta(Class metaClass, Co @MagicConstant(flagsFromClass = RelativeFlags.class) int flags, boolean shouldConfirm) { Check.stateCondition(instance == null, "You need to use Entity#setInstance before teleporting an entity!"); - - EntityTeleportEvent event = new EntityTeleportEvent(this, position, flags); - EventDispatcher.call(event); - final Pos globalPosition = PositionUtils.getPositionWithRelativeFlags(this.position, position, flags); - final Runnable endCallback = () -> { this.previousPosition = this.position; this.position = globalPosition; @@ -1143,7 +1138,7 @@ protected void updatePose() { setPose(Pose.FALL_FLYING); } else if (entityMeta.isSwimming()) { setPose(Pose.SWIMMING); - } else if (entityMeta instanceof LivingEntityMeta livingMeta && livingMeta.isInRiptideSpinAttack()) { + } else if (this instanceof LivingEntity && entityMeta instanceof LivingEntityMeta && ((LivingEntityMeta) entityMeta).isInRiptideSpinAttack()) { setPose(Pose.SPIN_ATTACK); } else if (entityMeta.isSneaking()) { setPose(Pose.SNEAKING); diff --git a/src/main/java/net/minestom/server/entity/EntityProjectile.java b/src/main/java/net/minestom/server/entity/EntityProjectile.java index 6132577e365..f5548ce9d45 100644 --- a/src/main/java/net/minestom/server/entity/EntityProjectile.java +++ b/src/main/java/net/minestom/server/entity/EntityProjectile.java @@ -162,8 +162,8 @@ private boolean isStuck(Pos pos, Pos posNow) { chunk = currentChunk; entities = instance.getChunkEntities(chunk) .stream() - .filter(entity -> entity instanceof LivingEntity) - .map(entity -> (LivingEntity) entity) + .filter(LivingEntity.class::isInstance) //Microtus - update java keyword usage + .map(LivingEntity.class::cast) //Microtus - update java keyword usage .collect(Collectors.toSet()); } final Point currentPos = pos; diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java index 77789101ee7..d834b46270d 100644 --- a/src/main/java/net/minestom/server/entity/Player.java +++ b/src/main/java/net/minestom/server/entity/Player.java @@ -7,6 +7,7 @@ import net.kyori.adventure.identity.Identified; import net.kyori.adventure.identity.Identity; import net.kyori.adventure.inventory.Book; +import net.kyori.adventure.key.Key; import net.kyori.adventure.pointer.Pointers; import net.kyori.adventure.resource.ResourcePackCallback; import net.kyori.adventure.resource.ResourcePackInfo; @@ -35,6 +36,7 @@ import net.minestom.server.effects.Effects; import net.minestom.server.entity.attribute.Attribute; import net.minestom.server.entity.damage.DamageType; +import net.minestom.server.entity.metadata.EntityMeta; import net.minestom.server.entity.metadata.LivingEntityMeta; import net.minestom.server.entity.metadata.PlayerMeta; import net.minestom.server.entity.vehicle.PlayerVehicleInformation; @@ -904,8 +906,20 @@ public void sendMessage(final @NotNull Identity source, final @NotNull Component * * @param channel the message channel * @param data the message data + * @deprecated Use {@link #sendPluginMessage(Key, byte[])} instead. */ + @Deprecated(forRemoval = true, since = "1.5.0") public void sendPluginMessage(@NotNull String channel, byte @NotNull [] data) { + sendPluginMessage(Key.key(channel), data); + } + + /** + * Sends a plugin message to the player. + * + * @param channel the message channel + * @param data the message data + */ + public void sendPluginMessage(@NotNull Key channel, byte @NotNull [] data) { sendPacket(new PluginMessagePacket(channel, data)); } @@ -916,7 +930,9 @@ public void sendPluginMessage(@NotNull String channel, byte @NotNull [] data) { * * @param channel the message channel * @param message the message + * @deprecated Use {@link #sendPluginMessage(Key, byte[])} instead. */ + @Deprecated(forRemoval = true, since = "1.5.0") public void sendPluginMessage(@NotNull String channel, @NotNull String message) { sendPluginMessage(channel, message.getBytes(StandardCharsets.UTF_8)); } @@ -1047,6 +1063,10 @@ public void setHealth(float health) { return (PlayerMeta) super.getEntityMeta(); } + protected @NotNull EntityMeta getUnsafeEntityMeta() { + return super.getEntityMeta(); + } + /** * Gets the player additional hearts. * @@ -2324,16 +2344,6 @@ public void setLocale(@Nullable Locale locale) { return this.pointers; } - @Override - public boolean isPlayer() { - return true; - } - - @Override - public Player asPlayer() { - return this; - } - @Override protected void updateCollisions() { preventBlockPlacement = gameMode != GameMode.SPECTATOR; diff --git a/src/main/java/net/minestom/server/entity/PlayerSkin.java b/src/main/java/net/minestom/server/entity/PlayerSkin.java index fe85cf8ad30..88b81374aa5 100644 --- a/src/main/java/net/minestom/server/entity/PlayerSkin.java +++ b/src/main/java/net/minestom/server/entity/PlayerSkin.java @@ -60,20 +60,4 @@ public record PlayerSkin(String textures, String signature) { return null; } } - - /** - * @deprecated use {@link #textures()} - */ - @Deprecated - public String getTextures() { - return textures; - } - - /** - * @deprecated use {@link #signature()} - */ - @Deprecated - public String getSignature() { - return signature; - } } diff --git a/src/main/java/net/minestom/server/entity/ai/GoalSelector.java b/src/main/java/net/minestom/server/entity/ai/GoalSelector.java index e89698ad47e..3c3e48fc33e 100644 --- a/src/main/java/net/minestom/server/entity/ai/GoalSelector.java +++ b/src/main/java/net/minestom/server/entity/ai/GoalSelector.java @@ -2,6 +2,7 @@ import net.minestom.server.entity.Entity; import net.minestom.server.entity.EntityCreature; +import net.minestom.server.entity.LivingEntity; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -12,7 +13,7 @@ public abstract class GoalSelector { private WeakReference aiGroupWeakReference; protected EntityCreature entityCreature; - public GoalSelector(@NotNull EntityCreature entityCreature) { + protected GoalSelector(@NotNull EntityCreature entityCreature) { //Microtus - update java keyword usage this.entityCreature = entityCreature; } diff --git a/src/main/java/net/minestom/server/entity/ai/target/ClosestEntityTarget.java b/src/main/java/net/minestom/server/entity/ai/target/ClosestEntityTarget.java index 3775f1bf346..b046349be27 100644 --- a/src/main/java/net/minestom/server/entity/ai/target/ClosestEntityTarget.java +++ b/src/main/java/net/minestom/server/entity/ai/target/ClosestEntityTarget.java @@ -18,27 +18,6 @@ public class ClosestEntityTarget extends TargetSelector { private final double range; private final Predicate targetPredicate; - /** - * @param entityCreature the entity (self) - * @param range the maximum range the entity can target others within - * @param entitiesTarget the entities to target by class - * @deprecated Use {@link #ClosestEntityTarget(EntityCreature, double, Predicate)} - */ - @SafeVarargs - @Deprecated - public ClosestEntityTarget(@NotNull EntityCreature entityCreature, float range, - @NotNull Class... entitiesTarget) { - this(entityCreature, range, ent -> { - Class clazz = ent.getClass(); - for (Class targetClass : entitiesTarget) { - if (targetClass.isAssignableFrom(clazz)) { - return true; - } - } - return false; - }); - } - /** * @param entityCreature the entity (self) * @param range the maximum range the entity can target others within diff --git a/src/main/java/net/minestom/server/entity/metadata/EntityMeta.java b/src/main/java/net/minestom/server/entity/metadata/EntityMeta.java index 90b1663da75..11aa4444a50 100644 --- a/src/main/java/net/minestom/server/entity/metadata/EntityMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/EntityMeta.java @@ -14,13 +14,15 @@ public class EntityMeta { public static final byte OFFSET = 0; public static final byte MAX_OFFSET = OFFSET + 8; - private final static byte ON_FIRE_BIT = 0x01; - private final static byte CROUCHING_BIT = 0x02; - private final static byte SPRINTING_BIT = 0x08; - private final static byte SWIMMING_BIT = 0x10; - private final static byte INVISIBLE_BIT = 0x20; - private final static byte HAS_GLOWING_EFFECT_BIT = 0x40; - private final static byte FLYING_WITH_ELYTRA_BIT = (byte) 0x80; + //Microtus start - update java keyword usage + private static final byte ON_FIRE_BIT = 0x01; + private static final byte CROUCHING_BIT = 0x02; + private static final byte SPRINTING_BIT = 0x08; + private static final byte SWIMMING_BIT = 0x10; + private static final byte INVISIBLE_BIT = 0x20; + private static final byte HAS_GLOWING_EFFECT_BIT = 0x40; + private static final byte FLYING_WITH_ELYTRA_BIT = (byte) 0x80; + //Microtus end - update java keyword usage private final WeakReference entityRef; protected final MetadataHolder metadata; diff --git a/src/main/java/net/minestom/server/entity/metadata/LivingEntityMeta.java b/src/main/java/net/minestom/server/entity/metadata/LivingEntityMeta.java index d6b2ab27732..193b144cebd 100644 --- a/src/main/java/net/minestom/server/entity/metadata/LivingEntityMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/LivingEntityMeta.java @@ -15,9 +15,11 @@ public class LivingEntityMeta extends EntityMeta { public static final byte OFFSET = EntityMeta.MAX_OFFSET; public static final byte MAX_OFFSET = OFFSET + 7; - private final static byte IS_HAND_ACTIVE_BIT = 0x01; - private final static byte ACTIVE_HAND_BIT = 0x02; - private final static byte IS_IN_SPIN_ATTACK_BIT = 0x04; + //Microtus start - update java keyword usage + private static final byte IS_HAND_ACTIVE_BIT = 0x01; + private static final byte ACTIVE_HAND_BIT = 0x02; + private static final byte IS_IN_SPIN_ATTACK_BIT = 0x04; + //Microtus end - update java keyword usage protected LivingEntityMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); diff --git a/src/main/java/net/minestom/server/entity/metadata/MobMeta.java b/src/main/java/net/minestom/server/entity/metadata/MobMeta.java index 045b8d8fcc5..47d99a20a6d 100644 --- a/src/main/java/net/minestom/server/entity/metadata/MobMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/MobMeta.java @@ -8,9 +8,11 @@ public class MobMeta extends LivingEntityMeta { public static final byte OFFSET = LivingEntityMeta.MAX_OFFSET; public static final byte MAX_OFFSET = OFFSET + 1; - private final static byte NO_AI_BIT = 0x01; - private final static byte IS_LEFT_HANDED_BIT = 0x02; - private final static byte IS_AGGRESSIVE_BIT = 0x04; + //Microtus start - update java keyword usage + private static final byte NO_AI_BIT = 0x01; + private static final byte IS_LEFT_HANDED_BIT = 0x02; + private static final byte IS_AGGRESSIVE_BIT = 0x04; + //Microtus end - update java keyword usage protected MobMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); diff --git a/src/main/java/net/minestom/server/entity/metadata/PlayerMeta.java b/src/main/java/net/minestom/server/entity/metadata/PlayerMeta.java index b60b27fb0f4..54ca81fe192 100644 --- a/src/main/java/net/minestom/server/entity/metadata/PlayerMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/PlayerMeta.java @@ -12,13 +12,15 @@ public class PlayerMeta extends LivingEntityMeta { public static final byte OFFSET = LivingEntityMeta.MAX_OFFSET; public static final byte MAX_OFFSET = OFFSET + 5; - private final static byte CAPE_BIT = 0x01; - private final static byte JACKET_BIT = 0x02; - private final static byte LEFT_SLEEVE_BIT = 0x04; - private final static byte RIGHT_SLEEVE_BIT = 0x08; - private final static byte LEFT_LEG_BIT = 0x10; - private final static byte RIGHT_LEG_BIT = 0x20; - private final static byte HAT_BIT = 0x40; + //Microtus start - update java keyword usage + private static final byte CAPE_BIT = 0x01; + private static final byte JACKET_BIT = 0x02; + private static final byte LEFT_SLEEVE_BIT = 0x04; + private static final byte RIGHT_SLEEVE_BIT = 0x08; + private static final byte LEFT_LEG_BIT = 0x10; + private static final byte RIGHT_LEG_BIT = 0x20; + private static final byte HAT_BIT = 0x40; + //Microtus end - update java keyword usage public PlayerMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); diff --git a/src/main/java/net/minestom/server/entity/metadata/ambient/BatMeta.java b/src/main/java/net/minestom/server/entity/metadata/ambient/BatMeta.java index 69aa84ebb3b..4c2866d0950 100644 --- a/src/main/java/net/minestom/server/entity/metadata/ambient/BatMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/ambient/BatMeta.java @@ -8,7 +8,7 @@ public class BatMeta extends AmbientCreatureMeta { public static final byte OFFSET = AmbientCreatureMeta.MAX_OFFSET; public static final byte MAX_OFFSET = OFFSET + 0; - private final static byte IS_HANGING_BIT = 0x01; + private static final byte IS_HANGING_BIT = 0x01; //Microtus - update java keyword usage public BatMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); diff --git a/src/main/java/net/minestom/server/entity/metadata/animal/AbstractHorseMeta.java b/src/main/java/net/minestom/server/entity/metadata/animal/AbstractHorseMeta.java index cf607bd6cb5..a42e6dd73fc 100644 --- a/src/main/java/net/minestom/server/entity/metadata/animal/AbstractHorseMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/animal/AbstractHorseMeta.java @@ -8,12 +8,14 @@ public class AbstractHorseMeta extends AnimalMeta { public static final byte OFFSET = AnimalMeta.MAX_OFFSET; public static final byte MAX_OFFSET = OFFSET + 1; - private final static byte TAMED_BIT = 0x02; - private final static byte SADDLED_BIT = 0x04; - private final static byte HAS_BRED_BIT = 0x08; - private final static byte EATING_BIT = 0x10; - private final static byte REARING_BIT = 0x20; - private final static byte MOUTH_OPEN_BIT = 0x40; + //Microtus start - update java keyword usage + private static final byte TAMED_BIT = 0x02; + private static final byte SADDLED_BIT = 0x04; + private static final byte HAS_BRED_BIT = 0x08; + private static final byte EATING_BIT = 0x10; + private static final byte REARING_BIT = 0x20; + private static final byte MOUTH_OPEN_BIT = 0x40; + //Microtus end - update java keyword usage protected AbstractHorseMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); diff --git a/src/main/java/net/minestom/server/entity/metadata/animal/BeeMeta.java b/src/main/java/net/minestom/server/entity/metadata/animal/BeeMeta.java index d65538d79d6..9cbb7f62ecc 100644 --- a/src/main/java/net/minestom/server/entity/metadata/animal/BeeMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/animal/BeeMeta.java @@ -9,9 +9,11 @@ public class BeeMeta extends AnimalMeta { public static final byte OFFSET = AnimalMeta.MAX_OFFSET; public static final byte MAX_OFFSET = OFFSET + 2; - private final static byte ANGRY_BIT = 0x02; - private final static byte HAS_STUNG_BIT = 0x04; - private final static byte HAS_NECTAR_BIT = 0x08; + //Microtus start - update java keyword usage + private static final byte ANGRY_BIT = 0x02; + private static final byte HAS_STUNG_BIT = 0x04; + private static final byte HAS_NECTAR_BIT = 0x08; + //Microtus end - update java keyword usage public BeeMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); diff --git a/src/main/java/net/minestom/server/entity/metadata/animal/FoxMeta.java b/src/main/java/net/minestom/server/entity/metadata/animal/FoxMeta.java index b7cb5c17c2e..84e6e3ef95a 100644 --- a/src/main/java/net/minestom/server/entity/metadata/animal/FoxMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/animal/FoxMeta.java @@ -12,13 +12,15 @@ public class FoxMeta extends AnimalMeta { public static final byte OFFSET = AnimalMeta.MAX_OFFSET; public static final byte MAX_OFFSET = OFFSET + 4; - private final static byte SITTING_BIT = 0x01; - private final static byte CROUCHING_BIT = 0x04; - private final static byte INTERESTED_BIT = 0x08; - private final static byte POUNCING_BIT = 0x10; - private final static byte SLEEPING_BIT = 0x20; - private final static byte FACEPLANTED_BIT = 0x40; - private final static byte DEFENDING_BIT = (byte) 0x80; + //Microtus start - update java keyword usage + private static final byte SITTING_BIT = 0x01; + private static final byte CROUCHING_BIT = 0x04; + private static final byte INTERESTED_BIT = 0x08; + private static final byte POUNCING_BIT = 0x10; + private static final byte SLEEPING_BIT = 0x20; + private static final byte FACEPLANTED_BIT = 0x40; + private static final byte DEFENDING_BIT = (byte) 0x80; + //Microtus end - update java keyword usage public FoxMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); @@ -111,7 +113,7 @@ public enum Type { RED, SNOW; - private final static Type[] VALUES = values(); + private static final Type[] VALUES = values(); } } diff --git a/src/main/java/net/minestom/server/entity/metadata/animal/FrogMeta.java b/src/main/java/net/minestom/server/entity/metadata/animal/FrogMeta.java index 40dbf21090c..5110d383c02 100644 --- a/src/main/java/net/minestom/server/entity/metadata/animal/FrogMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/animal/FrogMeta.java @@ -15,24 +15,48 @@ public FrogMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); } - public Variant getVariant() { + /** + * Get the current {@link Variant} from a frog. + * @return the given variant entry + */ + public @NotNull Variant getVariant() { return super.metadata.getIndex(OFFSET, Variant.TEMPERATE); } + /** + * Set the variant for a frog. + * @param value the value to set + */ public void setVariant(@NotNull Variant value) { super.metadata.setIndex(OFFSET, Metadata.FrogVariant(value)); } - public @Nullable Integer getTongueTarget() { - return super.metadata.getIndex(OFFSET + 1, null); + /** + * Get the current tongue target value. + * @return the given value + */ + public int getTongueTarget() { + return super.metadata.getIndex(OFFSET + 1, 0); } + /** + * Set's the current tongue target back to the default value from the protocol. + */ + public void resetTongueTarget() { + super.metadata.setIndex(OFFSET + 1, Metadata.VarInt(0)); + } - public void setTongueTarget(@Nullable Integer value) { + /** + * Set the target value for a tongue. + * @param value the target to set + */ + public void setTongueTarget(int value) { super.metadata.setIndex(OFFSET + 1, Metadata.OptVarInt(value)); } - + /** + * The enum contains all variants from a frog which are currently implemented in the game. + */ public enum Variant { TEMPERATE, WARM, diff --git a/src/main/java/net/minestom/server/entity/metadata/animal/GoatMeta.java b/src/main/java/net/minestom/server/entity/metadata/animal/GoatMeta.java index 81ee50d5940..12f60559f10 100644 --- a/src/main/java/net/minestom/server/entity/metadata/animal/GoatMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/animal/GoatMeta.java @@ -21,6 +21,7 @@ public void setScreaming(boolean screaming) { metadata.setIndex(OFFSET, Metadata.Boolean(screaming)); } + // Microtus start - meta update public boolean hasLeftHorn() { return metadata.getIndex(OFFSET + 1, true); } @@ -36,4 +37,5 @@ public boolean hasRightHorn() { public void setRightHorn(boolean rightHorn) { metadata.setIndex(OFFSET + 2, Metadata.Boolean(rightHorn)); } + // Microtus end - meta update } diff --git a/src/main/java/net/minestom/server/entity/metadata/animal/HorseMeta.java b/src/main/java/net/minestom/server/entity/metadata/animal/HorseMeta.java index fb98e5e06d7..21a2c88904a 100644 --- a/src/main/java/net/minestom/server/entity/metadata/animal/HorseMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/animal/HorseMeta.java @@ -69,7 +69,7 @@ public enum Marking { WHITE_DOTS, BLACK_DOTS; - private final static Marking[] VALUES = values(); + private static final Marking[] VALUES = values(); //Microtus - update java keyword usage } public enum Color { @@ -81,7 +81,6 @@ public enum Color { GRAY, DARK_BROWN; - private final static Color[] VALUES = values(); + private static final Color[] VALUES = values(); //Microtus - update java keyword usage } - } diff --git a/src/main/java/net/minestom/server/entity/metadata/animal/LlamaMeta.java b/src/main/java/net/minestom/server/entity/metadata/animal/LlamaMeta.java index 44b11667d27..62ec398ea79 100644 --- a/src/main/java/net/minestom/server/entity/metadata/animal/LlamaMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/animal/LlamaMeta.java @@ -43,7 +43,6 @@ public enum Variant { BROWN, GRAY; - private final static Variant[] VALUES = values(); + private static final Variant[] VALUES = values(); //Microtus - update java keyword usage } - } diff --git a/src/main/java/net/minestom/server/entity/metadata/animal/PandaMeta.java b/src/main/java/net/minestom/server/entity/metadata/animal/PandaMeta.java index a915857572f..cbf91f3aaff 100644 --- a/src/main/java/net/minestom/server/entity/metadata/animal/PandaMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/animal/PandaMeta.java @@ -9,10 +9,12 @@ public class PandaMeta extends AnimalMeta { public static final byte OFFSET = AnimalMeta.MAX_OFFSET; public static final byte MAX_OFFSET = OFFSET + 6; - private final static byte SNEEZING_BIT = 0x02; - private final static byte ROLLING_BIT = 0x04; - private final static byte SITTING_BIT = 0x08; - private final static byte ON_BACK_BIT = 0x10; + //Microtus start - update java keyword usage + private static final byte SNEEZING_BIT = 0x02; + private static final byte ROLLING_BIT = 0x04; + private static final byte SITTING_BIT = 0x08; + private static final byte ON_BACK_BIT = 0x10; + //Microtus end - update java keyword usage public PandaMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); diff --git a/src/main/java/net/minestom/server/entity/metadata/animal/SheepMeta.java b/src/main/java/net/minestom/server/entity/metadata/animal/SheepMeta.java index b20e25e9a64..ea127614ec9 100644 --- a/src/main/java/net/minestom/server/entity/metadata/animal/SheepMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/animal/SheepMeta.java @@ -8,8 +8,10 @@ public class SheepMeta extends AnimalMeta { public static final byte OFFSET = AnimalMeta.MAX_OFFSET; public static final byte MAX_OFFSET = OFFSET + 1; - private final static byte COLOR_BITS = 0x0F; - private final static byte SHEARED_BIT = 0x10; + //Microtus start - update java keyword usage + private static final byte COLOR_BITS = 0x0F; + private static final byte SHEARED_BIT = 0x10; + //Microtus end - update java keyword usage public SheepMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); diff --git a/src/main/java/net/minestom/server/entity/metadata/display/AbstractDisplayMeta.java b/src/main/java/net/minestom/server/entity/metadata/display/AbstractDisplayMeta.java index 1c8e0c9eb46..bdba2ec4402 100644 --- a/src/main/java/net/minestom/server/entity/metadata/display/AbstractDisplayMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/display/AbstractDisplayMeta.java @@ -145,7 +145,6 @@ public enum BillboardConstraints { HORIZONTAL, CENTER; - private final static BillboardConstraints[] VALUES = values(); + private static final BillboardConstraints[] VALUES = values(); //Microtus - update java keyword usage } - } diff --git a/src/main/java/net/minestom/server/entity/metadata/display/ItemDisplayMeta.java b/src/main/java/net/minestom/server/entity/metadata/display/ItemDisplayMeta.java index 0ac24b14382..1d2b93f5954 100644 --- a/src/main/java/net/minestom/server/entity/metadata/display/ItemDisplayMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/display/ItemDisplayMeta.java @@ -41,7 +41,7 @@ public enum DisplayContext { GROUND, FIXED; - private final static DisplayContext[] VALUES = values(); + private static final DisplayContext[] VALUES = values(); //Microtus - update java keyword usage } } diff --git a/src/main/java/net/minestom/server/entity/metadata/golem/IronGolemMeta.java b/src/main/java/net/minestom/server/entity/metadata/golem/IronGolemMeta.java index a82131c984d..9ce3966e9a5 100644 --- a/src/main/java/net/minestom/server/entity/metadata/golem/IronGolemMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/golem/IronGolemMeta.java @@ -7,8 +7,7 @@ public class IronGolemMeta extends AbstractGolemMeta { public static final byte OFFSET = AbstractGolemMeta.MAX_OFFSET; public static final byte MAX_OFFSET = OFFSET + 1; - - private final static byte PLAYER_CREATED_BIT = 0x01; + private static final byte PLAYER_CREATED_BIT = 0x01; //Microtus - update java keyword usage public IronGolemMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); diff --git a/src/main/java/net/minestom/server/entity/metadata/monster/BlazeMeta.java b/src/main/java/net/minestom/server/entity/metadata/monster/BlazeMeta.java index 5690a553c96..a5fab29ff42 100644 --- a/src/main/java/net/minestom/server/entity/metadata/monster/BlazeMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/monster/BlazeMeta.java @@ -7,8 +7,7 @@ public class BlazeMeta extends MonsterMeta { public static final byte OFFSET = MonsterMeta.MAX_OFFSET; public static final byte MAX_OFFSET = OFFSET + 1; - - private final static byte ON_FIRE_BIT = 0x01; + private static final byte ON_FIRE_BIT = 0x01; //Microtus - update java keyword usage public BlazeMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); diff --git a/src/main/java/net/minestom/server/entity/metadata/monster/SpiderMeta.java b/src/main/java/net/minestom/server/entity/metadata/monster/SpiderMeta.java index d5e2accf563..f2bd7c63bb3 100644 --- a/src/main/java/net/minestom/server/entity/metadata/monster/SpiderMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/monster/SpiderMeta.java @@ -7,8 +7,7 @@ public class SpiderMeta extends MonsterMeta { public static final byte OFFSET = MonsterMeta.MAX_OFFSET; public static final byte MAX_OFFSET = OFFSET + 1; - - private final static byte CLIMBING_BIT = 0x01; + private static final byte CLIMBING_BIT = 0x01; //Microtus - update java keyword usage public SpiderMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); diff --git a/src/main/java/net/minestom/server/entity/metadata/monster/VexMeta.java b/src/main/java/net/minestom/server/entity/metadata/monster/VexMeta.java index 9a74b0867e7..2b44ac08305 100644 --- a/src/main/java/net/minestom/server/entity/metadata/monster/VexMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/monster/VexMeta.java @@ -7,8 +7,7 @@ public class VexMeta extends MonsterMeta { public static final byte OFFSET = MonsterMeta.MAX_OFFSET; public static final byte MAX_OFFSET = OFFSET + 1; - - private final static byte ATTACKING_BIT = 0x01; + private static final byte ATTACKING_BIT = 0x01; //Microtus - update java keyword usage public VexMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); diff --git a/src/main/java/net/minestom/server/entity/metadata/monster/WardenMeta.java b/src/main/java/net/minestom/server/entity/metadata/monster/WardenMeta.java index 540fa9d5f2a..05237bf473c 100644 --- a/src/main/java/net/minestom/server/entity/metadata/monster/WardenMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/monster/WardenMeta.java @@ -5,21 +5,41 @@ import net.minestom.server.entity.MetadataHolder; import org.jetbrains.annotations.NotNull; +// Microtus - entity meta update +/** + * This metadata implementation can be used for a warden entity. + * @author theEvilReaper + * @version 1.0.0 + * @since 1.0.0 + **/ public class WardenMeta extends MonsterMeta { public static final byte OFFSET = MonsterMeta.MAX_OFFSET; public static final byte MAX_OFFSET = OFFSET + 1; + + /** + * Creates a new metadata which can be set to a warden entity. + * @param entity the warden entity reference + * @param metadata the reference to a {@link Metadata} + */ public WardenMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); } - public int getAngerLevel() { - return super.metadata.getIndex(OFFSET, 0); - } - + /** + * Set the anger level for a warden. + * @param value the level to set + */ public void setAngerLevel(int value) { super.metadata.setIndex(OFFSET, Metadata.VarInt(value)); } + /** + * Returns the given anger level from the meta or zero as default value if no value is set. + * @return the given level + */ + public int getAngerLevel() { + return super.metadata.getIndex(OFFSET, 0); + } } diff --git a/src/main/java/net/minestom/server/entity/metadata/monster/raider/PillagerMeta.java b/src/main/java/net/minestom/server/entity/metadata/monster/raider/PillagerMeta.java index b5de1e35451..1c0e3d6c9f5 100644 --- a/src/main/java/net/minestom/server/entity/metadata/monster/raider/PillagerMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/monster/raider/PillagerMeta.java @@ -13,12 +13,21 @@ public PillagerMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); } - public boolean isChargingCrossbow() { - return super.metadata.getIndex(OFFSET, false); - } - + // Microtus start - meta update + /** + * Set the state if a Pillager charge his crossbow. + * @param value the value to set + */ public void setChargingCrossbow(boolean value) { super.metadata.setIndex(OFFSET, Metadata.Boolean(value)); } + /** + * Returns a boolean value if a Pillager is charging his crossbow. + * @return true when yes otherwise false + */ + public boolean isChargingCrossbow() { + return super.metadata.getIndex(OFFSET, false); + } + // Microtus end - meta update } diff --git a/src/main/java/net/minestom/server/entity/metadata/monster/zombie/ZombieVillagerMeta.java b/src/main/java/net/minestom/server/entity/metadata/monster/zombie/ZombieVillagerMeta.java index 66023cc1212..ea04af22fb9 100644 --- a/src/main/java/net/minestom/server/entity/metadata/monster/zombie/ZombieVillagerMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/monster/zombie/ZombieVillagerMeta.java @@ -4,6 +4,8 @@ import net.minestom.server.entity.Metadata; import net.minestom.server.entity.MetadataHolder; import net.minestom.server.entity.metadata.villager.VillagerMeta; +import net.minestom.server.entity.villager.VillagerProfession; +import net.minestom.server.entity.villager.VillagerType; import org.jetbrains.annotations.NotNull; public class ZombieVillagerMeta extends ZombieMeta { @@ -25,15 +27,15 @@ public void setConverting(boolean value) { public VillagerMeta.VillagerData getVillagerData() { int[] data = super.metadata.getIndex(OFFSET + 1, null); if (data == null) { - return new VillagerMeta.VillagerData(VillagerMeta.Type.PLAINS, VillagerMeta.Profession.NONE, VillagerMeta.Level.NOVICE); + return new VillagerMeta.VillagerData(VillagerType.PLAINS, VillagerProfession.NONE, VillagerMeta.Level.NOVICE); } - return new VillagerMeta.VillagerData(VillagerMeta.Type.VALUES[data[0]], VillagerMeta.Profession.VALUES[data[1]], VillagerMeta.Level.VALUES[data[2] - 1]); + return new VillagerMeta.VillagerData(VillagerType.fromId(data[0]), VillagerProfession.fromId(data[1]), VillagerMeta.Level.VALUES[data[2] - 1]); } public void setVillagerData(VillagerMeta.VillagerData data) { super.metadata.setIndex(OFFSET + 1, Metadata.VillagerData( - data.getType().ordinal(), - data.getProfession().ordinal(), + data.getType().id(), + data.getProfession().id(), data.getLevel().ordinal() + 1 )); } diff --git a/src/main/java/net/minestom/server/entity/metadata/other/ArmorStandMeta.java b/src/main/java/net/minestom/server/entity/metadata/other/ArmorStandMeta.java index aedc5f58469..c1f53492724 100644 --- a/src/main/java/net/minestom/server/entity/metadata/other/ArmorStandMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/other/ArmorStandMeta.java @@ -11,10 +11,12 @@ public class ArmorStandMeta extends LivingEntityMeta { public static final byte OFFSET = LivingEntityMeta.MAX_OFFSET; public static final byte MAX_OFFSET = OFFSET + 7; - private final static byte IS_SMALL_BIT = 0x01; - private final static byte HAS_ARMS_BIT = 0x04; - private final static byte HAS_NO_BASE_PLATE_BIT = 0x08; - private final static byte IS_MARKER_BIT = 0x10; + //Microtus start - update java keyword usage + private static final byte IS_SMALL_BIT = 0x01; + private static final byte HAS_ARMS_BIT = 0x04; + private static final byte HAS_NO_BASE_PLATE_BIT = 0x08; + private static final byte IS_MARKER_BIT = 0x10; + //Microtus end - update java keyword usage public ArmorStandMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); diff --git a/src/main/java/net/minestom/server/entity/metadata/other/BoatMeta.java b/src/main/java/net/minestom/server/entity/metadata/other/BoatMeta.java index f1c954cdf2e..a0a3d02ff95 100644 --- a/src/main/java/net/minestom/server/entity/metadata/other/BoatMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/other/BoatMeta.java @@ -82,7 +82,7 @@ public enum Type { MANGROVE, BAMBOO; - private final static Type[] VALUES = values(); + private static final Type[] VALUES = values(); } } diff --git a/src/main/java/net/minestom/server/entity/metadata/other/EnderDragonMeta.java b/src/main/java/net/minestom/server/entity/metadata/other/EnderDragonMeta.java index 8713235d56b..931be9044f3 100644 --- a/src/main/java/net/minestom/server/entity/metadata/other/EnderDragonMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/other/EnderDragonMeta.java @@ -36,7 +36,6 @@ public enum Phase { FLYING_TO_THE_PORTAL_TO_DIE, HOVERING_WITHOUT_AI; - private final static Phase[] VALUES = values(); + private static final Phase[] VALUES = values(); //Microtus - update java keyword usage } - } diff --git a/src/main/java/net/minestom/server/entity/metadata/projectile/AbstractArrowMeta.java b/src/main/java/net/minestom/server/entity/metadata/projectile/AbstractArrowMeta.java index 649223612e0..53b50c7eb67 100644 --- a/src/main/java/net/minestom/server/entity/metadata/projectile/AbstractArrowMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/projectile/AbstractArrowMeta.java @@ -10,8 +10,10 @@ public class AbstractArrowMeta extends EntityMeta { public static final byte OFFSET = EntityMeta.MAX_OFFSET; public static final byte MAX_OFFSET = OFFSET + 2; - private final static byte CRITICAL_BIT = 0x01; - private final static byte NO_CLIP_BIT = 0x02; + //Microtus start - update java keyword usage + private static final byte CRITICAL_BIT = 0x01; + private static final byte NO_CLIP_BIT = 0x02; + //Microtus end - update java keyword usage protected AbstractArrowMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); diff --git a/src/main/java/net/minestom/server/entity/metadata/villager/VillagerMeta.java b/src/main/java/net/minestom/server/entity/metadata/villager/VillagerMeta.java index aa72c04c097..6fd0de565c7 100644 --- a/src/main/java/net/minestom/server/entity/metadata/villager/VillagerMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/villager/VillagerMeta.java @@ -2,6 +2,8 @@ import net.minestom.server.entity.Entity; import net.minestom.server.entity.Metadata; +import net.minestom.server.entity.villager.VillagerProfession; +import net.minestom.server.entity.villager.VillagerType; import net.minestom.server.entity.MetadataHolder; import org.jetbrains.annotations.NotNull; @@ -17,46 +19,46 @@ public VillagerMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { public VillagerData getVillagerData() { int[] data = super.metadata.getIndex(OFFSET, null); if (data == null) { - return new VillagerData(Type.PLAINS, Profession.NONE, Level.NOVICE); + return new VillagerData(VillagerType.PLAINS, VillagerProfession.NONE, Level.NOVICE); } - return new VillagerData(Type.VALUES[data[0]], Profession.VALUES[data[1]], Level.VALUES[data[2] - 1]); + return new VillagerData(VillagerType.fromId(data[0]), VillagerProfession.fromId(data[1]), Level.VALUES[data[2] - 1]); } public void setVillagerData(@NotNull VillagerData data) { super.metadata.setIndex(OFFSET, Metadata.VillagerData( - data.type.ordinal(), - data.profession.ordinal(), + data.type.id(), + data.profession.id(), data.level.ordinal() + 1 )); } public static class VillagerData { - private Type type; - private Profession profession; + private VillagerType type; + private VillagerProfession profession; private Level level; - public VillagerData(@NotNull Type type, @NotNull Profession profession, @NotNull Level level) { + public VillagerData(@NotNull VillagerType type, @NotNull VillagerProfession profession, @NotNull Level level) { this.type = type; this.profession = profession; this.level = level; } @NotNull - public Type getType() { + public VillagerType getType() { return this.type; } - public void setType(@NotNull Type type) { + public void setType(@NotNull VillagerType type) { this.type = type; } @NotNull - public Profession getProfession() { + public VillagerProfession getProfession() { return this.profession; } - public void setProfession(@NotNull Profession profession) { + public void setProfession(@NotNull VillagerProfession profession) { this.profession = profession; } @@ -70,39 +72,6 @@ public void setLevel(@NotNull Level level) { } } - public enum Type { - DESERT, - JUNGLE, - PLAINS, - SAVANNA, - SNOW, - SWAMP, - TAIGA; - - public final static Type[] VALUES = values(); - } - - public enum Profession { - NONE, - ARMORER, - BUTCHER, - CARTOGRAPHER, - CLERIC, - FARMER, - FISHERMAN, - FLETCHER, - LEATHERWORKER, - LIBRARIAN, - NITWIT, - UNEMPLOYED, - MASON, - SHEPHERD, - TOOLSMITH, - WEAPONSMITH; - - public final static Profession[] VALUES = values(); - } - public enum Level { NOVICE, APPRENTICE, diff --git a/src/main/java/net/minestom/server/entity/metadata/water/AxolotlMeta.java b/src/main/java/net/minestom/server/entity/metadata/water/AxolotlMeta.java index 92bff5a722e..68c68bce3fb 100644 --- a/src/main/java/net/minestom/server/entity/metadata/water/AxolotlMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/water/AxolotlMeta.java @@ -45,6 +45,6 @@ public enum Variant { CYAN, BLUE; - private final static AxolotlMeta.Variant[] VALUES = values(); + private static final AxolotlMeta.Variant[] VALUES = values(); //Microtus - update java keyword usage } } diff --git a/src/main/java/net/minestom/server/entity/metadata/water/DolphinMeta.java b/src/main/java/net/minestom/server/entity/metadata/water/DolphinMeta.java index 8ecd228dbc1..bc37f0b2cfa 100644 --- a/src/main/java/net/minestom/server/entity/metadata/water/DolphinMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/water/DolphinMeta.java @@ -11,32 +11,70 @@ public class DolphinMeta extends WaterAnimalMeta { public static final byte OFFSET = WaterAnimalMeta.MAX_OFFSET; public static final byte MAX_OFFSET = OFFSET + 3; + /** + * Creates a new meta data for a dolphin. + * @param entity the involved entity + * @param metadata the base metadata + */ public DolphinMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); } - @NotNull - public Point getTreasurePosition() { + /** + * Get the given destination point for a treasure. + * @return the point or {@link Vec#ZERO} when no point is set + */ + public @NotNull Point getTreasurePosition() { return super.metadata.getIndex(OFFSET, Vec.ZERO); } + /** + * Set the destination point to lead a player to a treasure. + * @param value the point to set + */ public void setTreasurePosition(@NotNull Point value) { super.metadata.setIndex(OFFSET, Metadata.BlockPosition(value)); } + /** + * Returns an indicator if a Dolphin received a fish from a player. + * @return true when yes otherwise false + */ + @Deprecated + public boolean hasFish() { + return super.metadata.getIndex(OFFSET + 1, false); + } + + /** + * Returns an indicator if a Dolphin received a fish from a player. + * @return true when yes otherwise false + */ public boolean isHasFish() { return super.metadata.getIndex(OFFSET + 1, false); } + /** + * Set the indicator if a Dolphin got a fish from a player. + * @param value the value to set + */ public void setHasFish(boolean value) { super.metadata.setIndex(OFFSET + 1, Metadata.Boolean(value)); } + /** + * Get the current moisture level. + * @return the given level + */ public int getMoistureLevel() { return super.metadata.getIndex(OFFSET + 2, 2400); } - public void setMoistureLevel(int value) { - super.metadata.setIndex(OFFSET + 2, Metadata.VarInt(value)); + /** + * Updates the given moisture level. + * @param level the level to set + */ + public void setMoistureLevel(int level) { + super.metadata.setIndex(OFFSET + 2, Metadata.VarInt(level)); } + } diff --git a/src/main/java/net/minestom/server/entity/metadata/water/fish/TadpoleMeta.java b/src/main/java/net/minestom/server/entity/metadata/water/fish/TadpoleMeta.java index 808197a1f8e..466e766d595 100644 --- a/src/main/java/net/minestom/server/entity/metadata/water/fish/TadpoleMeta.java +++ b/src/main/java/net/minestom/server/entity/metadata/water/fish/TadpoleMeta.java @@ -4,12 +4,18 @@ import net.minestom.server.entity.MetadataHolder; import org.jetbrains.annotations.NotNull; -public class TadpoleMeta extends AbstractFishMeta { - public static final byte OFFSET = AbstractFishMeta.MAX_OFFSET; - public static final byte MAX_OFFSET = OFFSET + 0; +// Microtus - entity meta update +/** + * Metadata implementation for a Tadpole entity. + */ +public final class TadpoleMeta extends AbstractFishMeta { + /** + * Creates a new reference from this meta. + * @param entity the involved entity + * @param metadata the involved metadata + */ public TadpoleMeta(@NotNull Entity entity, @NotNull MetadataHolder metadata) { super(entity, metadata); } - } diff --git a/src/main/java/net/minestom/server/entity/villager/VillagerProfession.java b/src/main/java/net/minestom/server/entity/villager/VillagerProfession.java new file mode 100644 index 00000000000..faf65662f88 --- /dev/null +++ b/src/main/java/net/minestom/server/entity/villager/VillagerProfession.java @@ -0,0 +1,42 @@ +package net.minestom.server.entity.villager; + +import net.kyori.adventure.key.Key; +import net.minestom.server.registry.Registry; +import net.minestom.server.registry.StaticProtocolObject; +import net.minestom.server.utils.NamespaceID; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +public interface VillagerProfession extends StaticProtocolObject, VillagerProfessions { + static @NotNull Collection<@NotNull VillagerProfession> values() { + return VillagerProfessionImpl.values(); + } + + static @Nullable VillagerProfession fromNamespaceId(@NotNull String namespaceID) { + return VillagerProfessionImpl.getSafe(namespaceID); + } + + static @Nullable VillagerProfession fromNamespaceId(@NotNull NamespaceID namespaceID) { + return fromNamespaceId(namespaceID.asString()); + } + + static @Nullable VillagerProfession fromId(int id) { + return VillagerProfessionImpl.getId(id); + } + + @Override + default @NotNull Key key() { + return StaticProtocolObject.super.key(); + } + + @Contract(pure = true) + Registry.VillagerProfession registry(); + + @Override + default @NotNull NamespaceID namespace() { + return registry().namespace(); + } +} diff --git a/src/main/java/net/minestom/server/entity/villager/VillagerProfessionImpl.java b/src/main/java/net/minestom/server/entity/villager/VillagerProfessionImpl.java new file mode 100644 index 00000000000..338cbb39e3f --- /dev/null +++ b/src/main/java/net/minestom/server/entity/villager/VillagerProfessionImpl.java @@ -0,0 +1,39 @@ +package net.minestom.server.entity.villager; + +import net.minestom.server.registry.Registry; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +public record VillagerProfessionImpl(Registry.VillagerProfession registry, int id) implements VillagerProfession { + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.VILLAGER_PROFESSION, VillagerProfessionImpl::createImpl); + + public VillagerProfessionImpl(Registry.VillagerProfession registry) { + this(registry, registry.id()); + } + + private static VillagerProfession createImpl(String namespace, Registry.Properties properties) { + return new VillagerProfessionImpl(Registry.villagerProfession(namespace, properties)); + } + + static VillagerProfession get(@NotNull String namespace) { + return CONTAINER.get(namespace); + } + + static VillagerProfession getSafe(@NotNull String namespace) { + return CONTAINER.getSafe(namespace); + } + + static VillagerProfession getId(int id) { + return CONTAINER.getId(id); + } + + static Collection values() { + return CONTAINER.values(); + } + + @Override + public String toString() { + return name(); + } +} diff --git a/src/main/java/net/minestom/server/entity/villager/VillagerType.java b/src/main/java/net/minestom/server/entity/villager/VillagerType.java new file mode 100644 index 00000000000..ac8fcfd4f21 --- /dev/null +++ b/src/main/java/net/minestom/server/entity/villager/VillagerType.java @@ -0,0 +1,43 @@ +package net.minestom.server.entity.villager; + +import net.kyori.adventure.key.Key; +import net.minestom.server.registry.Registry; +import net.minestom.server.registry.StaticProtocolObject; +import net.minestom.server.utils.NamespaceID; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +public sealed interface VillagerType extends StaticProtocolObject, VillagerTypes permits VillagerTypeImpl { + + static @NotNull Collection<@NotNull VillagerType> values() { + return VillagerTypeImpl.values(); + } + + static @Nullable VillagerType fromNamespaceId(@NotNull String namespaceID) { + return VillagerTypeImpl.getSafe(namespaceID); + } + + static @Nullable VillagerType fromNamespaceId(@NotNull NamespaceID namespaceID) { + return fromNamespaceId(namespaceID.asString()); + } + + static @Nullable VillagerType fromId(int id) { + return VillagerTypeImpl.getId(id); + } + + @Override + default @NotNull Key key() { + return StaticProtocolObject.super.key(); + } + + @Contract(pure = true) + Registry.VillagerType registry(); + + @Override + default @NotNull NamespaceID namespace() { + return registry().namespace(); + } +} diff --git a/src/main/java/net/minestom/server/entity/villager/VillagerTypeImpl.java b/src/main/java/net/minestom/server/entity/villager/VillagerTypeImpl.java new file mode 100644 index 00000000000..ec8af984f09 --- /dev/null +++ b/src/main/java/net/minestom/server/entity/villager/VillagerTypeImpl.java @@ -0,0 +1,39 @@ +package net.minestom.server.entity.villager; + +import net.minestom.server.registry.Registry; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +public record VillagerTypeImpl(Registry.VillagerType registry, int id) implements VillagerType { + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.VILLAGER_TYPES, VillagerTypeImpl::createImpl); + + public VillagerTypeImpl(Registry.VillagerType registry) { + this(registry, registry.id()); + } + + private static VillagerType createImpl(String namespace, Registry.Properties properties) { + return new VillagerTypeImpl(Registry.villagerType(namespace, properties)); + } + + static VillagerType get(@NotNull String namespace) { + return CONTAINER.get(namespace); + } + + static VillagerType getSafe(@NotNull String namespace) { + return CONTAINER.getSafe(namespace); + } + + static VillagerType getId(int id) { + return CONTAINER.getId(id); + } + + static Collection values() { + return CONTAINER.values(); + } + + @Override + public String toString() { + return name(); + } +} diff --git a/src/main/java/net/minestom/server/event/instance/InstanceWorldPositionChangeEvent.java b/src/main/java/net/minestom/server/event/instance/InstanceWorldPositionChangeEvent.java new file mode 100644 index 00000000000..d7ef61eaed4 --- /dev/null +++ b/src/main/java/net/minestom/server/event/instance/InstanceWorldPositionChangeEvent.java @@ -0,0 +1,60 @@ +package net.minestom.server.event.instance; + +import net.minestom.server.coordinate.Pos; +import net.minestom.server.event.trait.InstanceEvent; +import net.minestom.server.instance.Instance; +import org.jetbrains.annotations.NotNull; + +//Microtus start - integrate world spawn position +/** + * The event is triggered by the server when an instance successfully changes its world spawn position. + * By implementing a listener for this event, developers can track changes to a world's spawn position initiated by instances during runtime. + * @author theEvilReaper + * @version 1.0.0 + * @since 1.1.3 + */ +public class InstanceWorldPositionChangeEvent implements InstanceEvent { + + private final Instance instance; + private final Pos oldPosition; + + /** + * Constructs a new {@code InstanceWorldPositionChangeEvent} with the specified parameters. + * + * @param instance the involved instance + * @param oldPosition the old position of the instance before the change + */ + public InstanceWorldPositionChangeEvent(@NotNull Instance instance, @NotNull Pos oldPosition) { + this.instance = instance; + this.oldPosition = oldPosition; + } + + /** + * Gets the new position of the instance after the change. + * + * @return the new position + */ + public @NotNull Pos getNewPosition() { + return instance.getWorldSpawnPosition(); + } + + /** + * Gets the old position of the instance before the change. + * + * @return the old position + */ + public @NotNull Pos getOldPosition() { + return oldPosition; + } + + /** + * Gets the instance which received a world position change. + * + * @return the involved instance + */ + @Override + public @NotNull Instance getInstance() { + return instance; + } +} +//Microtus end - integrate world spawn position \ No newline at end of file diff --git a/src/main/java/net/minestom/server/event/player/PlayerEatEvent.java b/src/main/java/net/minestom/server/event/player/PlayerEatEvent.java index b45665fb719..71d3c37edba 100644 --- a/src/main/java/net/minestom/server/event/player/PlayerEatEvent.java +++ b/src/main/java/net/minestom/server/event/player/PlayerEatEvent.java @@ -21,17 +21,6 @@ public PlayerEatEvent(@NotNull Player player, @NotNull ItemStack foodItem, @NotN this.hand = hand; } - /** - * Gets the food item that has been eaten. - * - * @return the food item - * @deprecated use getItemStack() for the eaten item - */ - @Deprecated - public @NotNull ItemStack getFoodItem() { - return foodItem; - } - public @NotNull Player.Hand getHand() { return hand; } diff --git a/src/main/java/net/minestom/server/event/player/PlayerPreEatEvent.java b/src/main/java/net/minestom/server/event/player/PlayerPreEatEvent.java index abf6b633671..5531c7ac14b 100644 --- a/src/main/java/net/minestom/server/event/player/PlayerPreEatEvent.java +++ b/src/main/java/net/minestom/server/event/player/PlayerPreEatEvent.java @@ -28,17 +28,6 @@ public PlayerPreEatEvent(@NotNull Player player, @NotNull ItemStack foodItem, @N this.eatingTime = eatingTime; } - /** - * The food item which will be eaten. - * - * @return the food item - * @deprecated use getItemStack() for the eaten item - */ - @Deprecated - public @NotNull ItemStack getFoodItem() { - return foodItem; - } - public @NotNull Player.Hand getHand() { return hand; } diff --git a/src/main/java/net/minestom/server/exception/ExceptionManager.java b/src/main/java/net/minestom/server/exception/ExceptionManager.java index 1ee7870e905..14b2d21a3d2 100644 --- a/src/main/java/net/minestom/server/exception/ExceptionManager.java +++ b/src/main/java/net/minestom/server/exception/ExceptionManager.java @@ -2,12 +2,16 @@ import net.minestom.server.MinecraftServer; import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Manages the handling of exceptions. */ public final class ExceptionManager { + private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionManager.class); + private ExceptionHandler exceptionHandler; /** @@ -18,7 +22,7 @@ public final class ExceptionManager { public void handleException(Throwable e) { if (e instanceof OutOfMemoryError) { // OOM should be handled manually - e.printStackTrace(); + LOGGER.error("OOM error", e); MinecraftServer.stopCleanly(); return; } diff --git a/src/main/java/net/minestom/server/extensions/DiscoveredExtension.java b/src/main/java/net/minestom/server/extensions/DiscoveredExtension.java new file mode 100644 index 00000000000..1239990db64 --- /dev/null +++ b/src/main/java/net/minestom/server/extensions/DiscoveredExtension.java @@ -0,0 +1,236 @@ +package net.minestom.server.extensions; + +import com.google.gson.JsonObject; +import net.minestom.server.utils.validate.Check; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.net.URL; +import java.nio.file.Path; +import java.util.LinkedList; +import java.util.List; + +/** + * Represents an extension from an `extension.json` that is capable of powering an Extension object. + * + * This has no constructor as its properties are set via GSON. + */ +public final class DiscoveredExtension { + /** Static logger for this class. */ + public static final Logger LOGGER = LoggerFactory.getLogger(DiscoveredExtension.class); + + /** The regex that this name must pass. If it doesn't, it will not be accepted. */ + public static final String NAME_REGEX = "[A-Za-z][_A-Za-z0-9]+"; + + /** Name of the DiscoveredExtension. Unique for all extensions. */ + private String name; + + /** Main class of this DiscoveredExtension, must extend Extension. */ + private String entrypoint; + + /** Version of this extension, highly reccomended to set it. */ + private String version; + + /** People who have made this extension. */ + private String[] authors; + + /** List of extension names that this depends on. */ + private String[] dependencies; + + /** List of Repositories and URLs that this depends on. */ + private ExternalDependencies externalDependencies; + + /** + * Extra meta on the object. + * Do NOT use as configuration: + * + * Meta is meant to handle properties that will + * be accessed by other extensions, not accessed by itself + */ + private JsonObject meta; + + /** All files of this extension */ + transient List files = new LinkedList<>(); + + /** The load status of this extension -- LOAD_SUCCESS is the only good one. */ + transient LoadStatus loadStatus = LoadStatus.LOAD_SUCCESS; + + /** The original jar this is from. */ + transient private File originalJar; + + transient private Path dataDirectory; + + /** The class loader that powers it. */ + transient private ExtensionClassLoader classLoader; + + @NotNull + public String getName() { + return name; + } + + @NotNull + public String getEntrypoint() { + return entrypoint; + } + + @NotNull + public String getVersion() { + return version; + } + + @NotNull + public String[] getAuthors() { + return authors; + } + + @NotNull + public String[] getDependencies() { + return dependencies; + } + + @NotNull + public ExternalDependencies getExternalDependencies() { + return externalDependencies; + } + + public void setOriginalJar(@Nullable File file) { + originalJar = file; + } + + @Nullable + public File getOriginalJar() { + return originalJar; + } + + public @NotNull Path getDataDirectory() { + return dataDirectory; + } + + public void setDataDirectory(@NotNull Path dataDirectory) { + this.dataDirectory = dataDirectory; + } + + void createClassLoader() { + Check.stateCondition(classLoader != null, "Extension classloader has already been created"); + final URL[] urls = this.files.toArray(new URL[0]); + classLoader = new ExtensionClassLoader(this.getName(), urls, this); + } + + @NotNull + public ExtensionClassLoader getClassLoader() { + return classLoader; + } + + /** + * Ensures that all properties of this extension are properly set if they aren't + * + * @param extension The extension to verify + */ + public static void verifyIntegrity(@NotNull DiscoveredExtension extension) { + if (extension.name == null) { + StringBuilder fileList = new StringBuilder(); + for (URL f : extension.files) { + fileList.append(f.toExternalForm()).append(", "); + } + LOGGER.error("Extension with no name. (at {}})", fileList); + LOGGER.error("Extension at ({}) will not be loaded.", fileList); + extension.loadStatus = DiscoveredExtension.LoadStatus.INVALID_NAME; + + // To ensure @NotNull: name = INVALID_NAME + extension.name = extension.loadStatus.name(); + return; + } + + if (!extension.name.matches(NAME_REGEX)) { + LOGGER.error("Extension '{}' specified an invalid name.", extension.name); + LOGGER.error("Extension '{}' will not be loaded.", extension.name); + extension.loadStatus = DiscoveredExtension.LoadStatus.INVALID_NAME; + + // To ensure @NotNull: name = INVALID_NAME + extension.name = extension.loadStatus.name(); + return; + } + + if (extension.entrypoint == null) { + LOGGER.error("Extension '{}' did not specify an entry point (via 'entrypoint').", extension.name); + LOGGER.error("Extension '{}' will not be loaded.", extension.name); + extension.loadStatus = DiscoveredExtension.LoadStatus.NO_ENTRYPOINT; + + // To ensure @NotNull: entrypoint = NO_ENTRYPOINT + extension.entrypoint = extension.loadStatus.name(); + return; + } + + // Handle defaults + // If we reach this code, then the extension will most likely be loaded: + if (extension.version == null) { + LOGGER.warn("Extension '{}' did not specify a version.", extension.name); + LOGGER.warn("Extension '{}' will continue to load but should specify a plugin version.", extension.name); + extension.version = "Unspecified"; + } + + if (extension.authors == null) { + extension.authors = new String[0]; + } + + // No dependencies were specified + if (extension.dependencies == null) { + extension.dependencies = new String[0]; + } + + // No external dependencies were specified; + if (extension.externalDependencies == null) { + extension.externalDependencies = new ExternalDependencies(); + } + + // No meta was provided + if (extension.meta == null) { + extension.meta = new JsonObject(); + } + + } + + @NotNull + public JsonObject getMeta() { + return meta; + } + + /** + * The status this extension has, all are breakpoints. + * + * LOAD_SUCCESS is the only valid one. + */ + enum LoadStatus { + LOAD_SUCCESS("Actually, it did not fail. This message should not have been printed."), + MISSING_DEPENDENCIES("Missing dependencies, check your logs."), + INVALID_NAME("Invalid name."), + NO_ENTRYPOINT("No entrypoint specified."), + FAILED_TO_SETUP_CLASSLOADER("Extension classloader could not be setup."), + LOAD_FAILED("Load failed. See logs for more information."), + ; + + private final String message; + + LoadStatus(@NotNull String message) { + this.message = message; + } + + @NotNull + public String getMessage() { + return message; + } + } + + public static final class ExternalDependencies { + Repository[] repositories = new Repository[0]; + String[] artifacts = new String[0]; + + public static class Repository { + String name = ""; + String url = ""; + } + } +} diff --git a/src/main/java/net/minestom/server/extensions/Extension.java b/src/main/java/net/minestom/server/extensions/Extension.java new file mode 100644 index 00000000000..020f229cb22 --- /dev/null +++ b/src/main/java/net/minestom/server/extensions/Extension.java @@ -0,0 +1,193 @@ +package net.minestom.server.extensions; + +import net.kyori.adventure.text.logger.slf4j.ComponentLogger; +import net.minestom.server.event.Event; +import net.minestom.server.event.EventNode; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.HashSet; +import java.util.Set; + +public abstract class Extension { + /** + * List of extensions that depend on this extension. + */ + protected final Set dependents = new HashSet<>(); + + protected Extension() { + + } + + public void preInitialize() { + + } + + public abstract void initialize(); + + public void postInitialize() { + + } + + public void preTerminate() { + + } + + public abstract void terminate(); + + public void postTerminate() { + + } + + ExtensionClassLoader getExtensionClassLoader() { + if (getClass().getClassLoader() instanceof ExtensionClassLoader extensionClassLoader) { + return extensionClassLoader; + } + throw new IllegalStateException("Extension class loader is not an ExtensionClassLoader"); + } + + @NotNull + public DiscoveredExtension getOrigin() { + return getExtensionClassLoader().getDiscoveredExtension(); + } + + /** + * Gets the logger for the extension + * + * @return The logger for the extension + */ + @NotNull + public ComponentLogger getLogger() { + return getExtensionClassLoader().getLogger(); + } + + public @NotNull EventNode getEventNode() { + return getExtensionClassLoader().getEventNode(); + } + + public @NotNull Path getDataDirectory() { + return getOrigin().getDataDirectory(); + } + + /** + * Gets a resource from the extension directory, or from inside the jar if it does not + * exist in the extension directory. + *

+ * If it does not exist in the extension directory, it will be copied from inside the jar. + *

+ * The caller is responsible for closing the returned {@link InputStream}. + * + * @param fileName The file to read + * @return The file contents, or null if there was an issue reading the file. + */ + public @Nullable InputStream getResource(@NotNull String fileName) { + return getResource(Paths.get(fileName)); + } + + /** + * Gets a resource from the extension directory, or from inside the jar if it does not + * exist in the extension directory. + *

+ * If it does not exist in the extension directory, it will be copied from inside the jar. + *

+ * The caller is responsible for closing the returned {@link InputStream}. + * + * @param target The file to read + * @return The file contents, or null if there was an issue reading the file. + */ + public @Nullable InputStream getResource(@NotNull Path target) { + final Path targetFile = getDataDirectory().resolve(target); + try { + // Copy from jar if the file does not exist in the extension data directory. + if (!Files.exists(targetFile)) { + savePackagedResource(target); + } + + return Files.newInputStream(targetFile); + } catch (IOException ex) { + getLogger().info("Failed to read resource {}.", target, ex); + return null; + } + } + + /** + * Gets a resource from inside the extension jar. + *

+ * The caller is responsible for closing the returned {@link InputStream}. + * + * @param fileName The file to read + * @return The file contents, or null if there was an issue reading the file. + */ + public @Nullable InputStream getPackagedResource(@NotNull String fileName) { + try { + final URL url = getOrigin().getClassLoader().getResource(fileName); + if (url == null) { + getLogger().debug("Resource not found: {}", fileName); + return null; + } + + return url.openConnection().getInputStream(); + } catch (IOException ex) { + getLogger().debug("Failed to load resource {}.", fileName, ex); + return null; + } + } + + /** + * Gets a resource from inside the extension jar. + *

+ * The caller is responsible for closing the returned {@link InputStream}. + * + * @param target The file to read + * @return The file contents, or null if there was an issue reading the file. + */ + public @Nullable InputStream getPackagedResource(@NotNull Path target) { + return getPackagedResource(target.toString().replace('\\', '/')); + } + + /** + * Copies a resource file to the extension directory, replacing any existing copy. + * + * @param fileName The resource to save + * @return True if the resource was saved successfully, null otherwise + */ + public boolean savePackagedResource(@NotNull String fileName) { + return savePackagedResource(Paths.get(fileName)); + } + + /** + * Copies a resource file to the extension directory, replacing any existing copy. + * + * @param target The resource to save + * @return True if the resource was saved successfully, null otherwise + */ + public boolean savePackagedResource(@NotNull Path target) { + final Path targetFile = getDataDirectory().resolve(target); + try (InputStream is = getPackagedResource(target)) { + if (is == null) { + return false; + } + + Files.createDirectories(targetFile.getParent()); + Files.copy(is, targetFile, StandardCopyOption.REPLACE_EXISTING); + return true; + } catch (IOException ex) { + getLogger().debug("Failed to save resource {}.", target, ex); + return false; + } + } + + /** + * @return A modifiable list of dependents. + */ + public Set getDependents() { + return dependents; + } +} diff --git a/src/main/java/net/minestom/server/extensions/ExtensionClassLoader.java b/src/main/java/net/minestom/server/extensions/ExtensionClassLoader.java new file mode 100644 index 00000000000..dd96f46af26 --- /dev/null +++ b/src/main/java/net/minestom/server/extensions/ExtensionClassLoader.java @@ -0,0 +1,91 @@ +package net.minestom.server.extensions; + +import net.kyori.adventure.text.logger.slf4j.ComponentLogger; +import net.minestom.server.MinecraftServer; +import net.minestom.server.event.Event; +import net.minestom.server.event.EventNode; +import org.jetbrains.annotations.NotNull; + +import java.io.InputStream; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.List; + +public final class ExtensionClassLoader extends URLClassLoader { + private final List children = new ArrayList<>(); + private final DiscoveredExtension discoveredExtension; + private EventNode eventNode; + private ComponentLogger logger; + + public ExtensionClassLoader(String name, URL[] urls, DiscoveredExtension discoveredExtension) { + super("Ext_" + name, urls, MinecraftServer.class.getClassLoader()); + this.discoveredExtension = discoveredExtension; + } + + public ExtensionClassLoader(String name, URL[] urls, ClassLoader parent, DiscoveredExtension discoveredExtension) { + super("Ext_" + name, urls, parent); + this.discoveredExtension = discoveredExtension; + } + + @Override + public void addURL(@NotNull URL url) { + super.addURL(url); + } + + public void addChild(@NotNull ExtensionClassLoader loader) { + children.add(loader); + } + + @Override + protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + try { + return super.loadClass(name, resolve); + } catch (ClassNotFoundException e) { + for (ExtensionClassLoader child : children) { + try { + return child.loadClass(name, resolve); + } catch (ClassNotFoundException ignored) {} + } + throw e; + } + } + + public InputStream getResourceAsStreamWithChildren(@NotNull String name) { + InputStream in = getResourceAsStream(name); + if (in != null) return in; + + for (ExtensionClassLoader child : children) { + InputStream childInput = child.getResourceAsStreamWithChildren(name); + if (childInput != null) + return childInput; + } + + return null; + } + + public DiscoveredExtension getDiscoveredExtension() { + return discoveredExtension; + } + + public EventNode getEventNode() { + if (eventNode == null) { + eventNode = EventNode.all(discoveredExtension.getName()); + MinecraftServer.getGlobalEventHandler().addChild(eventNode); + } + return eventNode; + } + + public ComponentLogger getLogger() { + if (logger == null) { + logger = ComponentLogger.logger(discoveredExtension.getName()); + } + return logger; + } + + void terminate() { + if (eventNode != null) { + MinecraftServer.getGlobalEventHandler().removeChild(eventNode); + } + } +} diff --git a/src/main/java/net/minestom/server/extensions/ExtensionManager.java b/src/main/java/net/minestom/server/extensions/ExtensionManager.java new file mode 100644 index 00000000000..6985fb8baa6 --- /dev/null +++ b/src/main/java/net/minestom/server/extensions/ExtensionManager.java @@ -0,0 +1,712 @@ +package net.minestom.server.extensions; + +import com.google.gson.Gson; +import net.minestom.server.ServerProcess; +import net.minestom.server.utils.validate.Check; +import org.apache.maven.repository.internal.MavenRepositorySystemUtils; +import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.impl.DefaultServiceLocator; +import org.eclipse.aether.repository.LocalRepository; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.repository.RepositoryPolicy; +import org.eclipse.aether.resolution.DependencyRequest; +import org.eclipse.aether.resolution.DependencyResolutionException; +import org.eclipse.aether.resolution.DependencyResult; +import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; +import org.eclipse.aether.spi.connector.transport.TransporterFactory; +import org.eclipse.aether.transfer.AbstractTransferListener; +import org.eclipse.aether.transfer.TransferCancelledException; +import org.eclipse.aether.transfer.TransferEvent; +import org.eclipse.aether.transport.http.HttpTransporterFactory; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.net.MalformedURLException; +import java.nio.file.Path; +import java.util.*; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +public class ExtensionManager { + + public final static Logger LOGGER = LoggerFactory.getLogger(ExtensionManager.class); + + public static final String INDEV_CLASSES_FOLDER = "minestom.extension.indevfolder.classes"; + public static final String INDEV_RESOURCES_FOLDER = "minestom.extension.indevfolder.resources"; + private static final Gson GSON = new Gson(); + + private final ServerProcess serverProcess; + + // LinkedHashMaps are HashMaps that preserve order + private final Map extensions = new LinkedHashMap<>(); + private final Map immutableExtensions = Collections.unmodifiableMap(extensions); + + private final File extensionFolder = new File(System.getProperty("minestom.extension.folder", "extensions")); + private Path extensionDataRoot = extensionFolder.toPath(); + + private enum State {DO_NOT_START, NOT_STARTED, STARTED, PRE_INIT, INIT, POST_INIT} + private State state = State.NOT_STARTED; + + private final RepositorySystem repository; + private final DefaultRepositorySystemSession session; + private final List repositories = new ArrayList<>(); + private final List dependencies = new ArrayList<>(); + + + public ExtensionManager(ServerProcess serverProcess) { + this.serverProcess = serverProcess; + DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator(); + locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class); + locator.addService(TransporterFactory.class, HttpTransporterFactory.class); + this.repository = locator.getService(RepositorySystem.class); + this.session = MavenRepositorySystemUtils.newSession(); + + this.session.setSystemProperties(System.getProperties()); + this.session.setChecksumPolicy(RepositoryPolicy.CHECKSUM_POLICY_FAIL); + this.session.setLocalRepositoryManager(this.repository.newLocalRepositoryManager(this.session, new LocalRepository("libraries"))); + this.session.setTransferListener(new AbstractTransferListener() { + @Override + public void transferInitiated(@NotNull TransferEvent event) throws TransferCancelledException { + LOGGER.info("Downloading {}", event.getResource().getRepositoryUrl() + event.getResource().getResourceName()); + } + }); + this.session.setReadOnly(); + } + + /** + * Gets if the extensions should be loaded during startup. + *

+ * Default value is 'true'. + * + * @return true if extensions are loaded in {@link net.minestom.server.MinecraftServer#start(java.net.SocketAddress)} + */ + public boolean shouldLoadOnStartup() { + return state != State.DO_NOT_START; + } + + /** + * Used to specify if you want extensions to be loaded and initialized during startup. + *

+ * Only useful before the server start. + * + * @param loadOnStartup true to load extensions on startup, false to do nothing + */ + public void setLoadOnStartup(boolean loadOnStartup) { + Check.stateCondition(state.ordinal() > State.NOT_STARTED.ordinal(), "Extensions have already been initialized"); + this.state = loadOnStartup ? State.NOT_STARTED : State.DO_NOT_START; + } + + @NotNull + public File getExtensionFolder() { + return extensionFolder; + } + + public @NotNull Path getExtensionDataRoot() { + return extensionDataRoot; + } + + public void setExtensionDataRoot(@NotNull Path dataRoot) { + this.extensionDataRoot = dataRoot; + } + + @NotNull + public Collection getExtensions() { + return immutableExtensions.values(); + } + + @Nullable + public Extension getExtension(@NotNull String name) { + return extensions.get(name.toLowerCase()); + } + + public boolean hasExtension(@NotNull String name) { + return extensions.containsKey(name); + } + + // + // Init phases + // + + @ApiStatus.Internal + public void start() { + if (state == State.DO_NOT_START) { + LOGGER.warn("Extension loadOnStartup option is set to false, extensions are therefore neither loaded or initialized."); + return; + } + Check.stateCondition(state != State.NOT_STARTED, "ExtensionManager has already been started"); + loadExtensions(); + state = State.STARTED; + } + + @ApiStatus.Internal + public void gotoPreInit() { + if (state == State.DO_NOT_START) return; + Check.stateCondition(state != State.STARTED, "Extensions have already done pre initialization"); + extensions.values().forEach(Extension::preInitialize); + state = State.PRE_INIT; + } + + @ApiStatus.Internal + public void gotoInit() { + if (state == State.DO_NOT_START) return; + Check.stateCondition(state != State.PRE_INIT, "Extensions have already done initialization"); + extensions.values().forEach(Extension::initialize); + state = State.INIT; + } + + @ApiStatus.Internal + public void gotoPostInit() { + if (state == State.DO_NOT_START) return; + Check.stateCondition(state != State.INIT, "Extensions have already done post initialization"); + extensions.values().forEach(Extension::postInitialize); + state = State.POST_INIT; + } + + // + // Loading + // + + /** + * Loads all extensions in the extension folder into this server. + *

+ *

+ * Pipeline: + *
+ * Finds all .jar files in the extensions folder. + *
+ * Per each jar: + *
+ * Turns its extension.json into a DiscoveredExtension object. + *
+ * Verifies that all properties of extension.json are correctly set. + *

+ *

+ * It then sorts all those jars by their load order (making sure that an extension's dependencies load before it) + *
+ * Note: Cyclic dependencies will stop both extensions from being loaded. + *

+ *

+ * Afterwards, it loads all external dependencies and adds them to the extension's files + *

+ *

+ * Then removes any invalid extensions (Invalid being its Load Status isn't SUCCESS) + *

+ *

+ * After that, it set its classloaders so each extension is self-contained, + *

+ *

+ * Removes invalid extensions again, + *

+ *

+ * and loads all of those extensions into Minestom + *
+ * (Extension fields are set via reflection after each extension is verified, then loaded.) + *

+ *

+ * If the extension successfully loads, add it to the global extension Map (Name to Extension) + *

+ *

+ * And finally make a scheduler to clean observers per extension. + */ + private void loadExtensions() { + // Load extensions + { + // Get all extensions and order them accordingly. + List discoveredExtensions = discoverExtensions(); + + // Don't waste resources on doing extra actions if there is nothing to do. + if (discoveredExtensions.isEmpty()) return; + + // Create classloaders for each extension (so that they can be used during dependency resolution) + Iterator extensionIterator = discoveredExtensions.iterator(); + while (extensionIterator.hasNext()) { + DiscoveredExtension discoveredExtension = extensionIterator.next(); + try { + discoveredExtension.createClassLoader(); + } catch (Exception e) { + discoveredExtension.loadStatus = DiscoveredExtension.LoadStatus.FAILED_TO_SETUP_CLASSLOADER; + serverProcess.exception().handleException(e); + LOGGER.error("Failed to load extension {}", discoveredExtension.getName()); + LOGGER.error("Failed to load extension", e); + extensionIterator.remove(); + } + } + + discoveredExtensions = generateLoadOrder(discoveredExtensions); + loadDependencies(discoveredExtensions); + + // remove invalid extensions + discoveredExtensions.removeIf(ext -> ext.loadStatus != DiscoveredExtension.LoadStatus.LOAD_SUCCESS); + + // Load the extensions + for (DiscoveredExtension discoveredExtension : discoveredExtensions) { + try { + loadExtension(discoveredExtension); + } catch (Exception e) { + discoveredExtension.loadStatus = DiscoveredExtension.LoadStatus.LOAD_FAILED; + LOGGER.error("Failed to load extension {}", discoveredExtension.getName()); + serverProcess.exception().handleException(e); + } + } + } + } + + public boolean loadDynamicExtension(@NotNull File jarFile) throws FileNotFoundException { + if (!jarFile.exists()) { + throw new FileNotFoundException("File '" + jarFile.getAbsolutePath() + "' does not exists. Cannot load extension."); + } + + LOGGER.info("Discover dynamic extension from jar {}", jarFile.getAbsolutePath()); + DiscoveredExtension discoveredExtension = discoverFromJar(jarFile); + List extensionsToLoad = Collections.singletonList(discoveredExtension); + return loadExtensionList(extensionsToLoad); + } + + /** + * Loads an extension into Minestom. + * + * @param discoveredExtension The extension. Make sure to verify its integrity, set its class loader, and its files. + * @return An extension object made from this DiscoveredExtension + */ + @Nullable + private Extension loadExtension(@NotNull DiscoveredExtension discoveredExtension) { + // Create Extension (authors, version etc.) + String extensionName = discoveredExtension.getName(); + String mainClass = discoveredExtension.getEntrypoint(); + + ExtensionClassLoader loader = discoveredExtension.getClassLoader(); + + if (extensions.containsKey(extensionName.toLowerCase())) { + LOGGER.error("An extension called '{}' has already been registered.", extensionName); + return null; + } + + Class jarClass; + try { + jarClass = Class.forName(mainClass, true, loader); + } catch (ClassNotFoundException e) { + LOGGER.error("Could not find main class '{}' in extension '{}'.", + mainClass, extensionName, e); + return null; + } + + Class extensionClass; + try { + extensionClass = jarClass.asSubclass(Extension.class); + } catch (ClassCastException e) { + LOGGER.error("Main class '{}' in '{}' does not extend the 'Extension' superclass.", mainClass, extensionName, e); + return null; + } + + Constructor constructor; + try { + constructor = extensionClass.getDeclaredConstructor(); + // Let's just make it accessible, plugin creators don't have to make this public. + constructor.setAccessible(true); + } catch (NoSuchMethodException e) { + LOGGER.error("Main class '{}' in '{}' does not define a no-args constructor.", mainClass, extensionName, e); + return null; + } + Extension extension = null; + try { + extension = constructor.newInstance(); + } catch (InstantiationException e) { + LOGGER.error("Main class '{}' in '{}' cannot be an abstract class.", mainClass, extensionName, e); + return null; + } catch (IllegalAccessException ignored) { + // We made it accessible, should not occur + } catch (InvocationTargetException e) { + LOGGER.error( + "While instantiating the main class '{}' in '{}' an exception was thrown.", + mainClass, + extensionName, + e.getTargetException() + ); + return null; + } + + // add dependents to pre-existing extensions, so that they can easily be found during reloading + for (String dependencyName : discoveredExtension.getDependencies()) { + Extension dependency = extensions.get(dependencyName.toLowerCase()); + if (dependency == null) { + LOGGER.warn("Dependency {} of {} is null? This means the extension has been loaded without its dependency, which could cause issues later.", dependencyName, discoveredExtension.getName()); + } else { + dependency.getDependents().add(discoveredExtension.getName()); + } + } + + // add to a linked hash map, as they preserve order + extensions.put(extensionName.toLowerCase(), extension); + + return extension; + } + + /** + * Get all extensions from the extensions folder and make them discovered. + *

+ * It skims the extension folder, discovers and verifies each extension, and returns those created DiscoveredExtensions. + * + * @return A list of discovered extensions from this folder. + */ + private @NotNull List discoverExtensions() { + List extensions = new LinkedList<>(); + + File[] fileList = extensionFolder.listFiles(); + + if (fileList != null) { + // Loop through all files in extension folder + for (File file : fileList) { + + // Ignore folders + if (file.isDirectory()) { + continue; + } + + // Ignore non .jar files + if (!file.getName().endsWith(".jar")) { + continue; + } + + DiscoveredExtension extension = discoverFromJar(file); + if (extension != null && extension.loadStatus == DiscoveredExtension.LoadStatus.LOAD_SUCCESS) { + extensions.add(extension); + } + } + } + + //TODO(mattw): Extract this into its own method to load an extension given classes and resources directory. + //TODO(mattw): Should show a warning if one is set and not the other. It is most likely a mistake. + + // this allows developers to have their extension discovered while working on it, without having to build a jar and put in the extension folder + if (System.getProperty(INDEV_CLASSES_FOLDER) != null && System.getProperty(INDEV_RESOURCES_FOLDER) != null) { + LOGGER.info("Found indev folders for extension. Adding to list of discovered extensions."); + final String extensionClasses = System.getProperty(INDEV_CLASSES_FOLDER); + final String extensionResources = System.getProperty(INDEV_RESOURCES_FOLDER); + try (InputStreamReader reader = new InputStreamReader(new FileInputStream(new File(extensionResources, "extension.json")))) { + DiscoveredExtension extension = GSON.fromJson(reader, DiscoveredExtension.class); + extension.files.add(new File(extensionClasses).toURI().toURL()); + extension.files.add(new File(extensionResources).toURI().toURL()); + extension.setDataDirectory(getExtensionDataRoot().resolve(extension.getName())); + + // Verify integrity and ensure defaults + DiscoveredExtension.verifyIntegrity(extension); + + if (extension.loadStatus == DiscoveredExtension.LoadStatus.LOAD_SUCCESS) { + extensions.add(extension); + } + } catch (IOException e) { + serverProcess.exception().handleException(e); + } + } + return extensions; + } + + /** + * Grabs a discovered extension from a jar. + * + * @param file The jar to grab it from (a .jar is a formatted .zip file) + * @return The created DiscoveredExtension. + */ + private @Nullable DiscoveredExtension discoverFromJar(@NotNull File file) { + try (ZipFile f = new ZipFile(file)) { + + ZipEntry entry = f.getEntry("extension.json"); + + if (entry == null) + throw new IllegalStateException("Missing extension.json in extension " + file.getName() + "."); + + InputStreamReader reader = new InputStreamReader(f.getInputStream(entry)); + + // Initialize DiscoveredExtension from GSON. + DiscoveredExtension extension = GSON.fromJson(reader, DiscoveredExtension.class); + extension.setOriginalJar(file); + extension.files.add(file.toURI().toURL()); + extension.setDataDirectory(getExtensionDataRoot().resolve(extension.getName())); + + // Verify integrity and ensure defaults + DiscoveredExtension.verifyIntegrity(extension); + + return extension; + } catch (IOException e) { + serverProcess.exception().handleException(e); + return null; + } + } + + @NotNull + private List generateLoadOrder(@NotNull List discoveredExtensions) { + // Extension --> Extensions it depends on. + Map> dependencyMap = new HashMap<>(); + + // Put dependencies in dependency map + { + Map extensionMap = new HashMap<>(); + + // go through all the discovered extensions and assign their name in a map. + for (DiscoveredExtension discoveredExtension : discoveredExtensions) { + extensionMap.put(discoveredExtension.getName().toLowerCase(), discoveredExtension); + } + + allExtensions: + // go through all the discovered extensions and get their dependencies as extensions + for (DiscoveredExtension discoveredExtension : discoveredExtensions) { + + List dependencies = new ArrayList<>(discoveredExtension.getDependencies().length); + + // Map the dependencies into DiscoveredExtensions. + for (String dependencyName : discoveredExtension.getDependencies()) { + + DiscoveredExtension dependencyExtension = extensionMap.get(dependencyName.toLowerCase()); + // Specifies an extension we don't have. + if (dependencyExtension == null) { + + // attempt to see if it is not already loaded (happens with dynamic (re)loading) + if (extensions.containsKey(dependencyName.toLowerCase())) { + + dependencies.add(extensions.get(dependencyName.toLowerCase()).getOrigin()); + continue; // Go to the next loop in this dependency loop, this iteration is done. + + } else { + + // dependency isn't loaded, move on. + LOGGER.error("Extension {} requires an extension called {}.", discoveredExtension.getName(), dependencyName); + LOGGER.error("However the extension {} could not be found.", dependencyName); + LOGGER.error("Therefore {} will not be loaded.", discoveredExtension.getName()); + discoveredExtension.loadStatus = DiscoveredExtension.LoadStatus.MISSING_DEPENDENCIES; + continue allExtensions; // the above labeled loop will go to the next extension as this dependency is invalid. + + } + } + // This will add null for an unknown-extension + dependencies.add(dependencyExtension); + + } + + dependencyMap.put( + discoveredExtension, + dependencies + ); + + } + } + + // List containing the load order. + LinkedList sortedList = new LinkedList<>(); + + // TODO actually have to read this + { + // entries with empty lists + List>> loadableExtensions; + + // While there are entries with no more elements (no more dependencies) + while (!( + loadableExtensions = dependencyMap.entrySet().stream().filter(entry -> isLoaded(entry.getValue())).toList() + ).isEmpty() + ) { + // Get all "loadable" (not actually being loaded!) extensions and put them in the sorted list. + for (var entry : loadableExtensions) { + // Add to sorted list. + sortedList.add(entry.getKey()); + // Remove to make the next iterations a little quicker (hopefully) and to find cyclic dependencies. + dependencyMap.remove(entry.getKey()); + + // Remove this dependency from all the lists (if they include it) to make way for next level of extensions. + for (var dependencies : dependencyMap.values()) { + dependencies.remove(entry.getKey()); + } + } + } + } + + // Check if there are cyclic extensions. + if (!dependencyMap.isEmpty()) { + LOGGER.error("Minestom found {} cyclic extensions.", dependencyMap.size()); + LOGGER.error("Cyclic extensions depend on each other and can therefore not be loaded."); + for (var entry : dependencyMap.entrySet()) { + DiscoveredExtension discoveredExtension = entry.getKey(); + LOGGER.error("{} could not be loaded, as it depends on: {}.", + discoveredExtension.getName(), + entry.getValue().stream().map(DiscoveredExtension::getName).collect(Collectors.joining(", "))); + } + + } + + return sortedList; + } + + /** + * Checks if this list of extensions are loaded + * + * @param extensions The list of extensions to check against. + * @return If all of these extensions are loaded. + */ + private boolean isLoaded(@NotNull List extensions) { + return + extensions.isEmpty() // Don't waste CPU on checking an empty array + // Make sure the internal extensions list contains all of these. + || extensions.stream().allMatch(ext -> this.extensions.containsKey(ext.getName().toLowerCase())); + } + + private void loadDependencies(@NotNull List extensions) { + List repos = this.repository.newResolutionRepositories(this.session, this.repositories); + List allLoadedExtensions = new LinkedList<>(extensions); + + for (Extension extension : immutableExtensions.values()) + allLoadedExtensions.add(extension.getOrigin()); + + for (DiscoveredExtension discoveredExtension : extensions) { + try { + + DiscoveredExtension.ExternalDependencies externalDependencies = discoveredExtension.getExternalDependencies(); + for (var repository : externalDependencies.repositories) { + + if (repository.name == null || repository.name.isEmpty()) { + throw new IllegalStateException("Missing 'name' element in repository object."); + } + + if (repository.url == null || repository.url.isEmpty()) { + throw new IllegalStateException("Missing 'url' element in repository object."); + } + repos.add(new RemoteRepository.Builder(repository.name, "default", repository.url).build()); + } + + for (String artifact : externalDependencies.artifacts) { + this.dependencies.add(new Dependency(new DefaultArtifact(artifact), null)); + } + + DependencyResult result; + try { + result = this.repository.resolveDependencies(this.session, new DependencyRequest(new CollectRequest((Dependency) null, this.dependencies, repos), null)); + } catch (DependencyResolutionException ex) { + throw new IllegalStateException("Error resolving libraries", ex); + } + LOGGER.trace("Dependency of extension {}: {}", discoveredExtension.getName(), result.toString()); + result.getArtifactResults().forEach(artifactResult -> { + try { + discoveredExtension.files.add(artifactResult.getArtifact().getFile().toURI().toURL()); + discoveredExtension.getClassLoader().addURL(artifactResult.getArtifact().getFile().toURI().toURL()); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + }); + ExtensionClassLoader extensionClassLoader = discoveredExtension.getClassLoader(); + for (String dependencyName : discoveredExtension.getDependencies()) { + var resolved = extensions.stream() + .filter(ext -> ext.getName().equalsIgnoreCase(dependencyName)) + .findFirst() + .orElseThrow(() -> new IllegalStateException("Unknown dependency '" + dependencyName + "' of '" + discoveredExtension.getName() + "'")); + + ExtensionClassLoader dependencyClassLoader = resolved.getClassLoader(); + + extensionClassLoader.addChild(dependencyClassLoader); + LOGGER.trace("Dependency of extension {}: {}", discoveredExtension.getName(), resolved); + } + } catch (Exception e) { + discoveredExtension.loadStatus = DiscoveredExtension.LoadStatus.MISSING_DEPENDENCIES; + LOGGER.error("Failed to load dependencies for extension {}", discoveredExtension.getName()); + LOGGER.error("Extension '{}' will not be loaded", discoveredExtension.getName()); + LOGGER.error("This is the exception", e); + } + } + } + + private boolean loadExtensionList(@NotNull List extensionsToLoad) { + // ensure correct order of dependencies + LOGGER.debug("Reorder extensions to ensure proper load order"); + extensionsToLoad = generateLoadOrder(extensionsToLoad); + loadDependencies(extensionsToLoad); + + // setup new classloaders for the extensions to reload + for (DiscoveredExtension toReload : extensionsToLoad) { + LOGGER.debug("Setting up classloader for extension {}", toReload.getName()); +// toReload.setMinestomExtensionClassLoader(toReload.makeClassLoader()); //TODO: Fix this + } + + List newExtensions = new LinkedList<>(); + for (DiscoveredExtension toReload : extensionsToLoad) { + // reload extensions + LOGGER.info("Actually load extension {}", toReload.getName()); + Extension loadedExtension = loadExtension(toReload); + if (loadedExtension != null) { + newExtensions.add(loadedExtension); + } + } + + if (newExtensions.isEmpty()) { + LOGGER.error("No extensions to load, skipping callbacks"); + return false; + } + + LOGGER.info("Load complete, firing preinit, init and then postinit callbacks"); + // retrigger preinit, init and postinit + newExtensions.forEach(Extension::preInitialize); + newExtensions.forEach(Extension::initialize); + newExtensions.forEach(Extension::postInitialize); + return true; + } + + // + // Shutdown / Unload + // + + /** + * Shutdowns all the extensions by unloading them. + */ + public void shutdown() {// copy names, as the extensions map will be modified via the calls to unload + Set extensionNames = new HashSet<>(extensions.keySet()); + for (String ext : extensionNames) { + if (extensions.containsKey(ext)) { // is still loaded? Because extensions can depend on one another, it might have already been unloaded + unloadExtension(ext); + } + } + } + + private void unloadExtension(@NotNull String extensionName) { + Extension ext = extensions.get(extensionName.toLowerCase()); + + if (ext == null) { + throw new IllegalArgumentException("Extension " + extensionName + " is not currently loaded."); + } + + List dependents = new LinkedList<>(ext.getDependents()); // copy dependents list + + for (String dependentID : dependents) { + Extension dependentExt = extensions.get(dependentID.toLowerCase()); + if (dependentExt != null) { // check if extension isn't already unloaded. + LOGGER.info("Unloading dependent extension {} (because it depends on {})", dependentID, extensionName); + unload(dependentExt); + } + } + + LOGGER.info("Unloading extension {}", extensionName); + unload(ext); + } + + private void unload(@NotNull Extension ext) { + ext.preTerminate(); + ext.terminate(); + + ext.getExtensionClassLoader().terminate(); + + ext.postTerminate(); + + // remove from loaded extensions + String id = ext.getOrigin().getName().toLowerCase(); + extensions.remove(id); + + // cleanup classloader + // TODO: Is it necessary to remove the CLs since this is only called on shutdown? + } +} diff --git a/src/main/java/net/minestom/server/extras/bungee/BungeeCordProxy.java b/src/main/java/net/minestom/server/extras/bungee/BungeeCordProxy.java index 82884558daa..cb3f1333df0 100644 --- a/src/main/java/net/minestom/server/extras/bungee/BungeeCordProxy.java +++ b/src/main/java/net/minestom/server/extras/bungee/BungeeCordProxy.java @@ -1,7 +1,5 @@ package net.minestom.server.extras.bungee; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/net/minestom/server/extras/velocity/VelocityProxy.java b/src/main/java/net/minestom/server/extras/velocity/VelocityProxy.java index 10e47b03da0..d965ae05d39 100644 --- a/src/main/java/net/minestom/server/extras/velocity/VelocityProxy.java +++ b/src/main/java/net/minestom/server/extras/velocity/VelocityProxy.java @@ -1,5 +1,6 @@ package net.minestom.server.extras.velocity; +import net.minestom.server.MinecraftServer; import net.minestom.server.extras.MojangAuth; import net.minestom.server.network.NetworkBuffer; import net.minestom.server.utils.validate.Check; @@ -66,7 +67,7 @@ public static boolean checkIntegrity(@NotNull NetworkBuffer buffer) { return false; } } catch (NoSuchAlgorithmException | InvalidKeyException e) { - e.printStackTrace(); + MinecraftServer.getExceptionManager().handleException(e); } final int version = buffer.read(VAR_INT); return version == SUPPORTED_FORWARDING_VERSION; diff --git a/src/main/java/net/minestom/server/fluid/Fluid.java b/src/main/java/net/minestom/server/fluid/Fluid.java new file mode 100644 index 00000000000..c9e6bedf370 --- /dev/null +++ b/src/main/java/net/minestom/server/fluid/Fluid.java @@ -0,0 +1,37 @@ +package net.minestom.server.fluid; + +import net.minestom.server.registry.Registry; +import net.minestom.server.registry.StaticProtocolObject; +import net.minestom.server.utils.NamespaceID; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +public sealed interface Fluid extends StaticProtocolObject, Fluids permits FluidImpl { + /** + * Returns the entity registry. + * + * @return the entity registry or null if it was created with a builder + */ + @Contract(pure = true) + @Nullable + Registry.FluidEntry registry(); + + @Override + @NotNull + NamespaceID namespace(); + + static @NotNull Collection<@NotNull Fluid> values() { + return FluidImpl.values(); + } + + static @Nullable Fluid fromNamespaceId(@NotNull String namespaceID) { + return FluidImpl.getSafe(namespaceID); + } + + static @Nullable Fluid fromNamespaceId(@NotNull NamespaceID namespaceID) { + return fromNamespaceId(namespaceID.asString()); + } +} diff --git a/src/main/java/net/minestom/server/fluid/FluidImpl.java b/src/main/java/net/minestom/server/fluid/FluidImpl.java new file mode 100644 index 00000000000..330108fefc3 --- /dev/null +++ b/src/main/java/net/minestom/server/fluid/FluidImpl.java @@ -0,0 +1,34 @@ +package net.minestom.server.fluid; + +import net.minestom.server.registry.Registry; +import net.minestom.server.utils.NamespaceID; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.concurrent.atomic.AtomicInteger; + +public record FluidImpl(Registry.FluidEntry registry, NamespaceID namespace, int id) implements Fluid { + + private static final AtomicInteger INDEX = new AtomicInteger(); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.FLUIDS, FluidImpl::createImpl); + + private static FluidImpl createImpl(String namespace, Registry.Properties properties) { + return new FluidImpl(Registry.fluidEntry(namespace, properties)); + } + + private FluidImpl(Registry.FluidEntry registry) { + this(registry, registry.namespace(), INDEX.getAndIncrement()); + } + + static Collection values() { + return CONTAINER.values(); + } + + public static Fluid get(@NotNull String namespace) { + return CONTAINER.get(namespace); + } + + static Fluid getSafe(@NotNull String namespace) { + return CONTAINER.getSafe(namespace); + } +} diff --git a/src/main/java/net/minestom/server/game/GameEvent.java b/src/main/java/net/minestom/server/game/GameEvent.java new file mode 100644 index 00000000000..86ddb2a8d35 --- /dev/null +++ b/src/main/java/net/minestom/server/game/GameEvent.java @@ -0,0 +1,69 @@ +package net.minestom.server.game; + +import net.minestom.server.registry.Registry; +import net.minestom.server.registry.StaticProtocolObject; +import net.minestom.server.utils.NamespaceID; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +/** + * Represents a game event. + * Used for a wide variety of events, from weather to bed use to game mode to demo messages. + * + * @version 1.0.0 + * @since 1.6.0 + * @author themeinerlp + */ +public sealed interface GameEvent extends StaticProtocolObject permits GameEventImpl { + + /** + * Returns the game event registry. + * + * @return the game event registry or null if not found + */ + @Contract(pure = true) + @Nullable + Registry.GameEventEntry registry(); + + /** + * Gets the namespace ID of this game event. + * + * @return the namespace ID + */ + @Override + @NotNull + NamespaceID namespace(); + + /** + * Gets the game events from the registry. + * + * @return the game events + */ + static @NotNull Collection<@NotNull GameEvent> values() { + return GameEventImpl.values(); + } + + /** + * Gets a game event by its namespace ID. + * + * @param namespaceID the namespace ID + * @return the game event or null if not found + */ + static @Nullable GameEvent fromNamespaceId(@NotNull String namespaceID) { + return GameEventImpl.getSafe(namespaceID); + } + + /** + * Gets a game event by its namespace ID. + * + * @param namespaceID the namespace ID + * @return the game event or null if not found + */ + static @Nullable GameEvent fromNamespaceId(@NotNull NamespaceID namespaceID) { + return fromNamespaceId(namespaceID.asString()); + } + +} \ No newline at end of file diff --git a/src/main/java/net/minestom/server/game/GameEventImpl.java b/src/main/java/net/minestom/server/game/GameEventImpl.java new file mode 100644 index 00000000000..e5ab9d437ab --- /dev/null +++ b/src/main/java/net/minestom/server/game/GameEventImpl.java @@ -0,0 +1,70 @@ +package net.minestom.server.game; + +import net.minestom.server.registry.Registry; +import net.minestom.server.utils.NamespaceID; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Represents a game event implementation. + * Used for a wide variety of events, from weather to bed use to game mode to demo messages. + * + * @version 1.0.0 + * @since 1.6.0 + * @author themeinerlp + */ +record GameEventImpl(Registry.GameEventEntry registry, NamespaceID namespace, int id) implements GameEvent { + private static final AtomicInteger INDEX = new AtomicInteger(); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.GAME_EVENTS, GameEventImpl::createImpl); + + /** + * Creates a new {@link GameEventImpl} with the given namespace and properties. + * + * @param namespace the namespace + * @param properties the properties + * @return a new {@link GameEventImpl} + */ + private static GameEventImpl createImpl(String namespace, Registry.Properties properties) { + return new GameEventImpl(Registry.gameEventEntry(namespace, properties)); + } + + /** + * Creates a new {@link GameEventImpl} with the given registry. + * + * @param registry the registry + */ + private GameEventImpl(Registry.GameEventEntry registry) { + this(registry, registry.namespace(), registry.main().getInt("id")); + } + + /** + * Gets the game events from the registry. + * + * @return the game events + */ + static Collection values() { + return CONTAINER.values(); + } + + /** + * Gets a game event by its namespace ID. + * + * @param namespace the namespace ID + * @return the game event or null if not found + */ + public static GameEvent get(@NotNull String namespace) { + return CONTAINER.get(namespace); + } + + /** + * Gets a game event by its namespace ID. + * + * @param namespace the namespace ID + * @return the game event or null if not found + */ + static GameEvent getSafe(@NotNull String namespace) { + return CONTAINER.getSafe(namespace); + } +} diff --git a/src/main/java/net/minestom/server/gamedata/tags/Tag.java b/src/main/java/net/minestom/server/gamedata/tags/Tag.java index 663f9a1299d..2984ffd0243 100644 --- a/src/main/java/net/minestom/server/gamedata/tags/Tag.java +++ b/src/main/java/net/minestom/server/gamedata/tags/Tag.java @@ -4,10 +4,11 @@ import net.kyori.adventure.key.Keyed; import net.minestom.server.MinecraftServer; import net.minestom.server.entity.EntityType; +import net.minestom.server.fluid.Fluid; +import net.minestom.server.game.GameEvent; import net.minestom.server.instance.block.Block; import net.minestom.server.item.Material; import net.minestom.server.registry.DynamicRegistry; -import net.minestom.server.registry.FluidRegistries; import net.minestom.server.registry.ProtocolObject; import net.minestom.server.registry.Registry; import net.minestom.server.utils.NamespaceID; @@ -17,7 +18,7 @@ import java.util.Collections; import java.util.HashSet; -import java.util.Objects; +import java.util.Optional; import java.util.Set; import java.util.function.Function; @@ -89,30 +90,31 @@ public NamespaceID getName() { public enum BasicType { BLOCKS("minecraft:block", Registry.Resource.BLOCK_TAGS, - name -> Objects.requireNonNull(Block.fromNamespaceId(name)).id()), + blockName -> Optional.ofNullable(Block.fromNamespaceId(blockName)).map(Block::id)), ITEMS("minecraft:item", Registry.Resource.ITEM_TAGS, - name -> Objects.requireNonNull(Material.fromNamespaceId(name)).id()), + itemName -> Optional.ofNullable(Material.fromNamespaceId(itemName)).map(Material::id)), FLUIDS("minecraft:fluid", Registry.Resource.FLUID_TAGS, - name -> FluidRegistries.getFluid(name).ordinal()), + fluidName -> Optional.ofNullable(Fluid.fromNamespaceId(fluidName)).map(Fluid::id)), + BIOMES("minecraft:worldgen/biome", Registry.Resource.BIOME_TAGS, + biomeName -> Optional.of(DynamicRegistry.Key.of(biomeName)).map(DynamicRegistry.Key::namespace).map(MinecraftServer.getBiomeRegistry()::getId)), ENTITY_TYPES("minecraft:entity_type", Registry.Resource.ENTITY_TYPE_TAGS, - name -> Objects.requireNonNull(EntityType.fromNamespaceId(name)).id()), + entityName -> Optional.ofNullable(EntityType.fromNamespaceId(entityName)).map(EntityType::id)), GAME_EVENTS("minecraft:game_event", Registry.Resource.GAMEPLAY_TAGS, - name -> FluidRegistries.getFluid(name).ordinal()), + eventName -> Optional.ofNullable(GameEvent.fromNamespaceId(eventName)).map(GameEvent::id)), SOUND_EVENTS("minecraft:sound_event", null, null), // Seems not to be included in server data POTION_EFFECTS("minecraft:sound_event", null, null), // Seems not to be included in server data - //todo this is cursed. it does not update as the registry changes. Fix later. ENCHANTMENTS("minecraft:enchantment", Registry.Resource.ENCHANTMENT_TAGS, - name -> MinecraftServer.getEnchantmentRegistry().getId(DynamicRegistry.Key.of(name))); + enchName -> Optional.of(DynamicRegistry.Key.of(enchName)).map(DynamicRegistry.Key::namespace).map(MinecraftServer.getEnchantmentRegistry()::getId)),; - private final static BasicType[] VALUES = values(); + private static final BasicType[] VALUES = values(); private final String identifier; private final Registry.Resource resource; - private final Function function; + private final Function> function; BasicType(@NotNull String identifier, @Nullable Registry.Resource resource, - @Nullable Function function) { + @Nullable Function> function) { this.identifier = identifier; this.resource = resource; this.function = function; @@ -126,7 +128,7 @@ public Registry.Resource getResource() { return resource; } - public Function getFunction() { + public Function> getFunction() { return function; } diff --git a/src/main/java/net/minestom/server/instance/Explosion.java b/src/main/java/net/minestom/server/instance/Explosion.java index 186be7a1da3..1a5467cce1f 100644 --- a/src/main/java/net/minestom/server/instance/Explosion.java +++ b/src/main/java/net/minestom/server/instance/Explosion.java @@ -1,6 +1,9 @@ package net.minestom.server.instance; +import net.minestom.server.ServerFlag; import net.minestom.server.coordinate.Point; +import net.minestom.server.coordinate.Pos; +import net.minestom.server.entity.Player; import net.minestom.server.instance.block.Block; import net.minestom.server.network.packet.server.play.ExplosionPacket; import net.minestom.server.utils.PacketUtils; @@ -19,7 +22,7 @@ public abstract class Explosion { private final float centerZ; private final float strength; - public Explosion(float centerX, float centerY, float centerZ, float strength) { + protected Explosion(float centerX, float centerY, float centerZ, float strength) { //Microtus - update java keyword usage this.centerX = centerX; this.centerY = centerY; this.centerZ = centerZ; @@ -69,11 +72,14 @@ public void apply(@NotNull Instance instance) { records[i * 3 + 2] = z; } - // TODO send only to close players ExplosionPacket packet = new ExplosionPacket(centerX, centerY, centerZ, strength, records, 0, 0, 0); postExplosion(instance, blocks, packet); - PacketUtils.sendGroupedPacket(instance.getPlayers(), packet); + List players = instance.getNearbyEntities(new Pos(centerX, centerY, centerZ), ServerFlag.EXPLOSION_SEND_DISTANCE) + .stream() + .filter(Player.class::isInstance) + .map(Player.class::cast).toList(); + PacketUtils.sendGroupedPacket(players, packet); postSend(instance, blocks); } diff --git a/src/main/java/net/minestom/server/instance/Instance.java b/src/main/java/net/minestom/server/instance/Instance.java index bccaada7eca..cb05bee3566 100644 --- a/src/main/java/net/minestom/server/instance/Instance.java +++ b/src/main/java/net/minestom/server/instance/Instance.java @@ -13,6 +13,7 @@ import net.minestom.server.adventure.AdventurePacketConvertor; import net.minestom.server.adventure.audience.PacketGroupingAudience; import net.minestom.server.coordinate.Point; +import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.Entity; import net.minestom.server.entity.EntityCreature; import net.minestom.server.entity.ExperienceOrb; @@ -22,6 +23,7 @@ import net.minestom.server.event.EventHandler; import net.minestom.server.event.EventNode; import net.minestom.server.event.instance.InstanceTickEvent; +import net.minestom.server.event.instance.InstanceWorldPositionChangeEvent; import net.minestom.server.event.trait.InstanceEvent; import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.BlockFace; @@ -31,6 +33,7 @@ import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.play.BlockActionPacket; import net.minestom.server.network.packet.server.play.InitializeWorldBorderPacket; +import net.minestom.server.network.packet.server.play.SpawnPositionPacket; import net.minestom.server.network.packet.server.play.TimeUpdatePacket; import net.minestom.server.registry.DynamicRegistry; import net.minestom.server.snapshot.*; @@ -116,6 +119,8 @@ public abstract class Instance implements Block.Getter, Block.Setter, // Adventure private final Pointers pointers; + private Pos worldSpawnPosition = Pos.ZERO; + /** * Creates a new instance. * @@ -434,16 +439,43 @@ public long getWorldAge() { return worldAge; } + //Microtus start - integrate world spawn position /** - * Sets the age of this instance in tick. It will send the age to all players. - * Will send new age to all players in the instance, unaffected by {@link #getTimeSynchronizationTicks()} - * - * @param worldAge the age of this instance in tick + * Updates the spawn position of the instance. + * This method doesn't send the SpawnPositionPacket to the players. + * @param spawnPosition the new spawn position */ - public void setWorldAge(long worldAge) { - this.worldAge = worldAge; - PacketUtils.sendGroupedPacket(getPlayers(), createTimePacket()); + public boolean setWorldSpawnPosition(@NotNull Pos spawnPosition) { + return this.setWorldSpawnPosition(spawnPosition, false); + } + + /** + * Updates the spawn position of the instance. + * The underlying spawn position will only be updated if the new position is different from the current one. + * It sends the SpawnPositionPacket when the boolean option is true and the instance has players. + * @param spawnPosition the new spawn position + * @param sendPacket if true, the new spawn position will be sent to all players in the instance + */ + public boolean setWorldSpawnPosition(@NotNull Pos spawnPosition, boolean sendPacket) { + if (this.worldSpawnPosition.samePoint(spawnPosition)) return false; + final Pos oldPosition = this.worldSpawnPosition; + this.worldSpawnPosition = spawnPosition; + EventDispatcher.call(new InstanceWorldPositionChangeEvent(this, oldPosition)); + if (!sendPacket || getPlayers().isEmpty()) return false; + var spawnPositionPacket = new SpawnPositionPacket(spawnPosition, spawnPosition.yaw()); + PacketUtils.sendGroupedPacket(getPlayers(), spawnPositionPacket); + return true; + } + + /** + * Gets the spawn position of the instance. + * If the position is not set, it will return {@link Pos#ZERO} + * @return the spawn position of the instance + */ + public @NotNull Pos getWorldSpawnPosition() { + return this.worldSpawnPosition; } + //Microtus end - integrate world spawn position /** * Gets the current time in the instance (sun/moon). diff --git a/src/main/java/net/minestom/server/instance/anvil/AnvilLoader.java b/src/main/java/net/minestom/server/instance/anvil/AnvilLoader.java index 44990bce260..47730cbd0c9 100644 --- a/src/main/java/net/minestom/server/instance/anvil/AnvilLoader.java +++ b/src/main/java/net/minestom/server/instance/anvil/AnvilLoader.java @@ -246,6 +246,10 @@ private Block[] loadBlockPalette(@NotNull ListBinaryTag paletteTag) { if (blockName.equals("minecraft:air")) { convertedPalette[i] = Block.AIR; } else { + + if (blockName.equals("minecraft:grass")) { + blockName = "minecraft:grass_block"; + } Block block = Objects.requireNonNull(Block.fromNamespaceId(blockName), "Unknown block " + blockName); // Properties final Map properties = new HashMap<>(); diff --git a/src/main/java/net/minestom/server/instance/batch/ChunkBatch.java b/src/main/java/net/minestom/server/instance/batch/ChunkBatch.java index c427442a99b..0fd29d852ae 100644 --- a/src/main/java/net/minestom/server/instance/batch/ChunkBatch.java +++ b/src/main/java/net/minestom/server/instance/batch/ChunkBatch.java @@ -4,6 +4,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntArraySet; import it.unimi.dsi.fastutil.ints.IntSet; +import net.minestom.server.MinecraftServer; import net.minestom.server.instance.Chunk; import net.minestom.server.instance.Instance; import net.minestom.server.instance.InstanceContainer; @@ -193,7 +194,7 @@ private void singleThreadFlush(Instance instance, Chunk chunk, @Nullable ChunkBa if (inverse != null) inverse.readyLatch.countDown(); updateChunk(instance, chunk, sections, callback, safeCallback); } catch (Exception e) { - e.printStackTrace(); + MinecraftServer.getExceptionManager().handleException(e); } } diff --git a/src/main/java/net/minestom/server/instance/block/BlockFace.java b/src/main/java/net/minestom/server/instance/block/BlockFace.java index ec69fe23689..cc5bc2ceca8 100644 --- a/src/main/java/net/minestom/server/instance/block/BlockFace.java +++ b/src/main/java/net/minestom/server/instance/block/BlockFace.java @@ -3,7 +3,13 @@ import net.minestom.server.utils.Direction; import org.jetbrains.annotations.NotNull; +/** + * The enumeration contains all faces which a block can have in the game. + * It's possible that specific blocks doesn't have all faces + * @version 1.0.1 + */ public enum BlockFace { + BOTTOM(Direction.DOWN), TOP(Direction.UP), NORTH(Direction.NORTH), @@ -11,13 +17,25 @@ public enum BlockFace { WEST(Direction.WEST), EAST(Direction.EAST); + private static final BlockFace[] VALUES = values(); + private final Direction direction; - BlockFace(Direction direction) { + /** + * Creates a new enum entry + * + * @param direction the direction for the entry + */ + BlockFace(@NotNull Direction direction) { this.direction = direction; } - public Direction toDirection() { + /** + * Returns the {@link Direction} which correspond with the face. + * + * @return the given direction + */ + public @NotNull Direction toDirection() { return direction; } @@ -77,4 +95,12 @@ public static BlockFace fromDirection(Direction direction) { case EAST -> EAST; }; } + + /** + * Returns the static accessor which caches all entries from the values call. + * @return the given array + */ + public static @NotNull BlockFace[] getValues() { + return VALUES; + } } diff --git a/src/main/java/net/minestom/server/instance/block/BlockImpl.java b/src/main/java/net/minestom/server/instance/block/BlockImpl.java index b4667de1744..f2e5568bbfa 100644 --- a/src/main/java/net/minestom/server/instance/block/BlockImpl.java +++ b/src/main/java/net/minestom/server/instance/block/BlockImpl.java @@ -37,67 +37,9 @@ record BlockImpl(@NotNull Registry.BlockEntry registry, private static final ObjectArray BLOCK_STATE_MAP = ObjectArray.singleThread(); // Block id -> valid property keys (order is important for lookup) private static final ObjectArray PROPERTIES_TYPE = ObjectArray.singleThread(); - // Block id -> Map + // Block id -> Map private static final ObjectArray> POSSIBLE_STATES = ObjectArray.singleThread(); - private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.BLOCKS, - (namespace, properties) -> { - final int blockId = properties.getInt("id"); - final Registry.Properties stateObject = properties.section("states"); - - // Retrieve properties - PropertyType[] propertyTypes; - { - Registry.Properties stateProperties = properties.section("properties"); - if (stateProperties != null) { - final int stateCount = stateProperties.size(); - if (stateCount > MAX_STATES) { - throw new IllegalStateException("Too many properties for block " + namespace); - } - propertyTypes = new PropertyType[stateCount]; - int i = 0; - for (var entry : stateProperties) { - final var k = entry.getKey(); - final var v = (List) entry.getValue(); - assert v.size() < MAX_VALUES; - propertyTypes[i++] = new PropertyType(k, v); - } - } else { - propertyTypes = new PropertyType[0]; - } - } - PROPERTIES_TYPE.set(blockId, propertyTypes); - - // Retrieve block states - { - final int propertiesCount = stateObject.size(); - long[] propertiesKeys = new long[propertiesCount]; - BlockImpl[] blocksValues = new BlockImpl[propertiesCount]; - int propertiesOffset = 0; - for (var stateEntry : stateObject) { - final String query = stateEntry.getKey(); - final var stateOverride = (Map) stateEntry.getValue(); - final var propertyMap = BlockUtils.parseProperties(query); - assert propertyTypes.length == propertyMap.size(); - long propertiesValue = 0; - for (Map.Entry entry : propertyMap.entrySet()) { - final byte keyIndex = findKeyIndex(propertyTypes, entry.getKey(), null); - final byte valueIndex = findValueIndex(propertyTypes[keyIndex], entry.getValue(), null); - propertiesValue = updateIndex(propertiesValue, keyIndex, valueIndex); - } - - var mainProperties = Registry.Properties.fromMap(new MergedMap<>(stateOverride, properties.asMap())); - final BlockImpl block = new BlockImpl(Registry.block(namespace, mainProperties), - propertiesValue, null, null); - BLOCK_STATE_MAP.set(block.stateId(), block); - propertiesKeys[propertiesOffset] = propertiesValue; - blocksValues[propertiesOffset++] = block; - } - POSSIBLE_STATES.set(blockId, new Long2ObjectArrayMap<>(propertiesKeys, blocksValues, propertiesOffset)); - } - // Register default state - final int defaultState = properties.getInt("defaultStateId"); - return getState(defaultState); - }); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.BLOCKS, BlockImpl::createImpl); static { PROPERTIES_TYPE.trim(); @@ -232,6 +174,65 @@ private Block compute(long updatedProperties) { return new BlockImpl(block.registry(), block.propertiesArray, nbt, handler); } + private static Block createImpl(String namespace, Registry.Properties properties) { + final int blockId = properties.getInt("id"); + final Registry.Properties stateObject = properties.section("states"); + + // Retrieve properties + PropertyType[] propertyTypes; + { + Registry.Properties stateProperties = properties.section("properties"); + if (stateProperties != null) { + final int stateCount = stateProperties.size(); + if (stateCount > MAX_STATES) { + throw new IllegalStateException("Too many properties for block " + namespace); + } + propertyTypes = new PropertyType[stateCount]; + int i = 0; + for (var entry : stateProperties) { + final var k = entry.getKey(); + final var v = (List) entry.getValue(); + assert v.size() < MAX_VALUES; + propertyTypes[i++] = new PropertyType(k, v); + } + } else { + propertyTypes = new PropertyType[0]; + } + } + PROPERTIES_TYPE.set(blockId, propertyTypes); + + // Retrieve block states + { + final int propertiesCount = stateObject.size(); + long[] propertiesKeys = new long[propertiesCount]; + BlockImpl[] blocksValues = new BlockImpl[propertiesCount]; + int propertiesOffset = 0; + for (var stateEntry : stateObject) { + final String query = stateEntry.getKey(); + final var stateOverride = (Map) stateEntry.getValue(); + final var propertyMap = BlockUtils.parseProperties(query); + assert propertyTypes.length == propertyMap.size(); + long propertiesValue = 0; + for (Map.Entry entry : propertyMap.entrySet()) { + final byte keyIndex = findKeyIndex(propertyTypes, entry.getKey(), null); + final byte valueIndex = findValueIndex(propertyTypes[keyIndex], entry.getValue(), null); + propertiesValue = updateIndex(propertiesValue, keyIndex, valueIndex); + } + + var mainProperties = Registry.Properties.fromMap(new MergedMap<>(stateOverride, properties.asMap())); + final BlockImpl block = new BlockImpl(Registry.block(namespace, mainProperties), + propertiesValue, null, null); + BLOCK_STATE_MAP.set(block.stateId(), block); + propertiesKeys[propertiesOffset] = propertiesValue; + blocksValues[propertiesOffset++] = block; + } + POSSIBLE_STATES.set(blockId, new Long2ObjectArrayMap<>(propertiesKeys, blocksValues, propertiesOffset)); + } + // Register default state + final int defaultState = properties.getInt("defaultStateId"); + return getState(defaultState); + } + private static byte findKeyIndex(PropertyType[] properties, String key, BlockImpl block) { for (byte i = 0; i < properties.length; i++) { if (properties[i].key().equals(key)) return i; diff --git a/src/main/java/net/minestom/server/instance/block/BlockManager.java b/src/main/java/net/minestom/server/instance/block/BlockManager.java index fd0243002b9..d19f1c50432 100644 --- a/src/main/java/net/minestom/server/instance/block/BlockManager.java +++ b/src/main/java/net/minestom/server/instance/block/BlockManager.java @@ -17,7 +17,7 @@ import java.util.function.Supplier; public final class BlockManager { - private final static Logger LOGGER = LoggerFactory.getLogger(BlockManager.class); + private static final Logger LOGGER = LoggerFactory.getLogger(BlockManager.class); //Microtus - update java keyword usage // Namespace -> handler supplier private final Map> blockHandlerMap = new ConcurrentHashMap<>(); // block id -> block placement rule diff --git a/src/main/java/net/minestom/server/instance/block/rule/BlockPlacementRule.java b/src/main/java/net/minestom/server/instance/block/rule/BlockPlacementRule.java index a2eb98107e3..9488b6105da 100644 --- a/src/main/java/net/minestom/server/instance/block/rule/BlockPlacementRule.java +++ b/src/main/java/net/minestom/server/instance/block/rule/BlockPlacementRule.java @@ -16,7 +16,7 @@ public abstract class BlockPlacementRule { protected BlockPlacementRule(@NotNull Block block) { this.block = block; - } + } //Microtus - update java keyword usage /** * Called when the block state id can be updated (for instance if a neighbour block changed). diff --git a/src/main/java/net/minestom/server/instance/light/BlockLight.java b/src/main/java/net/minestom/server/instance/light/BlockLight.java index 244940fc430..f0b5109ae46 100644 --- a/src/main/java/net/minestom/server/instance/light/BlockLight.java +++ b/src/main/java/net/minestom/server/instance/light/BlockLight.java @@ -52,7 +52,7 @@ private ShortArrayFIFOQueue buildExternalQueue(Palette blockPalette, ShortArrayFIFOQueue lightSources = new ShortArrayFIFOQueue(); for (int i = 0; i < neighbors.length; i++) { - final BlockFace face = BlockFace.values()[i]; + final BlockFace face = BlockFace.getValues()[i]; Point neighborSection = neighbors[i]; if (neighborSection == null) continue; @@ -203,7 +203,7 @@ public Set calculateExternal(Palette blockPalette, for (int i = 0; i < neighbors.length; i++) { final Point neighbor = neighbors[i]; if (neighbor == null) continue; - final BlockFace face = BlockFace.values()[i]; + final BlockFace face = BlockFace.getValues()[i]; if (!LightCompute.compareBorders(content, contentPropagation, contentPropagationTemp, face)) { toUpdate.add(neighbor); } diff --git a/src/main/java/net/minestom/server/instance/light/Light.java b/src/main/java/net/minestom/server/instance/light/Light.java index 45216c834a7..add0d2f1a4c 100644 --- a/src/main/java/net/minestom/server/instance/light/Light.java +++ b/src/main/java/net/minestom/server/instance/light/Light.java @@ -51,8 +51,10 @@ static Point[] getNeighbors(Chunk chunk, int sectionY) { final int chunkX = chunk.getChunkX(); final int chunkZ = chunk.getChunkZ(); - Point[] links = new Vec[BlockFace.values().length]; - for (BlockFace face : BlockFace.values()) { + final BlockFace[] faces = BlockFace.getValues(); + + Point[] links = new Vec[faces.length]; + for (BlockFace face : faces) { final Direction direction = face.toDirection(); final int x = chunkX + direction.normalX(); final int z = chunkZ + direction.normalZ(); diff --git a/src/main/java/net/minestom/server/instance/light/SkyLight.java b/src/main/java/net/minestom/server/instance/light/SkyLight.java index 6a79b672048..e44291d9c85 100644 --- a/src/main/java/net/minestom/server/instance/light/SkyLight.java +++ b/src/main/java/net/minestom/server/instance/light/SkyLight.java @@ -54,7 +54,7 @@ private ShortArrayFIFOQueue buildExternalQueue(Palette blockPalette, ShortArrayFIFOQueue lightSources = new ShortArrayFIFOQueue(); for (int i = 0; i < neighbors.length; i++) { - final BlockFace face = BlockFace.values()[i]; + final BlockFace face = BlockFace.getValues()[i]; Point neighborSection = neighbors[i]; if (neighborSection == null) continue; @@ -225,7 +225,7 @@ public Set calculateExternal(Palette blockPalette, for (int i = 0; i < neighbors.length; i++) { final Point neighbor = neighbors[i]; if (neighbor == null) continue; - final BlockFace face = BlockFace.values()[i]; + final BlockFace face = BlockFace.getValues()[i]; if (!LightCompute.compareBorders(content, contentPropagation, contentPropagationTemp, face)) { toUpdate.add(neighbor); } diff --git a/src/main/java/net/minestom/server/inventory/AbstractInventory.java b/src/main/java/net/minestom/server/inventory/AbstractInventory.java index 99cfc2fb0d8..1d239416120 100644 --- a/src/main/java/net/minestom/server/inventory/AbstractInventory.java +++ b/src/main/java/net/minestom/server/inventory/AbstractInventory.java @@ -23,8 +23,8 @@ /** * Represents an inventory where items can be modified/retrieved. */ -public sealed abstract class AbstractInventory implements InventoryClickHandler, Taggable - permits Inventory, PlayerInventory { +public abstract sealed class AbstractInventory implements InventoryClickHandler, Taggable + permits Inventory, PlayerInventory { //Microtus - update java keyword usage private static final VarHandle ITEM_UPDATER = MethodHandles.arrayElementVarHandle(ItemStack[].class); diff --git a/src/main/java/net/minestom/server/inventory/Inventory.java b/src/main/java/net/minestom/server/inventory/Inventory.java index 174e301c06e..ace374daffc 100644 --- a/src/main/java/net/minestom/server/inventory/Inventory.java +++ b/src/main/java/net/minestom/server/inventory/Inventory.java @@ -22,7 +22,7 @@ /** * Represents an inventory which can be viewed by a collection of {@link Player}. *

- * You can create one with {@link Inventory#Inventory(InventoryType, String)} or by making your own subclass. + * You can create one with {@link Inventory#Inventory(InventoryType, Component)} or by making your own subclass. * It can then be opened using {@link Player#openInventory(Inventory)}. */ public non-sealed class Inventory extends AbstractInventory implements Viewable { @@ -50,10 +50,6 @@ public Inventory(@NotNull InventoryType inventoryType, @NotNull Component title) this.offset = getSize(); } - public Inventory(@NotNull InventoryType inventoryType, @NotNull String title) { - this(inventoryType, Component.text(title)); - } - private static byte generateId() { return (byte) ID_COUNTER.updateAndGet(i -> i + 1 >= 128 ? 1 : i + 1); } @@ -241,7 +237,7 @@ public boolean rightClick(@NotNull Player player, int slot) { } @Override - public boolean shiftClick(@NotNull Player player, int slot) { + public boolean shiftClick(@NotNull Player player, int slot, int button) { // Microtus final PlayerInventory playerInventory = player.getInventory(); final boolean isInWindow = isClickInWindow(slot); final int clickSlot = isInWindow ? slot : PlayerInventoryUtils.convertSlot(slot, offset); @@ -251,7 +247,7 @@ public boolean shiftClick(@NotNull Player player, int slot) { isInWindow ? this : playerInventory, isInWindow ? playerInventory : this, 0, isInWindow ? playerInventory.getInnerSize() : getInnerSize(), 1, - player, clickSlot, clicked, cursor); + player, clickSlot, clicked, cursor, button); // Microtus if (clickResult.isCancel()) { updateAll(player); return false; diff --git a/src/main/java/net/minestom/server/inventory/InventoryClickHandler.java b/src/main/java/net/minestom/server/inventory/InventoryClickHandler.java index 5fa175416eb..550f50ae2fd 100644 --- a/src/main/java/net/minestom/server/inventory/InventoryClickHandler.java +++ b/src/main/java/net/minestom/server/inventory/InventoryClickHandler.java @@ -38,9 +38,10 @@ public sealed interface InventoryClickHandler permits AbstractInventory { * * @param player the player who clicked * @param slot the slot number + * @param button the primary mouse or secondary mouse button * @return true if the click hasn't been cancelled, false otherwise */ - boolean shiftClick(@NotNull Player player, int slot); // shift + left/right click have the same behavior + boolean shiftClick(@NotNull Player player, int slot, int button); // shift + left/right click have the same behavior // Microtus /** * Called when a {@link Player} held click in the inventory diff --git a/src/main/java/net/minestom/server/inventory/InventoryType.java b/src/main/java/net/minestom/server/inventory/InventoryType.java index 9b77808c066..9b4c1effd91 100644 --- a/src/main/java/net/minestom/server/inventory/InventoryType.java +++ b/src/main/java/net/minestom/server/inventory/InventoryType.java @@ -44,13 +44,4 @@ public int getWindowType() { public int getSize() { return size; } - - /** - * @deprecated use {@link #getSize()} - */ - @Deprecated - public int getAdditionalSlot() { - return size; - } - } diff --git a/src/main/java/net/minestom/server/inventory/PlayerInventory.java b/src/main/java/net/minestom/server/inventory/PlayerInventory.java index cf229d55e8f..0515694bc51 100644 --- a/src/main/java/net/minestom/server/inventory/PlayerInventory.java +++ b/src/main/java/net/minestom/server/inventory/PlayerInventory.java @@ -213,7 +213,7 @@ public boolean drop(@NotNull Player player, boolean all, int slot, int button) { } @Override - public boolean shiftClick(@NotNull Player player, int slot) { + public boolean shiftClick(@NotNull Player player, int slot, int button) { // Microtus final int convertedSlot = convertPlayerInventorySlot(slot, OFFSET); final ItemStack cursor = getCursorItem(); final ItemStack clicked = getItemStack(convertedSlot); @@ -223,7 +223,7 @@ public boolean shiftClick(@NotNull Player player, int slot) { final InventoryClickResult clickResult = clickProcessor.shiftClick( this, this, start, end, 1, - player, convertedSlot, clicked, cursor); + player, convertedSlot, clicked, cursor, button); // Microtus if (clickResult.isCancel()) { update(); return false; diff --git a/src/main/java/net/minestom/server/inventory/click/ClickType.java b/src/main/java/net/minestom/server/inventory/click/ClickType.java index c6fe8eda8d5..bf5600760e4 100644 --- a/src/main/java/net/minestom/server/inventory/click/ClickType.java +++ b/src/main/java/net/minestom/server/inventory/click/ClickType.java @@ -6,8 +6,10 @@ public enum ClickType { RIGHT_CLICK, CHANGE_HELD, - START_SHIFT_CLICK, - SHIFT_CLICK, + START_SHIFT_LEFT_CLICK, // Microtus + START_SHIFT_RIGHT_CLICK, // Microtus + SHIFT_LEFT_CLICK, // Microtus + SHIFT_RIGHT_CLICK, // Microtus START_LEFT_DRAGGING, START_RIGHT_DRAGGING, diff --git a/src/main/java/net/minestom/server/inventory/click/InventoryClickProcessor.java b/src/main/java/net/minestom/server/inventory/click/InventoryClickProcessor.java index 0ee2534ee15..72f17ffaa32 100644 --- a/src/main/java/net/minestom/server/inventory/click/InventoryClickProcessor.java +++ b/src/main/java/net/minestom/server/inventory/click/InventoryClickProcessor.java @@ -117,10 +117,12 @@ public final class InventoryClickProcessor { public @NotNull InventoryClickResult shiftClick(@NotNull AbstractInventory inventory, @NotNull AbstractInventory targetInventory, int start, int end, int step, @NotNull Player player, int slot, - @NotNull ItemStack clicked, @NotNull ItemStack cursor) { - InventoryClickResult clickResult = startCondition(player, inventory, slot, ClickType.START_SHIFT_CLICK, clicked, cursor); + @NotNull ItemStack clicked, @NotNull ItemStack cursor, int button) { // Microtus + ClickType startShiftClick = button == 0 ? ClickType.START_SHIFT_LEFT_CLICK : ClickType.START_SHIFT_RIGHT_CLICK; // Microtus + InventoryClickResult clickResult = startCondition(player, inventory, slot, startShiftClick, clicked, cursor); // Microtus if (clickResult.isCancel()) return clickResult; if (clicked.isAir()) return clickResult.cancelled(); + ClickType shiftClick = button == 0 ? ClickType.SHIFT_LEFT_CLICK : ClickType.SHIFT_RIGHT_CLICK; // Microtus // Handle armor equip if (inventory instanceof PlayerInventory && targetInventory instanceof PlayerInventory) { @@ -131,7 +133,7 @@ public final class InventoryClickProcessor { final ItemStack currentArmor = player.getEquipment(equipmentSlot); if (currentArmor.isAir()) { final int armorSlot = equipmentSlot.armorSlot(); - InventoryClickResult result = startCondition(player, targetInventory, armorSlot, ClickType.SHIFT_CLICK, clicked, cursor); + InventoryClickResult result = startCondition(player, targetInventory, armorSlot, shiftClick, clicked, cursor); // Microtus if (result.isCancel()) return clickResult; result.setClicked(ItemStack.AIR); result.setCursor(cursor); @@ -145,7 +147,7 @@ public final class InventoryClickProcessor { final var pair = TransactionType.ADD.process(targetInventory, clicked, (index, itemStack) -> { if (inventory == targetInventory && index == slot) return false; // Prevent item lose/duplication - InventoryClickResult result = startCondition(player, targetInventory, index, ClickType.SHIFT_CLICK, itemStack, cursor); + InventoryClickResult result = startCondition(player, targetInventory, index, shiftClick, itemStack, cursor); // Microtus if (result.isCancel()) { return false; } @@ -157,7 +159,7 @@ public final class InventoryClickProcessor { final Map itemChangesMap = pair.right(); itemChangesMap.forEach((Integer s, ItemStack itemStack) -> { targetInventory.setItemStack(s, itemStack); - callClickEvent(player, targetInventory, s, ClickType.SHIFT_CLICK, itemStack, cursor); + callClickEvent(player, targetInventory, s, shiftClick, itemStack, cursor); // Microtus }); clickResult.setClicked(itemResult); return clickResult; diff --git a/src/main/java/net/minestom/server/inventory/type/AnvilInventory.java b/src/main/java/net/minestom/server/inventory/type/AnvilInventory.java index 8a7c9f2c154..ed21091b4ac 100644 --- a/src/main/java/net/minestom/server/inventory/type/AnvilInventory.java +++ b/src/main/java/net/minestom/server/inventory/type/AnvilInventory.java @@ -14,10 +14,6 @@ public AnvilInventory(@NotNull Component title) { super(InventoryType.ANVIL, title); } - public AnvilInventory(@NotNull String title) { - super(InventoryType.ANVIL, title); - } - /** * Gets the anvil repair cost. * diff --git a/src/main/java/net/minestom/server/inventory/type/BeaconInventory.java b/src/main/java/net/minestom/server/inventory/type/BeaconInventory.java index 30551dae67c..0a2dd297603 100644 --- a/src/main/java/net/minestom/server/inventory/type/BeaconInventory.java +++ b/src/main/java/net/minestom/server/inventory/type/BeaconInventory.java @@ -17,10 +17,6 @@ public BeaconInventory(@NotNull Component title) { super(InventoryType.BEACON, title); } - public BeaconInventory(@NotNull String title) { - super(InventoryType.BEACON, title); - } - /** * Gets the beacon power level. * diff --git a/src/main/java/net/minestom/server/inventory/type/BrewingStandInventory.java b/src/main/java/net/minestom/server/inventory/type/BrewingStandInventory.java index ed0bc7d783d..7c88145f40a 100644 --- a/src/main/java/net/minestom/server/inventory/type/BrewingStandInventory.java +++ b/src/main/java/net/minestom/server/inventory/type/BrewingStandInventory.java @@ -15,10 +15,6 @@ public BrewingStandInventory(@NotNull Component title) { super(InventoryType.BREWING_STAND, title); } - public BrewingStandInventory(@NotNull String title) { - super(InventoryType.BREWING_STAND, title); - } - /** * Gets the brewing stand brew time. * diff --git a/src/main/java/net/minestom/server/inventory/type/EnchantmentTableInventory.java b/src/main/java/net/minestom/server/inventory/type/EnchantmentTableInventory.java index a3a043a25f9..5b9d217a2cc 100644 --- a/src/main/java/net/minestom/server/inventory/type/EnchantmentTableInventory.java +++ b/src/main/java/net/minestom/server/inventory/type/EnchantmentTableInventory.java @@ -22,10 +22,6 @@ public EnchantmentTableInventory(@NotNull Component title) { super(InventoryType.ENCHANTMENT, title); } - public EnchantmentTableInventory(@NotNull String title) { - super(InventoryType.ENCHANTMENT, title); - } - /** * Gets the level requirement in a slot. * diff --git a/src/main/java/net/minestom/server/inventory/type/FurnaceInventory.java b/src/main/java/net/minestom/server/inventory/type/FurnaceInventory.java index 9e357da9936..56435798d49 100644 --- a/src/main/java/net/minestom/server/inventory/type/FurnaceInventory.java +++ b/src/main/java/net/minestom/server/inventory/type/FurnaceInventory.java @@ -17,10 +17,6 @@ public FurnaceInventory(@NotNull Component title) { super(InventoryType.FURNACE, title); } - public FurnaceInventory(@NotNull String title) { - super(InventoryType.FURNACE, title); - } - /** * Represents the amount of tick until the fire icon come empty. * diff --git a/src/main/java/net/minestom/server/inventory/type/VillagerInventory.java b/src/main/java/net/minestom/server/inventory/type/VillagerInventory.java index 048fa581393..a725850db5c 100644 --- a/src/main/java/net/minestom/server/inventory/type/VillagerInventory.java +++ b/src/main/java/net/minestom/server/inventory/type/VillagerInventory.java @@ -6,6 +6,7 @@ import net.minestom.server.inventory.InventoryType; import net.minestom.server.network.packet.server.CachedPacket; import net.minestom.server.network.packet.server.play.TradeListPacket; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -24,10 +25,6 @@ public VillagerInventory(@NotNull Component title) { super(InventoryType.MERCHANT, title); } - public VillagerInventory(@NotNull String title) { - super(InventoryType.MERCHANT, title); - } - public List getTrades() { return Collections.unmodifiableList(trades); } @@ -92,7 +89,8 @@ public boolean addViewer(@NotNull Player player) { return result; } - private TradeListPacket createTradePacket() { + @Contract(pure = true) + private @NotNull TradeListPacket createTradePacket() { return new TradeListPacket(getWindowId(), trades, villagerLevel, experience, regularVillager, canRestock); } } diff --git a/src/main/java/net/minestom/server/item/MaterialImpl.java b/src/main/java/net/minestom/server/item/MaterialImpl.java index 38c1c823684..2808b424c8e 100644 --- a/src/main/java/net/minestom/server/item/MaterialImpl.java +++ b/src/main/java/net/minestom/server/item/MaterialImpl.java @@ -6,8 +6,11 @@ import java.util.Collection; record MaterialImpl(Registry.MaterialEntry registry) implements Material { - private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.ITEMS, - (namespace, properties) -> new MaterialImpl(Registry.material(namespace, properties))); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.ITEMS, MaterialImpl::createImpl); + + private static Material createImpl(String namespace, Registry.Properties properties) { + return new MaterialImpl(Registry.material(namespace, properties)); + } static Material get(@NotNull String namespace) { return CONTAINER.get(namespace); diff --git a/src/main/java/net/minestom/server/item/banner/BannerPattern.java b/src/main/java/net/minestom/server/item/banner/BannerPattern.java new file mode 100644 index 00000000000..86d320f1285 --- /dev/null +++ b/src/main/java/net/minestom/server/item/banner/BannerPattern.java @@ -0,0 +1,40 @@ +package net.minestom.server.item.banner; + +import net.kyori.adventure.key.Key; +import net.minestom.server.registry.ProtocolObject; +import net.minestom.server.registry.StaticProtocolObject; +import net.minestom.server.utils.NamespaceID; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; + +// Microtus - Banner and Shield Meta +public sealed interface BannerPattern extends StaticProtocolObject, BannerPatterns permits BannerPatternImpl { + static @NotNull Collection<@NotNull BannerPattern> values() { + return BannerPatternImpl.values(); + } + + static @Nullable BannerPattern fromNamespaceId(@NotNull String namespaceID) { + return BannerPatternImpl.getSafe(namespaceID); + } + + static @Nullable BannerPattern fromNamespaceId(@NotNull NamespaceID namespaceID) { + return fromNamespaceId(namespaceID.asString()); + } + + static @Nullable BannerPattern fromId(int id) { + return BannerPatternImpl.getId(id); + } + + static @Nullable BannerPattern fromIdentifier(String identifier) { + return BannerPatternImpl.getIdentifier(identifier); + } + + @Override + default @NotNull Key key() { + return StaticProtocolObject.super.key(); + } + + @NotNull String identifier(); +} diff --git a/src/main/java/net/minestom/server/item/banner/BannerPatternImpl.java b/src/main/java/net/minestom/server/item/banner/BannerPatternImpl.java new file mode 100644 index 00000000000..028e219a01e --- /dev/null +++ b/src/main/java/net/minestom/server/item/banner/BannerPatternImpl.java @@ -0,0 +1,49 @@ +package net.minestom.server.item.banner; + +import net.minestom.server.registry.Registry; +import net.minestom.server.utils.NamespaceID; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +// Microtus - Banner and Shield Meta +public record BannerPatternImpl(NamespaceID namespace, int id, String identifier) implements BannerPattern { + + private static Map IDENTIFIERS = new HashMap<>(); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.BANNER_PATTERNS, BannerPatternImpl::createImpl); + + private static BannerPattern createImpl(String namespace, Registry.Properties properties) { + int id = properties.getInt("id"); + String identifier = properties.getString("identifier"); + BannerPatternImpl bannerPattern = new BannerPatternImpl(NamespaceID.from(namespace), id, identifier); + IDENTIFIERS.put(identifier, bannerPattern); + return bannerPattern; + } + + static BannerPattern get(@NotNull String namespace) { + return CONTAINER.get(namespace); + } + + static BannerPattern getSafe(@NotNull String namespace) { + return CONTAINER.getSafe(namespace); + } + + static BannerPattern getId(int id) { + return CONTAINER.getId(id); + } + + static BannerPattern getIdentifier(@NotNull String identifier) { + return IDENTIFIERS.get(identifier); + } + + static Collection values() { + return CONTAINER.values(); + } + + @Override + public String toString() { + return name(); + } +} diff --git a/src/main/java/net/minestom/server/listener/AdvancementTabListener.java b/src/main/java/net/minestom/server/listener/AdvancementTabListener.java index 3a8edbd121b..a27c3f10dbd 100644 --- a/src/main/java/net/minestom/server/listener/AdvancementTabListener.java +++ b/src/main/java/net/minestom/server/listener/AdvancementTabListener.java @@ -7,6 +7,8 @@ public class AdvancementTabListener { + private AdvancementTabListener() {} + public static void listener(ClientAdvancementTabPacket packet, Player player) { final String tabIdentifier = packet.tabIdentifier(); if (tabIdentifier != null) { diff --git a/src/main/java/net/minestom/server/listener/AnimationListener.java b/src/main/java/net/minestom/server/listener/AnimationListener.java index e8756e0f371..f0a55641c70 100644 --- a/src/main/java/net/minestom/server/listener/AnimationListener.java +++ b/src/main/java/net/minestom/server/listener/AnimationListener.java @@ -8,6 +8,8 @@ public class AnimationListener { + private AnimationListener() { } + public static void animationListener(ClientAnimationPacket packet, Player player) { final Player.Hand hand = packet.hand(); final ItemStack itemStack = player.getItemInHand(hand); diff --git a/src/main/java/net/minestom/server/listener/WindowListener.java b/src/main/java/net/minestom/server/listener/WindowListener.java index 682132a9b70..dad46cfb94a 100644 --- a/src/main/java/net/minestom/server/listener/WindowListener.java +++ b/src/main/java/net/minestom/server/listener/WindowListener.java @@ -49,7 +49,7 @@ public static void clickWindowListener(ClientClickWindowPacket packet, Player pl } } } else if (clickType == ClientClickWindowPacket.ClickType.QUICK_MOVE) { - successful = inventory.shiftClick(player, slot); + successful = inventory.shiftClick(player, slot, button); // Microtus } else if (clickType == ClientClickWindowPacket.ClickType.SWAP) { if (slot < 0 || button < 0) return; successful = inventory.changeHeld(player, slot, button); diff --git a/src/main/java/net/minestom/server/listener/preplay/HandshakeListener.java b/src/main/java/net/minestom/server/listener/preplay/HandshakeListener.java index 06ec2f836ec..b998be1206a 100644 --- a/src/main/java/net/minestom/server/listener/preplay/HandshakeListener.java +++ b/src/main/java/net/minestom/server/listener/preplay/HandshakeListener.java @@ -25,7 +25,7 @@ public final class HandshakeListener { - private final static Logger LOGGER = LoggerFactory.getLogger(HandshakeListener.class); + private static final Logger LOGGER = LoggerFactory.getLogger(HandshakeListener.class); /** * Text sent if a player tries to connect with an invalid version of the client @@ -138,4 +138,5 @@ private static void bungeeDisconnect(@NotNull PlayerConnection connection) { disconnect(connection, INVALID_BUNGEE_FORWARDING); } + private HandshakeListener() { } } diff --git a/src/main/java/net/minestom/server/monitoring/BenchmarkManager.java b/src/main/java/net/minestom/server/monitoring/BenchmarkManager.java index 84c502629a3..50053284b34 100644 --- a/src/main/java/net/minestom/server/monitoring/BenchmarkManager.java +++ b/src/main/java/net/minestom/server/monitoring/BenchmarkManager.java @@ -34,7 +34,7 @@ * Be aware that this is not the most accurate method, you should use a proper java profiler depending on your needs. */ public final class BenchmarkManager { - private final static Logger LOGGER = LoggerFactory.getLogger(BenchmarkManager.class); + private static final Logger LOGGER = LoggerFactory.getLogger(BenchmarkManager.class); //Microtus - update java keyword usage private static final ThreadMXBean THREAD_MX_BEAN = ManagementFactory.getThreadMXBean(); private static final List THREADS = new ArrayList<>(); diff --git a/src/main/java/net/minestom/server/network/packet/client/play/ClientPlayerDiggingPacket.java b/src/main/java/net/minestom/server/network/packet/client/play/ClientPlayerDiggingPacket.java index c6c8c08b18a..a39026f5327 100644 --- a/src/main/java/net/minestom/server/network/packet/client/play/ClientPlayerDiggingPacket.java +++ b/src/main/java/net/minestom/server/network/packet/client/play/ClientPlayerDiggingPacket.java @@ -12,7 +12,7 @@ public record ClientPlayerDiggingPacket(@NotNull Status status, @NotNull Point b @NotNull BlockFace blockFace, int sequence) implements ClientPacket { public ClientPlayerDiggingPacket(@NotNull NetworkBuffer reader) { this(reader.readEnum(Status.class), reader.read(BLOCK_POSITION), - BlockFace.values()[reader.read(BYTE)], reader.read(VAR_INT)); + BlockFace.getValues()[reader.read(BYTE)], reader.read(VAR_INT)); } @Override diff --git a/src/main/java/net/minestom/server/network/packet/server/common/PluginMessagePacket.java b/src/main/java/net/minestom/server/network/packet/server/common/PluginMessagePacket.java index ede91dd39d7..784c50a93ad 100644 --- a/src/main/java/net/minestom/server/network/packet/server/common/PluginMessagePacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/common/PluginMessagePacket.java @@ -1,5 +1,6 @@ package net.minestom.server.network.packet.server.common; +import net.kyori.adventure.key.Key; import net.minestom.server.MinecraftServer; import net.minestom.server.network.NetworkBuffer; import net.minestom.server.network.packet.server.ServerPacket; @@ -9,15 +10,15 @@ import static net.minestom.server.network.NetworkBuffer.RAW_BYTES; import static net.minestom.server.network.NetworkBuffer.STRING; -public record PluginMessagePacket(String channel, +public record PluginMessagePacket(Key channel, byte[] data) implements ServerPacket.Configuration, ServerPacket.Play { public PluginMessagePacket(@NotNull NetworkBuffer reader) { - this(reader.read(STRING), reader.read(RAW_BYTES)); + this(Key.key(reader.read(STRING)), reader.read(RAW_BYTES)); } @Override public void write(@NotNull NetworkBuffer writer) { - writer.write(STRING, channel); + writer.write(STRING, channel.asString()); writer.write(RAW_BYTES, data); } @@ -41,6 +42,6 @@ public int playId() { public static @NotNull PluginMessagePacket getBrandPacket() { final String brandName = MinecraftServer.getBrandName(); final byte[] data = NetworkBuffer.makeArray(networkBuffer -> networkBuffer.write(STRING, brandName)); - return new PluginMessagePacket("minecraft:brand", data); + return new PluginMessagePacket(Key.key("minecraft:brand"), data); } } diff --git a/src/main/java/net/minestom/server/network/packet/server/common/ServerLinksPacket.java b/src/main/java/net/minestom/server/network/packet/server/common/ServerLinksPacket.java index 3c98bc06d80..e5c34546d64 100644 --- a/src/main/java/net/minestom/server/network/packet/server/common/ServerLinksPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/common/ServerLinksPacket.java @@ -1,6 +1,7 @@ package net.minestom.server.network.packet.server.common; import net.kyori.adventure.text.Component; +import net.minestom.server.ServerFlag; import net.minestom.server.network.NetworkBuffer; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; @@ -11,7 +12,6 @@ import java.util.List; public record ServerLinksPacket(@NotNull List entries) implements ServerPacket.Configuration, ServerPacket.Play { - private static final int MAX_ENTRIES = 100; public ServerLinksPacket { entries = List.copyOf(entries); @@ -64,7 +64,7 @@ public Entry read(@NotNull NetworkBuffer buffer) { } } }; - public static final NetworkBuffer.Type> LIST_NETWORK_TYPE = NETWORK_TYPE.list(MAX_ENTRIES); + public static final NetworkBuffer.Type> LIST_NETWORK_TYPE = NETWORK_TYPE.list(ServerFlag.SERVER_LINK_AMOUNT); public Entry { Check.argCondition(knownType == null && customType == null, "One of knownType and customType must be present"); diff --git a/src/main/java/net/minestom/server/network/packet/server/common/TagsPacket.java b/src/main/java/net/minestom/server/network/packet/server/common/TagsPacket.java index ec24448d05e..6b4315120d2 100644 --- a/src/main/java/net/minestom/server/network/packet/server/common/TagsPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/common/TagsPacket.java @@ -45,7 +45,11 @@ public void write(@NotNull NetworkBuffer writer) { final var values = tag.getValues(); writer.write(VAR_INT, values.size()); for (var name : values) { - writer.write(VAR_INT, type.getFunction().apply(name.asString())); + var applied = type.getFunction().apply(name.asString()); + if (applied.isEmpty()) { + continue; + } + writer.write(VAR_INT, applied.get()); } } } diff --git a/src/main/java/net/minestom/server/network/packet/server/configuration/UpdateEnabledFeaturesPacket.java b/src/main/java/net/minestom/server/network/packet/server/configuration/UpdateEnabledFeaturesPacket.java index 7bba65a9b18..a819d0af3d6 100644 --- a/src/main/java/net/minestom/server/network/packet/server/configuration/UpdateEnabledFeaturesPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/configuration/UpdateEnabledFeaturesPacket.java @@ -11,7 +11,7 @@ import static net.minestom.server.network.NetworkBuffer.STRING; public record UpdateEnabledFeaturesPacket(@NotNull Set features) implements ServerPacket.Configuration { - public static final int MAX_FEATURES = 1024; + public static final int MAX_FEATURES = 64; public UpdateEnabledFeaturesPacket(@NotNull NetworkBuffer buffer) { this(Set.copyOf(buffer.readCollection((b) -> NamespaceID.from(b.read(STRING)), MAX_FEATURES))); diff --git a/src/main/java/net/minestom/server/network/socket/Server.java b/src/main/java/net/minestom/server/network/socket/Server.java index 38a55692442..b28c8e96292 100644 --- a/src/main/java/net/minestom/server/network/socket/Server.java +++ b/src/main/java/net/minestom/server/network/socket/Server.java @@ -82,7 +82,7 @@ public void start() { final SocketChannel client = serverSocket.accept(); worker.receiveConnection(client); } catch (IOException e) { - e.printStackTrace(); + MinecraftServer.getExceptionManager().handleException(e); } }); } catch (IOException e) { diff --git a/src/main/java/net/minestom/server/notifications/Notification.java b/src/main/java/net/minestom/server/notifications/Notification.java new file mode 100644 index 00000000000..90ee6fc4dbc --- /dev/null +++ b/src/main/java/net/minestom/server/notifications/Notification.java @@ -0,0 +1,117 @@ +package net.minestom.server.notifications; + +import net.kyori.adventure.text.Component; +import net.minestom.server.advancements.FrameType; +import net.minestom.server.entity.Player; +import net.minestom.server.item.ItemStack; +import net.minestom.server.item.Material; +import net.minestom.server.network.packet.server.play.AdvancementsPacket; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.List; + +/** + * Is used to send temporary advancements to the client, which are called notifications. + *
+ * Here is an example of its use: + *


+ * Notification notification = Notification.builder()
+ *  .frameType(FrameType.TASK)
+ *  .title(Component.text("Welcome!"))
+ *  .icon(Material.IRON_SWORD).build();
+ * notification.send(player);
+ * 
+ * + * The constant {@link #IDENTIFIER} is used for the advancement packet + * The constant {@link #REMOVE_PACKET} is used to remove previous notifications + * @since 1.4.1 + */ +public sealed interface Notification permits NotificationImpl { + + String IDENTIFIER = "minestom:notification"; + AdvancementsPacket REMOVE_PACKET = new AdvancementsPacket(false, List.of(), List.of(IDENTIFIER), List.of()); + + /** + * Creates a new builder instance + * @return an instance of the builder + */ + @Contract(pure = true) + static @NotNull Builder builder() { + return new NotificationBuilder(); + } + + /** + * Send the notification to the client + * @param player to get be sent + */ + void send(@NotNull Player player); + + /** + * Send the notification to a collection of clients + * @param players to get be sent + */ + void send(@NotNull Collection<@NotNull Player> players); + + /** + * Gets the title of the notification as a {@link Component} + * @return the title {@link Component} + */ + @NotNull Component title(); + + /** + * Get the {@link FrameType} of the notification + * @return the type + */ + @NotNull FrameType type(); + + /** + * Get the displayed icon of the notification as {@link ItemStack} + * @return the {@link ItemStack} + */ + @NotNull ItemStack icon(); + + /** + * @since 1.4.1 + */ + sealed interface Builder permits NotificationBuilder { + + /** + * Set the title for a notification as component. + * + * If you're using a resource pack you can use {@link Component#translatable(String)} + * + * @param component to get send to the client + * @return the builder + */ + Builder title(@NotNull Component component); + + /** + * Set the frame typ of the notification + * @param frameType to showed for the client + * @return the builder + */ + Builder frameType(@NotNull FrameType frameType); + + /** + * Set the {@link Material} for the icon + * @param material to be shown to the client + * @return the builder + */ + Builder icon(@NotNull Material material); + + /** + * Set the {@link ItemStack} for the icon + * @param itemStack to be shown to the client + * @return the builder + */ + Builder icon(@NotNull ItemStack itemStack); + + /** + * Returns an instance of the creation notification + * @return the instance + */ + Notification build(); + } +} diff --git a/src/main/java/net/minestom/server/notifications/NotificationBuilder.java b/src/main/java/net/minestom/server/notifications/NotificationBuilder.java new file mode 100644 index 00000000000..97452ee3a55 --- /dev/null +++ b/src/main/java/net/minestom/server/notifications/NotificationBuilder.java @@ -0,0 +1,60 @@ +package net.minestom.server.notifications; + +import net.kyori.adventure.text.Component; +import net.minestom.server.advancements.FrameType; +import net.minestom.server.item.ItemStack; +import net.minestom.server.item.Material; +import org.jetbrains.annotations.NotNull; + +/** + * {@inheritDoc} + */ +final class NotificationBuilder implements Notification.Builder { + private Component title; + private FrameType type; + private ItemStack icon; + + /** + * {@inheritDoc} + */ + @Override + public Notification.Builder title(@NotNull Component component) { + this.title = component; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public Notification.Builder frameType(@NotNull FrameType frameType) { + this.type = frameType; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public Notification.Builder icon(@NotNull Material material) { + this.icon = ItemStack.of(material); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public Notification.Builder icon(@NotNull ItemStack itemStack) { + this.icon = itemStack; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public Notification build() { + return new NotificationImpl(title, type, icon); + } +} diff --git a/src/main/java/net/minestom/server/notifications/NotificationImpl.java b/src/main/java/net/minestom/server/notifications/NotificationImpl.java new file mode 100644 index 00000000000..8f03e724c55 --- /dev/null +++ b/src/main/java/net/minestom/server/notifications/NotificationImpl.java @@ -0,0 +1,58 @@ +package net.minestom.server.notifications; + +import net.kyori.adventure.text.Component; +import net.minestom.server.advancements.FrameType; +import net.minestom.server.entity.Player; +import net.minestom.server.item.ItemStack; +import net.minestom.server.network.packet.server.play.AdvancementsPacket; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.List; + +/** + * {@inheritDoc} + */ +record NotificationImpl(@NotNull Component title, @NotNull FrameType type, + @NotNull ItemStack icon) implements Notification { + /** + * {@inheritDoc} + */ + @Override + public void send(@NotNull Player player) { + player.sendPacket(createPacket()); + player.sendPacket(REMOVE_PACKET); + } + + /** + * {@inheritDoc} + */ + @Override + public void send(@NotNull Collection<@NotNull Player> players) { + players.forEach(this::send); + } + + /** + * Create the advancement packet that simulates the notification. + * It's not private because integration tests + * @return the packet + */ + @NotNull AdvancementsPacket createPacket() { + final var displayData = new AdvancementsPacket.DisplayData( + title(), Component.empty(), + icon(), type(), + 0x6, null, 0f, 0f); + + final var criteria = new AdvancementsPacket.Criteria("minestom:some_criteria", + new AdvancementsPacket.CriterionProgress(System.currentTimeMillis())); + + final var advancement = new AdvancementsPacket.Advancement(null, displayData, + List.of(new AdvancementsPacket.Requirement(List.of(criteria.criterionIdentifier()))), + false); + + final var mapping = new AdvancementsPacket.AdvancementMapping(IDENTIFIER, advancement); + final var progressMapping = new AdvancementsPacket.ProgressMapping(IDENTIFIER, + new AdvancementsPacket.AdvancementProgress(List.of(criteria))); + return new AdvancementsPacket(false, List.of(mapping), List.of(), List.of(progressMapping)); + } +} diff --git a/src/main/java/net/minestom/server/notifications/package-info.java b/src/main/java/net/minestom/server/notifications/package-info.java new file mode 100644 index 00000000000..059b6016d8c --- /dev/null +++ b/src/main/java/net/minestom/server/notifications/package-info.java @@ -0,0 +1,12 @@ +/** + * This module contains logic about notification system for the minecraft client. + *

+ * It allows developers to show a toast in the right upper corner with 3 different frame types: + * {@link net.minestom.server.advancements.FrameType#GOAL}, {@link net.minestom.server.advancements.FrameType#TASK} or {@link net.minestom.server.advancements.FrameType#CHALLENGE} + *

+ * + * @since 1.4.1 + * @author TheMeinerLP + * @version 1.0 + */ +package net.minestom.server.notifications; \ No newline at end of file diff --git a/src/main/java/net/minestom/server/ping/ResponseData.java b/src/main/java/net/minestom/server/ping/ResponseData.java index 885d850b020..e3c644f0826 100644 --- a/src/main/java/net/minestom/server/ping/ResponseData.java +++ b/src/main/java/net/minestom/server/ping/ResponseData.java @@ -1,11 +1,7 @@ package net.minestom.server.ping; -import com.google.gson.JsonObject; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; -import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer; import net.minestom.server.MinecraftServer; -import net.minestom.server.entity.Player; import net.minestom.server.event.server.ServerListPingEvent; import net.minestom.server.network.ConnectionManager; import net.minestom.server.network.ConnectionState; @@ -21,9 +17,7 @@ */ public class ResponseData { private static final Component DEFAULT_DESCRIPTION = Component.text("Minestom Server"); - private final List entries; - private String version; private int protocol; private int maxPlayer; @@ -46,17 +40,6 @@ public ResponseData() { this.playersHidden = false; } - /** - * Sets the name for the response. - * - * @param name The name for the response data. - * @deprecated This is named incorrectly, use {@link #setVersion(String)} instead - */ - @Deprecated - public void setName(String name) { - this.setVersion(name); - } - /** * Sets the version name for the response. * @@ -129,88 +112,6 @@ public int getOnline() { return online; } - /** - * Adds some players to the response. - * - * @param players the players - * @deprecated Use {@link #addEntries(Collection)}} - */ - @Deprecated - public void addPlayer(Iterable players) { - for (Player player : players) { - this.addPlayer(player); - } - } - - /** - * Adds a player to the response. - * - * @param player the player - * @deprecated Use {@link #addEntry(NamedAndIdentified)} - */ - @Deprecated - public void addPlayer(Player player) { - this.addEntry(player); - } - - /** - * Adds a player to the response. - * - * @param name The name of the player. - * @param uuid The unique identifier of the player. - * @deprecated Use {@link #addEntry(NamedAndIdentified)} with {@link NamedAndIdentified#of(String, UUID)} - */ - @Deprecated - public void addPlayer(String name, UUID uuid) { - this.addEntry(NamedAndIdentified.of(name, uuid)); - } - - /** - * Adds a player to the response. - *

- * {@link UUID#randomUUID()} is used as the player's UUID. - * - * @param name The name of the player. - * @deprecated Use {@link #addEntry(NamedAndIdentified)} with {@link NamedAndIdentified#named(String)} - */ - @Deprecated - public void addPlayer(String name) { - this.addEntry(NamedAndIdentified.named(name)); - } - - /** - * Removes all of the ping players from this {@link #entries}. The {@link #entries} list - * will be empty this call returns. - * - * @deprecated Use {@link #clearEntries()} - */ - @Deprecated - public void clearPlayers() { - this.clearEntries(); - } - - /** - * Get the list of the response players. - * - * @return the list of the response players. - * @deprecated Use {@link #getEntries()}. This return value is now unmodifiable and this operation is incredibly costly. - */ - @Deprecated(forRemoval = true) // to throw an error for people using it - this method is *horrible* - public List getPlayers() { - return this.entries.stream() - .map(entry -> PingPlayer.of(PlainComponentSerializer.plain().serialize(entry.getName()), entry.getUuid())).toList(); - } - - /** - * Sets the response description. - * - * @param description The description for the response data. - * @deprecated Use {@link #setDescription(Component)} - */ - @Deprecated - public void setDescription(String description) { - this.description = LegacyComponentSerializer.legacySection().deserialize(description); - } /** * Sets the response description. @@ -314,44 +215,4 @@ public void setPlayersHidden(boolean playersHidden) { public boolean arePlayersHidden() { return playersHidden; } - - /** - * Converts the response data into a {@link JsonObject}. - * - * @return The converted response data as a json tree. - * @deprecated Use {@link ServerListPingType#getPingResponse(ResponseData)} - */ - @Deprecated - public @NotNull JsonObject build() { - return ServerListPingType.getModernPingResponse(this, true); - } - - /** - * Represents a player line in the server list hover. - * - * @deprecated See {@link NamedAndIdentified} - */ - @Deprecated - public static class PingPlayer { - - private static @NotNull PingPlayer of(@NotNull String name, @NotNull UUID uuid) { - return new PingPlayer(name, uuid); - } - - private final String name; - private final UUID uuid; - - private PingPlayer(@NotNull String name, @NotNull UUID uuid) { - this.name = name; - this.uuid = uuid; - } - - public @NotNull String getName() { - return name; - } - - public @NotNull UUID getUuid() { - return uuid; - } - } } diff --git a/src/main/java/net/minestom/server/potion/PotionEffectImpl.java b/src/main/java/net/minestom/server/potion/PotionEffectImpl.java index 0e90e62d111..0e214afe3e3 100644 --- a/src/main/java/net/minestom/server/potion/PotionEffectImpl.java +++ b/src/main/java/net/minestom/server/potion/PotionEffectImpl.java @@ -6,8 +6,11 @@ import java.util.Collection; record PotionEffectImpl(Registry.PotionEffectEntry registry) implements PotionEffect { - private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.POTION_EFFECTS, - (namespace, properties) -> new PotionEffectImpl(Registry.potionEffect(namespace, properties))); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.POTION_EFFECTS, PotionEffectImpl::createImpl); + + private static PotionEffect createImpl(String namespace, Registry.Properties properties) { + return new PotionEffectImpl(Registry.potionEffect(namespace, properties)); + } static PotionEffect get(@NotNull String namespace) { return CONTAINER.get(namespace); diff --git a/src/main/java/net/minestom/server/potion/PotionTypeImpl.java b/src/main/java/net/minestom/server/potion/PotionTypeImpl.java index 1cb427ef9b8..719a7cc6ce7 100644 --- a/src/main/java/net/minestom/server/potion/PotionTypeImpl.java +++ b/src/main/java/net/minestom/server/potion/PotionTypeImpl.java @@ -7,8 +7,11 @@ import java.util.Collection; record PotionTypeImpl(NamespaceID namespace, int id) implements PotionType { - private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.POTION_TYPES, - (namespace, properties) -> new PotionTypeImpl(NamespaceID.from(namespace), properties.getInt("id"))); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.POTION_TYPES, PotionTypeImpl::createImpl); + + private static PotionType createImpl(String namespace, Registry.Properties properties) { + return new PotionTypeImpl(NamespaceID.from(namespace), properties.getInt("id")); + } static PotionType get(@NotNull String namespace) { return CONTAINER.get(namespace); diff --git a/src/main/java/net/minestom/server/registry/Registry.java b/src/main/java/net/minestom/server/registry/Registry.java index 8093e7a87ee..bf5e00f52d3 100644 --- a/src/main/java/net/minestom/server/registry/Registry.java +++ b/src/main/java/net/minestom/server/registry/Registry.java @@ -130,6 +130,25 @@ public static JukeboxSongEntry jukeboxSong(String namespace, @NotNull Properties return new JukeboxSongEntry(namespace, main, null); } + @ApiStatus.Internal + public static FluidEntry fluidEntry(String namespace, @NotNull Properties main) { + return new FluidEntry(namespace, main, null); + } + + @ApiStatus.Internal + public static VillagerProfession villagerProfession(String namespace, @NotNull Properties main) { + return new VillagerProfession(namespace, main, null); + } + + @ApiStatus.Internal + public static VillagerType villagerType(String namespace, @NotNull Properties main) { + return new VillagerType(namespace, main, null); + } + + public static GameEventEntry gameEventEntry(String namespace, Properties properties) { + return new GameEventEntry(namespace, properties, null); + } + @ApiStatus.Internal public static Map> load(Resource resource) { Map> map = new HashMap<>(); @@ -226,6 +245,8 @@ public enum Resource { ENTITY_TYPE_TAGS("tags/entity_type.json"), FLUID_TAGS("tags/fluid.json"), GAMEPLAY_TAGS("tags/game_event.json"), + GAME_EVENTS("game_events.json"), + BIOME_TAGS("tags/biome.json"), ITEM_TAGS("tags/item.json"), ENCHANTMENT_TAGS("tags/enchantment.json"), DIMENSION_TYPES("dimension_types.json"), @@ -236,7 +257,11 @@ public enum Resource { CHAT_TYPES("chat_types.json"), ENCHANTMENTS("enchantments.snbt"), PAINTING_VARIANTS("painting_variants.json"), - JUKEBOX_SONGS("jukebox_songs.json"); + JUKEBOX_SONGS("jukebox_songs.json"), + VILLAGER_PROFESSION("villager_professions.json"), + VILLAGER_TYPES("villager_types.json"), + FLUIDS("fluids.json"), + ; private final String name; @@ -249,6 +274,20 @@ public enum Resource { } } + public record FluidEntry( + @NotNull NamespaceID namespace, + @NotNull NamespaceID bucketId, + @Nullable Properties custom + ) implements Entry { + + public FluidEntry(String namespace, Properties main, Properties custom) { + this(NamespaceID.from(namespace), + NamespaceID.from(main.getString("bucketId")), + custom + ); + } + } + public static final class BlockEntry implements Entry { private final NamespaceID namespace; private final int id; @@ -525,6 +564,12 @@ public boolean hasPrecipitation() { } } + public record GameEventEntry(NamespaceID namespace, Properties main, Properties custom) implements Entry { + public GameEventEntry(String namespace, Properties main, Properties custom) { + this(NamespaceID.from(namespace), main, custom); + } + } + public static final class MaterialEntry implements Entry { private final NamespaceID namespace; private final Properties main; @@ -779,6 +824,25 @@ public TrimPatternEntry(@NotNull String namespace, @NotNull Properties main, Pro } } + public record VillagerProfession(NamespaceID namespace, int id, SoundEvent soundEvent, Properties custom) implements Entry { + public VillagerProfession(String namespace, + Properties main, + Properties custom) { + this(NamespaceID.from(namespace), + main.getInt("id"), + SoundEvent.fromNamespaceId(main.getString("workSound")), + custom); + } + } + + public record VillagerType(NamespaceID namespace, int id, Properties custom) implements Entry { + public VillagerType(String namespace, Properties main, Properties custom) { + this(NamespaceID.from(namespace), + main.getInt("id"), + custom); + } + } + public record PotionEffectEntry(NamespaceID namespace, int id, String translationKey, int color, diff --git a/src/main/java/net/minestom/server/registry/StaticProtocolObject.java b/src/main/java/net/minestom/server/registry/StaticProtocolObject.java index a1dc1790aba..4ba895df31c 100644 --- a/src/main/java/net/minestom/server/registry/StaticProtocolObject.java +++ b/src/main/java/net/minestom/server/registry/StaticProtocolObject.java @@ -6,22 +6,50 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; +/** + * Represents a static protocol object. + * Used for objects which are not dynamic and are known at compile time. + * + * @version 1.0.0 + * @since 1.0.0 + * @author themeinerlp + */ public interface StaticProtocolObject extends ProtocolObject, Keyed { + /** + * Gets the namespace ID of this object. + * + * @return the namespace ID + */ @Contract(pure = true) @NotNull NamespaceID namespace(); + /** + * Gets the name of this object. + * + * @return the name + */ @Contract(pure = true) default @NotNull String name() { return namespace().asString(); } + /** + * Gets the key of this object. + * + * @return the key + */ @Override @Contract(pure = true) default @NotNull Key key() { return namespace(); } + /** + * Gets the ID of this object. + * + * @return the ID + */ @Contract(pure = true) int id(); } diff --git a/src/main/java/net/minestom/server/scoreboard/BelowNameTag.java b/src/main/java/net/minestom/server/scoreboard/BelowNameTag.java index b5817c96772..5e85964a527 100644 --- a/src/main/java/net/minestom/server/scoreboard/BelowNameTag.java +++ b/src/main/java/net/minestom/server/scoreboard/BelowNameTag.java @@ -25,18 +25,6 @@ public class BelowNameTag implements Scoreboard { private final ScoreboardObjectivePacket scoreboardObjectivePacket; - /** - * Creates a new below name scoreboard. - * - * @param name The objective name of the scoreboard - * @param value The value of the scoreboard - * @deprecated Use {@link #BelowNameTag(String, Component)} - */ - @Deprecated - public BelowNameTag(String name, String value) { - this(name, Component.text(value)); - } - /** * Creates a new below name scoreboard. * diff --git a/src/main/java/net/minestom/server/scoreboard/Scoreboard.java b/src/main/java/net/minestom/server/scoreboard/Scoreboard.java index ca3faecdd7a..ddc42f51f48 100644 --- a/src/main/java/net/minestom/server/scoreboard/Scoreboard.java +++ b/src/main/java/net/minestom/server/scoreboard/Scoreboard.java @@ -15,20 +15,6 @@ */ public interface Scoreboard extends Viewable, PacketGroupingAudience { - /** - * Creates a creation objective packet. - * - * @param value The value for the objective - * @param type The type for the objective - * @return the creation objective packet - * @deprecated Use {@link #getCreationObjectivePacket(Component, ScoreboardObjectivePacket.Type)} - */ - @Deprecated - @NotNull - default ScoreboardObjectivePacket getCreationObjectivePacket(String value, ScoreboardObjectivePacket.Type type) { - return this.getCreationObjectivePacket(Component.text(value), type); - } - /** * Creates a creation objective packet. * diff --git a/src/main/java/net/minestom/server/scoreboard/Sidebar.java b/src/main/java/net/minestom/server/scoreboard/Sidebar.java index d35dd8e0478..03778ff4a36 100644 --- a/src/main/java/net/minestom/server/scoreboard/Sidebar.java +++ b/src/main/java/net/minestom/server/scoreboard/Sidebar.java @@ -19,7 +19,7 @@ /** * Represents a sidebar which can contain up to 16 {@link ScoreboardLine}. *

- * In order to use it you need to create a new instance using the constructor {@link #Sidebar(String)} and create new lines + * In order to use it you need to create a new instance using the constructor {@link #Sidebar(Component)} and create new lines * with {@link #createLine(ScoreboardLine)}. You can then add a {@link Player} to the viewing list using {@link #addViewer(Player)} * and remove him later with {@link #removeViewer(Player)}. *

@@ -50,17 +50,6 @@ public class Sidebar implements Scoreboard { private Component title; - /** - * Creates a new sidebar - * - * @param title The title of the sidebar - * @deprecated Use {@link #Sidebar(Component)} - */ - @Deprecated - public Sidebar(@NotNull String title) { - this(Component.text(title)); - } - /** * Creates a new sidebar * @@ -77,17 +66,6 @@ public Sidebar(@NotNull Component title) { } } - /** - * Changes the {@link Sidebar} title - * - * @param title The new sidebar title - * @deprecated Use {@link #setTitle(Component)} - */ - @Deprecated - public void setTitle(@NotNull String title) { - this.setTitle(Component.text(title)); - } - /** * Changes the {@link Sidebar} title * diff --git a/src/main/java/net/minestom/server/statistic/StatisticTypeImpl.java b/src/main/java/net/minestom/server/statistic/StatisticTypeImpl.java index 40606e211dd..0d19b60d457 100644 --- a/src/main/java/net/minestom/server/statistic/StatisticTypeImpl.java +++ b/src/main/java/net/minestom/server/statistic/StatisticTypeImpl.java @@ -7,8 +7,11 @@ import java.util.Collection; record StatisticTypeImpl(NamespaceID namespace, int id) implements StatisticType { - private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.STATISTICS, - (namespace, properties) -> new StatisticTypeImpl(NamespaceID.from(namespace), properties.getInt("id"))); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.STATISTICS, StatisticTypeImpl::createImpl); + + private static StatisticType createImpl(String namespace, Registry.Properties properties) { + return new StatisticTypeImpl(NamespaceID.from(namespace), properties.getInt("id")); + } static StatisticType get(@NotNull String namespace) { return CONTAINER.get(namespace); diff --git a/src/main/java/net/minestom/server/tag/TagNbtSeparator.java b/src/main/java/net/minestom/server/tag/TagNbtSeparator.java index 83ea125f1bf..93584dbb606 100644 --- a/src/main/java/net/minestom/server/tag/TagNbtSeparator.java +++ b/src/main/java/net/minestom/server/tag/TagNbtSeparator.java @@ -1,6 +1,7 @@ package net.minestom.server.tag; import net.kyori.adventure.nbt.*; +import net.minestom.server.MinecraftServer; import net.minestom.server.utils.nbt.BinaryTagUtil; import java.util.ArrayList; @@ -72,7 +73,7 @@ private static void convert(List path, String key, BinaryTag nbt, Consum } consumer.accept(makeEntry(path, Tag.class.cast(tag), List.of(values))); } catch (Exception e) { - e.printStackTrace(); + MinecraftServer.getExceptionManager().handleException(e); consumer.accept(makeEntry(path, Tag.NBT(key), nbt)); } } diff --git a/src/main/java/net/minestom/server/terminal/MinestomConsoleWriter.java b/src/main/java/net/minestom/server/terminal/MinestomConsoleWriter.java new file mode 100644 index 00000000000..738c3d0ba9b --- /dev/null +++ b/src/main/java/net/minestom/server/terminal/MinestomConsoleWriter.java @@ -0,0 +1,36 @@ +package net.minestom.server.terminal; + +import org.fusesource.jansi.AnsiConsole; +import org.tinylog.core.LogEntry; +import org.tinylog.writers.AbstractFormatPatternWriter; + +import java.util.Map; + +import static net.minestom.server.terminal.MinestomTerminal.reader; + +public final class MinestomConsoleWriter extends AbstractFormatPatternWriter { + public MinestomConsoleWriter(Map properties) { + super(properties); + } + + @Override + public void write(LogEntry logEntry) throws Exception { + String rendered = render(logEntry); + String formatted = TerminalColorConverter.format(rendered); + if (reader != null) { + reader.printAbove(formatted); + } else { + AnsiConsole.out().print(formatted); + } + } + + @Override + public void flush() { + // EMPTY + } + + @Override + public void close() { + // EMPTY + } +} diff --git a/src/main/java/net/minestom/server/terminal/MinestomTerminal.java b/src/main/java/net/minestom/server/terminal/MinestomTerminal.java new file mode 100644 index 00000000000..a71fca4ffa1 --- /dev/null +++ b/src/main/java/net/minestom/server/terminal/MinestomTerminal.java @@ -0,0 +1,100 @@ +package net.minestom.server.terminal; + +import net.minestom.server.MinecraftServer; +import net.minestom.server.command.builder.Command; +import net.minestom.server.command.builder.suggestion.Suggestion; +import net.minestom.server.command.builder.suggestion.SuggestionEntry; +import net.minestom.server.listener.TabCompleteListener; +import org.jetbrains.annotations.ApiStatus; +import org.jline.reader.Candidate; +import org.jline.reader.Completer; +import org.jline.reader.EndOfFileException; +import org.jline.reader.LineReader; +import org.jline.reader.LineReaderBuilder; +import org.jline.reader.ParsedLine; +import org.jline.reader.UserInterruptException; +import org.jline.terminal.Terminal; +import org.jline.terminal.TerminalBuilder; + +import java.io.IOException; +import java.util.List; + +public class MinestomTerminal { + private static final String PROMPT = "> "; + private static volatile Terminal terminal; + static volatile LineReader reader; + private static volatile boolean running = false; + + @ApiStatus.Internal + public static void start() { + final Thread thread = new Thread(null, () -> { + try { + terminal = TerminalBuilder.terminal(); + } catch (IOException e) { + MinecraftServer.getExceptionManager().handleException(e); + } + reader = LineReaderBuilder.builder() + .completer(new MinestomCompleter()) + .terminal(terminal) + .build(); + running = true; + + while (running) { + String command; + try { + command = reader.readLine(PROMPT); + var commandManager = MinecraftServer.getCommandManager(); + commandManager.execute(commandManager.getConsoleSender(), command); + } catch (UserInterruptException e) { + // Handle Ctrl + C + System.exit(0); + return; + } catch (EndOfFileException e) { + return; + } + } + }, "Jline"); + thread.setDaemon(true); + thread.start(); + } + + @ApiStatus.Internal + public static void stop() { + running = false; + if (terminal != null) { + try { + terminal.close(); + } catch (IOException e) { + MinecraftServer.getExceptionManager().handleException(e); + } + reader = null; + } + } + + private static final class MinestomCompleter implements Completer { + @Override + public void complete(LineReader reader, ParsedLine line, List candidates) { + final var commandManager = MinecraftServer.getCommandManager(); + final var consoleSender = commandManager.getConsoleSender(); + if (line.wordIndex() == 0) { + final String commandString = line.word().toLowerCase(); + candidates.addAll( + commandManager.getDispatcher().getCommands().stream() + .map(Command::getName) + .filter(name -> commandString.isBlank() || name.toLowerCase().startsWith(commandString)) + .map(Candidate::new) + .toList() + ); + } else { + final String text = line.line(); + final Suggestion suggestion = TabCompleteListener.getSuggestion(consoleSender, text); + if (suggestion != null) { + suggestion.getEntries().stream() + .map(SuggestionEntry::getEntry) + .map(Candidate::new) + .forEach(candidates::add); + } + } + } + } +} diff --git a/src/main/java/net/minestom/server/terminal/TerminalColorConverter.java b/src/main/java/net/minestom/server/terminal/TerminalColorConverter.java new file mode 100644 index 00000000000..2c9fc094e28 --- /dev/null +++ b/src/main/java/net/minestom/server/terminal/TerminalColorConverter.java @@ -0,0 +1,100 @@ +package net.minestom.server.terminal; + +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import net.minestom.server.ServerFlag; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * A string converter to convert a string to an ansi-colored one. + * + * @see TerminalConsoleAppender + * @see Paper + */ +final class TerminalColorConverter { + + private static final String RGB_ANSI = "\u001B[38;2;%d;%d;%dm"; + private static final String ANSI_RESET = "\u001B[m"; + private static final String LOOKUP = "0123456789abcdefklmnor"; + private static final String[] ANSI_CODES = new String[]{ + getAnsiColor(NamedTextColor.BLACK, "\u001B[0;30m"), // Black §0 + getAnsiColor(NamedTextColor.DARK_BLUE, "\u001B[0;34m"), // Dark Blue §1 + getAnsiColor(NamedTextColor.DARK_GREEN, "\u001B[0;32m"), // Dark Green §2 + getAnsiColor(NamedTextColor.DARK_AQUA, "\u001B[0;36m"), // Dark Aqua §3 + getAnsiColor(NamedTextColor.DARK_RED, "\u001B[0;31m"), // Dark Red §4 + getAnsiColor(NamedTextColor.DARK_PURPLE, "\u001B[0;35m"), // Dark Purple §5 + getAnsiColor(NamedTextColor.GOLD, "\u001B[0;33m"), // Gold §6 + getAnsiColor(NamedTextColor.GRAY, "\u001B[0;37m"), // Gray §7 + getAnsiColor(NamedTextColor.DARK_GRAY, "\u001B[0;30;1m"), // Dark Gray §8 + getAnsiColor(NamedTextColor.BLUE, "\u001B[0;34;1m"), // Blue §9 + getAnsiColor(NamedTextColor.GREEN, "\u001B[0;32;1m"), // Green §a + getAnsiColor(NamedTextColor.AQUA, "\u001B[0;36;1m"), // Aqua §b + getAnsiColor(NamedTextColor.RED, "\u001B[0;31;1m"), // Red §c + getAnsiColor(NamedTextColor.LIGHT_PURPLE, "\u001B[0;35;1m"), // Light Purple §d + getAnsiColor(NamedTextColor.YELLOW, "\u001B[0;33;1m"), // Yellow §e + getAnsiColor(NamedTextColor.WHITE, "\u001B[0;37;1m"), // White §f + "\u001B[5m", // Obfuscated §k + "\u001B[1m", // Bold §l + "\u001B[9m", // Strikethrough §m + "\u001B[4m", // Underline §n + "\u001B[3m", // Italic §o + ANSI_RESET, // Reset §r + }; + private static final Pattern RGB_PATTERN = Pattern.compile(LegacyComponentSerializer.SECTION_CHAR + "#([\\da-fA-F]{6})"); + private static final Pattern NAMED_PATTERN = Pattern.compile(LegacyComponentSerializer.SECTION_CHAR + "([\\da-fk-orA-FK-OR])"); + + private TerminalColorConverter() { + } + + private static String getAnsiColor(NamedTextColor color, String fallback) { + return getAnsiColorFromHexColor(color.value(), fallback); + } + + private static String getAnsiColorFromHexColor(int color, String fallback) { + return ServerFlag.TERMINAL_SUPPORT_HEX_COLOR ? String.format(RGB_ANSI, (color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF) : fallback; + } + + private static String getAnsiColorFromHexColor(int color) { + return getAnsiColorFromHexColor(color, ""); + } + + /** + * Format the colored string to an ansi-colored one. + * + * @param string the string to format + * @return the formatted string + */ + public static String format(String string) { + if (string.indexOf(LegacyComponentSerializer.SECTION_CHAR) == -1) { + return string; + } + + string = RGB_PATTERN.matcher(string).replaceAll(match -> { + if (ServerFlag.TERMINAL_SUPPORT_COLOR) { + String hex = match.group(1); + return getAnsiColorFromHexColor(Integer.parseInt(hex, 16)); + } else { + return ""; + } + }); + + Matcher matcher = NAMED_PATTERN.matcher(string); + StringBuilder builder = new StringBuilder(); + while (matcher.find()) { + int format = LOOKUP.indexOf(Character.toLowerCase(matcher.group().charAt(1))); + if (format != -1) { + matcher.appendReplacement(builder, ServerFlag.TERMINAL_SUPPORT_COLOR ? ANSI_CODES[format] : ""); + } else { + matcher.appendReplacement(builder, matcher.group()); + } + } + matcher.appendTail(builder); + + if (ServerFlag.TERMINAL_SUPPORT_COLOR) { + builder.append(ANSI_RESET); + } + return builder.toString(); + } +} diff --git a/src/main/java/net/minestom/server/thread/Acquirable.java b/src/main/java/net/minestom/server/thread/Acquirable.java index ab56f33af80..ece76148a83 100644 --- a/src/main/java/net/minestom/server/thread/Acquirable.java +++ b/src/main/java/net/minestom/server/thread/Acquirable.java @@ -26,8 +26,8 @@ public sealed interface Acquirable permits AcquirableImpl { if (currentThread instanceof TickThread) { return ((TickThread) currentThread).entries().stream() .flatMap(partitionEntry -> partitionEntry.elements().stream()) - .filter(tickable -> tickable instanceof Entity) - .map(tickable -> (Entity) tickable); + .filter(Entity.class::isInstance) //Microtus - update java keyword usage + .map(Entity.class::cast); //Microtus - update java keyword usage } return Stream.empty(); } diff --git a/src/main/java/net/minestom/server/utils/ArrayUtils.java b/src/main/java/net/minestom/server/utils/ArrayUtils.java index de23b16d13d..ca21c1a23c1 100644 --- a/src/main/java/net/minestom/server/utils/ArrayUtils.java +++ b/src/main/java/net/minestom/server/utils/ArrayUtils.java @@ -15,7 +15,7 @@ public final class ArrayUtils { private ArrayUtils() { } - public static boolean isEmpty(@Nullable Object @NotNull [] array) { + public static boolean isEmpty(@Nullable Object[] array) { for (Object object : array) { if (object != null) return false; } diff --git a/src/main/java/net/minestom/server/utils/TickUtils.java b/src/main/java/net/minestom/server/utils/TickUtils.java index 84ac9ec1436..15bdbee8558 100644 --- a/src/main/java/net/minestom/server/utils/TickUtils.java +++ b/src/main/java/net/minestom/server/utils/TickUtils.java @@ -43,4 +43,9 @@ public static int fromDuration(@NotNull Duration duration, int msPerTick) { Check.argCondition(duration.isNegative(), "Duration cannot be negative"); return (int) (duration.toMillis() / msPerTick); } + + /** + * Default private default constructor. + */ + private TickUtils() { } } diff --git a/src/main/java/net/minestom/server/utils/UniqueIdUtils.java b/src/main/java/net/minestom/server/utils/UniqueIdUtils.java index 8d04807afb2..93c6d86ea39 100644 --- a/src/main/java/net/minestom/server/utils/UniqueIdUtils.java +++ b/src/main/java/net/minestom/server/utils/UniqueIdUtils.java @@ -12,16 +12,21 @@ */ @ApiStatus.Internal public final class UniqueIdUtils { + + public static final String UUID_GROUP_REPLACEMENT = "$1-$2-$3-$4-$5"; // Microtus - improve string pattern usage public static final Pattern UNIQUE_ID_PATTERN = Pattern.compile("\\b[0-9a-f]{8}\\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\\b[0-9a-f]{12}\\b"); + // Microtus - improve string pattern usage + add private constructor + private UniqueIdUtils() {} + /** * Checks whether the {@code input} string is an {@link UUID}. * * @param input The input string to be checked * @return {@code true} if the input an unique identifier, otherwise {@code false} */ - public static boolean isUniqueId(String input) { - return input.matches(UNIQUE_ID_PATTERN.pattern()); + public static boolean isUniqueId(@NotNull String input) { + return !input.trim().isEmpty() && UNIQUE_ID_PATTERN.matcher(input).matches(); // Microtus - improve string pattern usage } public static @NotNull UUID fromNbt(@NotNull IntArrayBinaryTag tag) { diff --git a/src/main/java/net/minestom/server/utils/mojang/MojangUtils.java b/src/main/java/net/minestom/server/utils/mojang/MojangUtils.java index e4aa269faec..dab724b018e 100644 --- a/src/main/java/net/minestom/server/utils/mojang/MojangUtils.java +++ b/src/main/java/net/minestom/server/utils/mojang/MojangUtils.java @@ -9,6 +9,7 @@ import java.io.IOException; import java.util.UUID; +import java.util.regex.Pattern; /** * Utils class using mojang API. @@ -16,6 +17,12 @@ public final class MojangUtils { private static final String FROM_UUID_URL = "https://sessionserver.mojang.com/session/minecraft/profile/%s?unsigned=false"; private static final String FROM_USERNAME_URL = "https://api.mojang.com/users/profiles/minecraft/%s"; + private static final Pattern UUID_PATTERN = + Pattern.compile("(\\p{XDigit}{8})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}+)"); + + private MojangUtils() { + // Private constructor to prevent instantiation of the utility class + } /** * Gets a player's UUID from their username @@ -27,14 +34,8 @@ public final class MojangUtils { @Blocking public static @NotNull UUID getUUID(String username) throws IOException { // Thanks stackoverflow: https://stackoverflow.com/a/19399768/13247146 - return UUID.fromString( - retrieve(String.format(FROM_USERNAME_URL, username)).get("id") - .getAsString() - .replaceFirst( - "(\\p{XDigit}{8})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}+)", - "$1-$2-$3-$4-$5" - ) - ); + String uuidString = retrieve(String.format(FROM_USERNAME_URL, username)).get("id").getAsString(); + return UUID.fromString(UUID_PATTERN.matcher(uuidString).replaceFirst("$1-$2-$3-$4-$5")); } /** diff --git a/src/main/java/net/minestom/server/utils/time/TimeUnit.java b/src/main/java/net/minestom/server/utils/time/TimeUnit.java index 7e181a47c91..43e25a3f283 100644 --- a/src/main/java/net/minestom/server/utils/time/TimeUnit.java +++ b/src/main/java/net/minestom/server/utils/time/TimeUnit.java @@ -11,11 +11,6 @@ public final class TimeUnit { public static final TemporalUnit MILLISECOND = ChronoUnit.MILLIS; public static final TemporalUnit SERVER_TICK = Tick.SERVER_TICKS; public static final TemporalUnit CLIENT_TICK = Tick.CLIENT_TICKS; - /** - * @deprecated Please use either {@link #SERVER_TICK} or {@link #CLIENT_TICK} - */ - @Deprecated(forRemoval = true) - public static final TemporalUnit TICK = CLIENT_TICK; private TimeUnit() { } diff --git a/src/main/java/net/minestom/server/world/biome/Biome.java b/src/main/java/net/minestom/server/world/biome/Biome.java index 30ba781b312..7276a7b912c 100644 --- a/src/main/java/net/minestom/server/world/biome/Biome.java +++ b/src/main/java/net/minestom/server/world/biome/Biome.java @@ -1,5 +1,6 @@ package net.minestom.server.world.biome; +import java.util.Locale; import net.minestom.server.coordinate.Point; import net.minestom.server.registry.DynamicRegistry; import net.minestom.server.registry.ProtocolObject; diff --git a/src/test/java/net/minestom/server/InsideTest.java b/src/test/java/net/minestom/server/InsideTest.java index 9adbea2e1e7..ee7564c2a56 100644 --- a/src/test/java/net/minestom/server/InsideTest.java +++ b/src/test/java/net/minestom/server/InsideTest.java @@ -4,9 +4,9 @@ import static org.junit.jupiter.api.Assertions.assertTrue; -public class InsideTest { +class InsideTest { @Test - public void inside() { + void inside() { assertTrue(ServerFlag.INSIDE_TEST); } } diff --git a/src/test/java/net/minestom/server/ServerProcessTest.java b/src/test/java/net/minestom/server/ServerProcessTest.java index 23fc5c7f2ec..00259a2531b 100644 --- a/src/test/java/net/minestom/server/ServerProcessTest.java +++ b/src/test/java/net/minestom/server/ServerProcessTest.java @@ -9,10 +9,10 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assumptions.assumeTrue; -public class ServerProcessTest { +class ServerProcessTest { @Test - public void init() { + void init() { // These like to fail on github actions assumeTrue(System.getenv("GITHUB_ACTIONS") == null); @@ -21,10 +21,11 @@ public void init() { assertDoesNotThrow(() -> process.get().start(new InetSocketAddress("localhost", 25565))); assertThrows(Exception.class, () -> process.get().start(new InetSocketAddress("localhost", 25566))); assertDoesNotThrow(() -> process.get().stop()); + process.set(null); } @Test - public void tick() { + void tick() { // These like to fail on github actions assumeTrue(System.getenv("GITHUB_ACTIONS") == null); diff --git a/src/test/java/net/minestom/server/advancements/AdvancementIntegrationTest.java b/src/test/java/net/minestom/server/advancements/AdvancementIntegrationTest.java index d74d97e8b82..59b5877031a 100644 --- a/src/test/java/net/minestom/server/advancements/AdvancementIntegrationTest.java +++ b/src/test/java/net/minestom/server/advancements/AdvancementIntegrationTest.java @@ -2,18 +2,19 @@ import net.kyori.adventure.text.Component; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Pos; import net.minestom.server.item.Material; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.*; -@EnvTest -public class AdvancementIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class AdvancementIntegrationTest { @Test - public void addAndRemoveViewer(Env env) { + void addAndRemoveViewer(Env env) { var instance = env.createFlatInstance(); var player = env.createPlayer(instance, new Pos(0, 42, 0)); @@ -46,7 +47,7 @@ public void addAndRemoveViewer(Env env) { } @Test - public void removeViewerOnDisconnect(Env env) { + void removeViewerOnDisconnect(Env env) { var instance = env.createFlatInstance(); var player = env.createPlayer(instance, new Pos(0, 42, 0)); diff --git a/src/test/java/net/minestom/server/adventure/provider/TranslationTest.java b/src/test/java/net/minestom/server/adventure/provider/TranslationTest.java index 6754317b800..fa2ea6380af 100644 --- a/src/test/java/net/minestom/server/adventure/provider/TranslationTest.java +++ b/src/test/java/net/minestom/server/adventure/provider/TranslationTest.java @@ -4,10 +4,10 @@ import net.minestom.server.adventure.MinestomAdventure; import org.junit.jupiter.api.Test; -public class TranslationTest { +class TranslationTest { @Test - public void testUnregisteredTranslation() { + void testUnregisteredTranslation() { MinestomAdventure.AUTOMATIC_COMPONENT_TRANSLATION = true; try { MinestomFlattenerProvider.INSTANCE.flatten(Component.translatable("key.unregistered"), text -> { diff --git a/src/test/java/net/minestom/server/collision/EntityBlockPhysicsIntegrationTest.java b/src/test/java/net/minestom/server/collision/EntityBlockPhysicsIntegrationTest.java index 0801f00fe72..13f9f76be86 100644 --- a/src/test/java/net/minestom/server/collision/EntityBlockPhysicsIntegrationTest.java +++ b/src/test/java/net/minestom/server/collision/EntityBlockPhysicsIntegrationTest.java @@ -2,7 +2,6 @@ import net.minestom.server.utils.block.BlockIterator; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Point; import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Vec; @@ -10,7 +9,9 @@ import net.minestom.server.entity.EntityType; import net.minestom.server.entity.metadata.other.SlimeMeta; import net.minestom.server.instance.block.Block; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.Arrays; import java.util.Iterator; @@ -19,8 +20,8 @@ import static org.junit.jupiter.api.Assertions.*; -@EnvTest -public class EntityBlockPhysicsIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class EntityBlockPhysicsIntegrationTest { private static final Point PRECISION = new Pos(0.01, 0.01, 0.01); private static boolean checkPoints(Point expected, Point actual) { @@ -48,7 +49,7 @@ private static void assertPossiblePoints(List expected, Point actual) { } @Test - public void entityPhysicsCheckCollision(Env env) { + void entityPhysicsCheckCollision(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 43, 1, Block.STONE); @@ -76,7 +77,7 @@ public void entityPhysicsCheckShortDiagonal(Env env) { } @Test - public void entityPhysicsCheckSlab(Env env) { + void entityPhysicsCheckSlab(Env env) { var instance = env.createFlatInstance(); for (int i = -2; i <= 2; ++i) @@ -94,7 +95,7 @@ public void entityPhysicsCheckSlab(Env env) { } @Test - public void entityPhysicsCheckShallowAngle(Env env) { + void entityPhysicsCheckShallowAngle(Env env) { var instance = env.createFlatInstance(); instance.setBlock(13, 99, 16, Block.STONE); @@ -109,7 +110,7 @@ public void entityPhysicsCheckShallowAngle(Env env) { } @Test - public void entityPhysicsCheckFallFence(Env env) { + void entityPhysicsCheckFallFence(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 42, 0, Block.OAK_FENCE); @@ -122,7 +123,7 @@ public void entityPhysicsCheckFallFence(Env env) { } @Test - public void entityPhysicsCheckFallHitCarpet(Env env) { + void entityPhysicsCheckFallHitCarpet(Env env) { var instance = env.createFlatInstance(); for (int i = -2; i <= 2; ++i) @@ -141,7 +142,7 @@ public void entityPhysicsCheckFallHitCarpet(Env env) { } @Test - public void entityPhysicsCheckFallHitFence(Env env) { + void entityPhysicsCheckFallHitFence(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 42, 0, Block.OAK_FENCE); instance.setBlock(0, 43, 0, Block.BROWN_CARPET); @@ -155,7 +156,7 @@ public void entityPhysicsCheckFallHitFence(Env env) { } @Test - public void entityPhysicsCheckHorizontalFence(Env env) { + void entityPhysicsCheckHorizontalFence(Env env) { var instance = env.createFlatInstance(); instance.setBlock(1, 42, 0, Block.OAK_FENCE); @@ -168,7 +169,7 @@ public void entityPhysicsCheckHorizontalFence(Env env) { } @Test - public void entityPhysicsCheckMultipleBlocksPassFirst(Env env) { + void entityPhysicsCheckMultipleBlocksPassFirst(Env env) { var instance = env.createFlatInstance(); instance.setBlock(4, 40, -1, Block.SANDSTONE_STAIRS); instance.setBlock(16, 40, 0, Block.STONE); @@ -182,7 +183,7 @@ public void entityPhysicsCheckMultipleBlocksPassFirst(Env env) { } @Test - public void entityPhysicsCheckMultipleBlocksHitFirst(Env env) { + void entityPhysicsCheckMultipleBlocksHitFirst(Env env) { var instance = env.createFlatInstance(); instance.setBlock(4, 40, 0, Block.GRASS_BLOCK); instance.setBlock(16, 40, 0, Block.STONE); @@ -199,7 +200,7 @@ public void entityPhysicsCheckMultipleBlocksHitFirst(Env env) { } @Test - public void entityPhysicsCheckHorizontalCarpetedFence(Env env) { + void entityPhysicsCheckHorizontalCarpetedFence(Env env) { var instance = env.createFlatInstance(); instance.setBlock(1, 42, 0, Block.OAK_FENCE); instance.setBlock(1, 43, 0, Block.BROWN_CARPET); @@ -213,7 +214,7 @@ public void entityPhysicsCheckHorizontalCarpetedFence(Env env) { } @Test - public void entityPhysicsCheckDiagonalCarpetedFenceX(Env env) { + void entityPhysicsCheckDiagonalCarpetedFenceX(Env env) { var instance = env.createFlatInstance(); for (int i = -2; i <= 2; ++i) @@ -232,7 +233,7 @@ public void entityPhysicsCheckDiagonalCarpetedFenceX(Env env) { } @Test - public void entityPhysicsCheckDiagonalCarpetedFenceZ(Env env) { + void entityPhysicsCheckDiagonalCarpetedFenceZ(Env env) { var instance = env.createFlatInstance(); for (int i = -2; i <= 2; ++i) @@ -251,7 +252,7 @@ public void entityPhysicsCheckDiagonalCarpetedFenceZ(Env env) { } @Test - public void entityPhysicsCheckDiagonalCarpetedFenceXZ(Env env) { + void entityPhysicsCheckDiagonalCarpetedFenceXZ(Env env) { var instance = env.createFlatInstance(); for (int i = -2; i <= 2; ++i) @@ -282,7 +283,7 @@ public void entityPhysicsCheckDiagonalCarpetedFenceXZ(Env env) { } @Test - public void entityPhysicsCheckFallHitFenceLongMove(Env env) { + void entityPhysicsCheckFallHitFenceLongMove(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 42, 0, Block.OAK_FENCE); instance.setBlock(0, 43, 0, Block.BROWN_CARPET); @@ -296,7 +297,7 @@ public void entityPhysicsCheckFallHitFenceLongMove(Env env) { } @Test - public void entityPhysicsCheckFenceAboveHead(Env env) { + void entityPhysicsCheckFenceAboveHead(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 45, 0, Block.OAK_FENCE); @@ -310,7 +311,7 @@ public void entityPhysicsCheckFenceAboveHead(Env env) { } @Test - public void entityPhysicsCheckDiagonal(Env env) { + void entityPhysicsCheckDiagonal(Env env) { var instance = env.createFlatInstance(); instance.setBlock(1, 43, 1, Block.STONE); instance.setBlock(1, 43, 2, Block.STONE); @@ -326,7 +327,7 @@ public void entityPhysicsCheckDiagonal(Env env) { } @Test - public void entityPhysicsCheckDirectSlide(Env env) { + void entityPhysicsCheckDirectSlide(Env env) { var instance = env.createFlatInstance(); instance.setBlock(1, 43, 1, Block.STONE); instance.setBlock(1, 43, 2, Block.STONE); @@ -340,7 +341,7 @@ public void entityPhysicsCheckDirectSlide(Env env) { } @Test - public void entityPhysicsCheckCorner(Env env) { + void entityPhysicsCheckCorner(Env env) { var instance = env.createFlatInstance(); for (int i = -2; i <= 2; ++i) for (int j = -2; j <= 2; ++j) @@ -359,7 +360,7 @@ public void entityPhysicsCheckCorner(Env env) { } @Test - public void entityPhysicsCheckEnclosedHit(Env env) { + void entityPhysicsCheckEnclosedHit(Env env) { var instance = env.createFlatInstance(); for (int i = -2; i <= 2; ++i) for (int j = -2; j <= 2; ++j) @@ -381,7 +382,7 @@ public void entityPhysicsCheckEnclosedHit(Env env) { } @Test - public void entityPhysicsCheckEnclosedHitSubBlock(Env env) { + void entityPhysicsCheckEnclosedHitSubBlock(Env env) { var instance = env.createFlatInstance(); for (int i = -2; i <= 2; ++i) for (int j = -2; j <= 2; ++j) @@ -403,7 +404,7 @@ public void entityPhysicsCheckEnclosedHitSubBlock(Env env) { } @Test - public void entityPhysicsCheckEnclosedMiss(Env env) { + void entityPhysicsCheckEnclosedMiss(Env env) { var instance = env.createFlatInstance(); instance.setBlock(11, 43, 11, Block.STONE); @@ -420,7 +421,7 @@ public void entityPhysicsCheckEnclosedMiss(Env env) { } @Test - public void entityPhysicsCheckEntityHit(Env env) { + void entityPhysicsCheckEntityHit() { Point z1 = new Pos(0, 0, 0); Point z2 = new Pos(15, 0, 0); Point z3 = new Pos(11, 0, 0); @@ -438,7 +439,7 @@ public void entityPhysicsCheckEntityHit(Env env) { } @Test - public void entityPhysicsCheckEdgeClip(Env env) { + void entityPhysicsCheckEdgeClip(Env env) { var instance = env.createFlatInstance(); instance.setBlock(1, 43, 1, Block.STONE); @@ -451,7 +452,7 @@ public void entityPhysicsCheckEdgeClip(Env env) { } @Test - public void entityPhysicsCheckEdgeClipSmall(Env env) { + void entityPhysicsCheckEdgeClipSmall(Env env) { var instance = env.createFlatInstance(); instance.setBlock(1, 42, 1, Block.STONE); @@ -465,7 +466,7 @@ public void entityPhysicsCheckEdgeClipSmall(Env env) { } @Test - public void entityPhysicsCheckDoorSubBlockNorth(Env env) { + void entityPhysicsCheckDoorSubBlockNorth(Env env) { var instance = env.createFlatInstance(); Block b = Block.ACACIA_TRAPDOOR.withProperties(Map.of("facing", "north", "open", "true")); @@ -480,7 +481,7 @@ public void entityPhysicsCheckDoorSubBlockNorth(Env env) { } @Test - public void entityPhysicsCheckDoorSubBlockSouth(Env env) { + void entityPhysicsCheckDoorSubBlockSouth(Env env) { var instance = env.createFlatInstance(); Block b = Block.ACACIA_TRAPDOOR.withProperties(Map.of("facing", "south", "open", "true")); @@ -495,7 +496,7 @@ public void entityPhysicsCheckDoorSubBlockSouth(Env env) { } @Test - public void entityPhysicsCheckDoorSubBlockWest(Env env) { + void entityPhysicsCheckDoorSubBlockWest(Env env) { var instance = env.createFlatInstance(); Block b = Block.ACACIA_TRAPDOOR.withProperties(Map.of("facing", "west", "open", "true")); @@ -510,7 +511,7 @@ public void entityPhysicsCheckDoorSubBlockWest(Env env) { } @Test - public void entityPhysicsCheckDoorSubBlockEast(Env env) { + void entityPhysicsCheckDoorSubBlockEast(Env env) { var instance = env.createFlatInstance(); Block b = Block.ACACIA_TRAPDOOR.withProperties(Map.of("facing", "east", "open", "true")); @@ -525,7 +526,7 @@ public void entityPhysicsCheckDoorSubBlockEast(Env env) { } @Test - public void entityPhysicsCheckDoorSubBlockUp(Env env) { + void entityPhysicsCheckDoorSubBlockUp(Env env) { var instance = env.createFlatInstance(); Block b = Block.ACACIA_TRAPDOOR.withProperties(Map.of("half", "top")); @@ -540,7 +541,7 @@ public void entityPhysicsCheckDoorSubBlockUp(Env env) { } @Test - public void entityPhysicsCheckDoorSubBlockDown(Env env) { + void entityPhysicsCheckDoorSubBlockDown(Env env) { var instance = env.createFlatInstance(); Block b = Block.ACACIA_TRAPDOOR; @@ -555,7 +556,7 @@ public void entityPhysicsCheckDoorSubBlockDown(Env env) { } @Test - public void entityPhysicsCheckOnGround(Env env) { + void entityPhysicsCheckOnGround(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 40, 0, Block.STONE); @@ -568,7 +569,7 @@ public void entityPhysicsCheckOnGround(Env env) { } @Test - public void entityPhysicsCheckStairTop(Env env) { + void entityPhysicsCheckStairTop(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 42, 0, Block.ACACIA_STAIRS); @@ -581,7 +582,7 @@ public void entityPhysicsCheckStairTop(Env env) { } @Test - public void entityPhysicsCheckStairTopSmall(Env env) { + void entityPhysicsCheckStairTopSmall(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 42, 0, Block.ACACIA_STAIRS); @@ -594,7 +595,7 @@ public void entityPhysicsCheckStairTopSmall(Env env) { } @Test - public void entityPhysicsCheckNotOnGround(Env env) { + void entityPhysicsCheckNotOnGround(Env env) { var instance = env.createFlatInstance(); for (int i = -2; i <= 2; ++i) @@ -610,7 +611,7 @@ public void entityPhysicsCheckNotOnGround(Env env) { } @Test - public void entityPhysicsCheckNotOnGroundHitUp(Env env) { + void entityPhysicsCheckNotOnGroundHitUp(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 60, 0, Block.STONE); @@ -623,7 +624,7 @@ public void entityPhysicsCheckNotOnGroundHitUp(Env env) { } @Test - public void entityPhysicsCheckSlide(Env env) { + void entityPhysicsCheckSlide(Env env) { var instance = env.createFlatInstance(); instance.setBlock(1, 43, 1, Block.STONE); instance.setBlock(1, 43, 2, Block.STONE); @@ -638,7 +639,7 @@ public void entityPhysicsCheckSlide(Env env) { } @Test - public void entityPhysicsSmallMoveCollide(Env env) { + void entityPhysicsSmallMoveCollide(Env env) { var instance = env.createFlatInstance(); instance.setBlock(1, 43, 0, Block.STONE); @@ -659,7 +660,7 @@ public void tmp(Env env) { // Checks C include all checks for crossing one intermediate block (3 block checks) @Test - public void entityPhysicsSmallMoveC0(Env env) { + void entityPhysicsSmallMoveC0(Env env) { var instance = env.createFlatInstance(); instance.setBlock(1, 42, 0, Block.STONE); @@ -674,7 +675,7 @@ public void entityPhysicsSmallMoveC0(Env env) { } @Test - public void entityPhysicsSmallMoveC1(Env env) { + void entityPhysicsSmallMoveC1(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 42, 1, Block.STONE); @@ -689,7 +690,7 @@ public void entityPhysicsSmallMoveC1(Env env) { } @Test - public void entityPhysicsSmallMoveC2(Env env) { + void entityPhysicsSmallMoveC2(Env env) { var instance = env.createFlatInstance(); instance.setBlock(1, 42, 1, Block.STONE); @@ -704,7 +705,7 @@ public void entityPhysicsSmallMoveC2(Env env) { } @Test - public void entityPhysicsSmallMoveC3(Env env) { + void entityPhysicsSmallMoveC3(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 42, 0, Block.STONE); @@ -719,7 +720,7 @@ public void entityPhysicsSmallMoveC3(Env env) { } @Test - public void entityPhysicsSmallMoveC4(Env env) { + void entityPhysicsSmallMoveC4(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 42, 1, Block.STONE); @@ -734,7 +735,7 @@ public void entityPhysicsSmallMoveC4(Env env) { } @Test - public void entityPhysicsSmallMoveC5(Env env) { + void entityPhysicsSmallMoveC5(Env env) { var instance = env.createFlatInstance(); instance.setBlock(1, 42, 0, Block.STONE); @@ -749,7 +750,7 @@ public void entityPhysicsSmallMoveC5(Env env) { } @Test - public void entityPhysicsSmallMoveC6(Env env) { + void entityPhysicsSmallMoveC6(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 42, 0, Block.STONE); @@ -764,7 +765,7 @@ public void entityPhysicsSmallMoveC6(Env env) { } @Test - public void entityPhysicsSmallMoveC7(Env env) { + void entityPhysicsSmallMoveC7(Env env) { var instance = env.createFlatInstance(); instance.setBlock(1, 42, 1, Block.STONE); @@ -780,7 +781,7 @@ public void entityPhysicsSmallMoveC7(Env env) { // Checks CE include checks for crossing two intermediate block (4 block checks) @Test - public void entityPhysicsSmallMoveC0E(Env env) { + void entityPhysicsSmallMoveC0E(Env env) { var instance = env.createFlatInstance(); instance.setBlock(1, 43, 0, Block.STONE); @@ -795,7 +796,7 @@ public void entityPhysicsSmallMoveC0E(Env env) { } @Test - public void entityPhysicsSmallMoveC1E(Env env) { + void entityPhysicsSmallMoveC1E(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 43, 1, Block.STONE); @@ -810,7 +811,7 @@ public void entityPhysicsSmallMoveC1E(Env env) { } @Test - public void entityPhysicsSmallMoveC2E(Env env) { + void entityPhysicsSmallMoveC2E(Env env) { var instance = env.createFlatInstance(); instance.setBlock(1, 43, 1, Block.STONE); @@ -826,7 +827,7 @@ public void entityPhysicsSmallMoveC2E(Env env) { } @Test - public void entityPhysicsCheckNoCollision(Env env) { + void entityPhysicsCheckNoCollision(Env env) { var instance = env.createFlatInstance(); for (int i = -2; i <= 2; ++i) @@ -842,7 +843,7 @@ public void entityPhysicsCheckNoCollision(Env env) { } @Test - public void entityPhysicsCheckBlockMiss(Env env) { + void entityPhysicsCheckBlockMiss(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 43, 2, Block.STONE); instance.setBlock(2, 43, 0, Block.STONE); @@ -856,7 +857,7 @@ public void entityPhysicsCheckBlockMiss(Env env) { } @Test - public void entityPhysicsCheckBlockDirections(Env env) { + void entityPhysicsCheckBlockDirections(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 43, 1, Block.STONE); @@ -890,7 +891,7 @@ public void entityPhysicsCheckBlockDirections(Env env) { } @Test - public void entityPhysicsCheckLargeVelocityMiss(Env env) { + void entityPhysicsCheckLargeVelocityMiss(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityType.ZOMBIE); @@ -905,7 +906,7 @@ public void entityPhysicsCheckLargeVelocityMiss(Env env) { } @Test - public void entityPhysicsCheckLargeVelocityHit(Env env) { + void entityPhysicsCheckLargeVelocityHit(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityType.ZOMBIE); @@ -922,7 +923,7 @@ public void entityPhysicsCheckLargeVelocityHit(Env env) { } @Test - public void entityPhysicsCheckNoMove(Env env) { + void entityPhysicsCheckNoMove(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityType.ZOMBIE); @@ -934,7 +935,7 @@ public void entityPhysicsCheckNoMove(Env env) { } @Test - public void entityPhysicsRepeatedCollision(Env env) { + void entityPhysicsRepeatedCollision(Env env) { var instance = env.createFlatInstance(); PhysicsResult previousResult = null; @@ -966,7 +967,7 @@ public void entityPhysicsRepeatedCollision(Env env) { } @Test - public void entityPhysicsCheckNoMoveCache(Env env) { + void entityPhysicsCheckNoMoveCache(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityType.ZOMBIE); @@ -980,7 +981,7 @@ public void entityPhysicsCheckNoMoveCache(Env env) { } @Test - public void entityPhysicsCheckNoMoveLargeVelocityHit(Env env) { + void entityPhysicsCheckNoMoveLargeVelocityHit(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityType.ZOMBIE); @@ -999,7 +1000,7 @@ public void entityPhysicsCheckNoMoveLargeVelocityHit(Env env) { } @Test - public void entityPhysicsCheckLargeVelocityHitNoMove(Env env) { + void entityPhysicsCheckLargeVelocityHitNoMove(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityType.ZOMBIE); @@ -1018,7 +1019,7 @@ public void entityPhysicsCheckLargeVelocityHitNoMove(Env env) { } @Test - public void entityPhysicsCheckDoorSubBlockSouthRepeat(Env env) { + void entityPhysicsCheckDoorSubBlockSouthRepeat(Env env) { var instance = env.createFlatInstance(); Block b = Block.ACACIA_TRAPDOOR.withProperties(Map.of("facing", "south", "open", "true")); @@ -1036,7 +1037,7 @@ public void entityPhysicsCheckDoorSubBlockSouthRepeat(Env env) { } @Test - public void entityPhysicsCheckCollisionDownCache(Env env) { + void entityPhysicsCheckCollisionDownCache(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 43, 1, Block.STONE); @@ -1056,7 +1057,7 @@ public void entityPhysicsCheckCollisionDownCache(Env env) { } @Test - public void entityPhysicsCheckGravityCached(Env env) { + void entityPhysicsCheckGravityCached(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 43, 1, Block.STONE); @@ -1087,7 +1088,7 @@ public void entityPhysicsCheckGravityCached(Env env) { } @Test - public void entityBlockPositionTestSlightlyAbove(Env env) { + void entityBlockPositionTestSlightlyAbove(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 42, 0, Block.STONE); @@ -1102,7 +1103,7 @@ public void entityBlockPositionTestSlightlyAbove(Env env) { } @Test - public void entityBlockPositionTestFarAbove(Env env) { + void entityBlockPositionTestFarAbove(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 42, 0, Block.STONE); diff --git a/src/test/java/net/minestom/server/collision/EntityBlockTouchTickIntegrationTest.java b/src/test/java/net/minestom/server/collision/EntityBlockTouchTickIntegrationTest.java index f5fbb8a9b99..e3236ac4641 100644 --- a/src/test/java/net/minestom/server/collision/EntityBlockTouchTickIntegrationTest.java +++ b/src/test/java/net/minestom/server/collision/EntityBlockTouchTickIntegrationTest.java @@ -1,7 +1,6 @@ package net.minestom.server.collision; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Point; import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Vec; @@ -10,8 +9,10 @@ import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.BlockHandler; import net.minestom.server.utils.NamespaceID; +import net.minestom.testing.extension.MicrotusExtension; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.HashSet; import java.util.Set; @@ -19,10 +20,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -@EnvTest -public class EntityBlockTouchTickIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class EntityBlockTouchTickIntegrationTest { @Test - public void entityPhysicsCheckTouchTick(Env env) { + void entityPhysicsCheckTouchTick(Env env) { var instance = env.createFlatInstance(); Set positions = new HashSet<>(); @@ -60,7 +61,7 @@ public void onTouch(@NotNull Touch touch) { } @Test - public void entityPhysicsCheckTouchTickFarZ(Env env) { + void entityPhysicsCheckTouchTickFarZ(Env env) { var instance = env.createFlatInstance(); instance.loadChunk(new Pos(1000, 1000, 1000)); @@ -100,7 +101,7 @@ public void onTouch(@NotNull Touch touch) { } @Test - public void entityPhysicsCheckTouchTickFarX(Env env) { + void entityPhysicsCheckTouchTickFarX(Env env) { var instance = env.createFlatInstance(); instance.loadChunk(new Pos(1000, 1000, 1000)); @@ -148,7 +149,7 @@ public void onTouch(@NotNull Touch touch) { } @Test - public void entityPhysicsCheckTouchTickFarNegative(Env env) { + void entityPhysicsCheckTouchTickFarNegative(Env env) { var instance = env.createFlatInstance(); instance.loadChunk(new Pos(-1000, 44, -1000)); diff --git a/src/test/java/net/minestom/server/collision/EntityProjectileCollisionIntegrationTest.java b/src/test/java/net/minestom/server/collision/EntityProjectileCollisionIntegrationTest.java index ccfc27c7872..b3f018ab0f5 100644 --- a/src/test/java/net/minestom/server/collision/EntityProjectileCollisionIntegrationTest.java +++ b/src/test/java/net/minestom/server/collision/EntityProjectileCollisionIntegrationTest.java @@ -4,7 +4,6 @@ import net.minestom.server.instance.WorldBorder; import net.minestom.server.ServerFlag; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Point; import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Vec; @@ -19,17 +18,19 @@ import net.minestom.server.instance.Instance; import net.minestom.server.instance.block.Block; import net.minestom.server.utils.time.TimeUnit; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.concurrent.atomic.AtomicReference; import static org.junit.jupiter.api.Assertions.*; -@EnvTest -public class EntityProjectileCollisionIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class EntityProjectileCollisionIntegrationTest { @Test - public void blockShootAndBlockRemoval(Env env) { + void blockShootAndBlockRemoval(Env env) { final Instance instance = env.createFlatInstance(); instance.setWorldBorder(WorldBorder.DEFAULT_BORDER.withDiameter(1000)); @@ -70,10 +71,12 @@ public void blockShootAndBlockRemoval(Env env) { assertNotNull(event); assertNotNull(event2); assertEquals(blockPosition.withY(y -> y - 1), new Vec(event.getCollisionPosition().blockX(), event.getCollisionPosition().blockY(), event.getCollisionPosition().blockZ())); + eventRef.set(null); + eventRef2.set(null); } @Test - public void entityShoot(Env env) { + void entityShoot(Env env) { final Instance instance = env.createFlatInstance(); instance.setWorldBorder(WorldBorder.DEFAULT_BORDER.withDiameter(1000)); @@ -121,7 +124,7 @@ private void singleEntityShoot( } @Test - public void entitySelfShoot(Env env) { + void entitySelfShoot(Env env) { final Instance instance = env.createFlatInstance(); instance.setWorldBorder(WorldBorder.DEFAULT_BORDER.withDiameter(1000)); @@ -150,6 +153,6 @@ public void entitySelfShoot(Env env) { assertNotNull(event); assertSame(shooter, event.getTarget()); assertTrue(shooter.getBoundingBox().intersectEntity(shooter.getPosition(), projectile)); + eventRef.set(null); } - } diff --git a/src/test/java/net/minestom/server/collision/PlacementCollisionIntegrationTest.java b/src/test/java/net/minestom/server/collision/PlacementCollisionIntegrationTest.java index 27a2f36c19f..5aab794e32f 100644 --- a/src/test/java/net/minestom/server/collision/PlacementCollisionIntegrationTest.java +++ b/src/test/java/net/minestom/server/collision/PlacementCollisionIntegrationTest.java @@ -1,41 +1,42 @@ package net.minestom.server.collision; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Vec; import net.minestom.server.entity.Entity; import net.minestom.server.entity.EntityType; import net.minestom.server.instance.block.Block; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.*; -@EnvTest -public class PlacementCollisionIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class PlacementCollisionIntegrationTest { @Test - public void empty(Env env) { + void empty(Env env) { var instance = env.createFlatInstance(); assertNull(BlockCollision.canPlaceBlockAt(instance, new Vec(0, 40, 0), Block.STONE)); } @Test - public void entityBlock(Env env) { + void entityBlock(Env env) { var instance = env.createFlatInstance(); new Entity(EntityType.ZOMBIE).setInstance(instance, new Pos(0, 40, 0)).join(); assertNotNull(BlockCollision.canPlaceBlockAt(instance, new Vec(0, 40, 0), Block.STONE)); } @Test - public void slab(Env env) { + void slab(Env env) { var instance = env.createFlatInstance(); new Entity(EntityType.ZOMBIE).setInstance(instance, new Pos(0, 40.75, 0)).join(); assertNull(BlockCollision.canPlaceBlockAt(instance, new Vec(0, 40, 0), Block.STONE_SLAB)); } @Test - public void belowPlayer(Env env) { + void belowPlayer(Env env) { var instance = env.createFlatInstance(); env.createPlayer(instance, new Pos(5.7, -8, 6.389)); assertNull(BlockCollision.canPlaceBlockAt(instance, new Vec(5, -9, 6), Block.STONE)); diff --git a/src/test/java/net/minestom/server/collision/TestShape.java b/src/test/java/net/minestom/server/collision/TestShape.java index 8ccc65d5a66..49c71f7af9c 100644 --- a/src/test/java/net/minestom/server/collision/TestShape.java +++ b/src/test/java/net/minestom/server/collision/TestShape.java @@ -11,7 +11,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -public class TestShape { +class TestShape { private static @NotNull Stream isFullFaceCases() { return Stream.of( diff --git a/src/test/java/net/minestom/server/command/ArgumentParserTest.java b/src/test/java/net/minestom/server/command/ArgumentParserTest.java index 9f5f68a566b..e044e512aba 100644 --- a/src/test/java/net/minestom/server/command/ArgumentParserTest.java +++ b/src/test/java/net/minestom/server/command/ArgumentParserTest.java @@ -11,10 +11,10 @@ /** * Test string version of arguments. */ -public class ArgumentParserTest { +class ArgumentParserTest { @Test - public void testArgumentParser() { + void testArgumentParser() { // Test each argument assertParserEquals("Literal", ArgumentType.Literal("example")); assertParserEquals("Boolean", ArgumentType.Boolean("example")); diff --git a/src/test/java/net/minestom/server/command/ArgumentTest.java b/src/test/java/net/minestom/server/command/ArgumentTest.java index f31ba6fb020..6b8846ed7c6 100644 --- a/src/test/java/net/minestom/server/command/ArgumentTest.java +++ b/src/test/java/net/minestom/server/command/ArgumentTest.java @@ -11,16 +11,16 @@ import static org.junit.jupiter.api.Assertions.*; -public class ArgumentTest { +class ArgumentTest { @Test - public void testParseSelf() { + void testParseSelf() { assertEquals("example", Argument.parse(new ServerSender(), ArgumentType.String("example"))); assertEquals(55, Argument.parse(new ServerSender(), ArgumentType.Integer("55"))); } @Test - public void testCallback() { + void testCallback() { var arg = ArgumentType.String("id"); assertFalse(arg.hasErrorCallback()); @@ -30,7 +30,7 @@ public void testCallback() { } @Test - public void testDefaultValue() { + void testDefaultValue() { var arg = ArgumentType.String("id"); assertFalse(arg.isOptional()); @@ -40,7 +40,7 @@ public void testDefaultValue() { } @Test - public void testSuggestionCallback() { + void testSuggestionCallback() { var arg = ArgumentType.String("id"); assertFalse(arg.hasSuggestion()); diff --git a/src/test/java/net/minestom/server/command/ArgumentTypeTest.java b/src/test/java/net/minestom/server/command/ArgumentTypeTest.java index 7bbdfa6b345..b7450a6f89d 100644 --- a/src/test/java/net/minestom/server/command/ArgumentTypeTest.java +++ b/src/test/java/net/minestom/server/command/ArgumentTypeTest.java @@ -35,14 +35,14 @@ import static org.junit.jupiter.api.Assertions.*; -public class ArgumentTypeTest { +class ArgumentTypeTest { static { MinecraftServer.init(); } @Test - public void testArgumentEntityType() { + void testArgumentEntityType() { var arg = ArgumentType.EntityType("entity_type"); assertInvalidArg(arg, "minecraft:invalid_entity_type"); assertArg(arg, EntityType.ARMOR_STAND, EntityType.ARMOR_STAND.name()); @@ -50,7 +50,7 @@ public void testArgumentEntityType() { } @Test - public void testArgumentParticle() { + void testArgumentParticle() { var arg = ArgumentType.Particle("particle"); assertInvalidArg(arg, "minecraft:invalid_particle"); assertArg(arg, Particle.BLOCK, Particle.BLOCK.name()); @@ -58,7 +58,7 @@ public void testArgumentParticle() { } @Test - public void testArgumentBlockState() { + void testArgumentBlockState() { var arg = ArgumentType.BlockState("block_state"); assertInvalidArg(arg, "minecraft:invalid_block[invalid_property=invalid_key]"); assertInvalidArg(arg, "minecraft:stone[invalid_property=invalid_key]"); @@ -69,7 +69,7 @@ public void testArgumentBlockState() { } @Test - public void testArgumentColor() { + void testArgumentColor() { var arg = ArgumentType.Color("color"); assertInvalidArg(arg, "invalid_color"); assertArg(arg, Style.style(NamedTextColor.DARK_PURPLE), "dark_purple"); @@ -77,7 +77,7 @@ public void testArgumentColor() { } @Test - public void testArgumentComponent() { + void testArgumentComponent() { var arg = ArgumentType.Component("component"); var component1 = Component.text("Example text", NamedTextColor.DARK_AQUA); var component2 = Component.text("Other example text", Style.style(TextDecoration.OBFUSCATED)); @@ -90,7 +90,7 @@ public void testArgumentComponent() { } @Test - public void testArgumentEntity() { + void testArgumentEntity() { var arg = ArgumentType.Entity("entity"); assertValidArg(arg, "@a"); @@ -127,7 +127,7 @@ public void testArgumentEntity() { } @Test - public void testArgumentFloatRange() { + void testArgumentFloatRange() { var arg = ArgumentType.FloatRange("float_range"); assertArg(arg, new FloatRange(0f, 50f), "0..50"); assertArg(arg, new FloatRange(0f, 0f), "0..0"); @@ -142,7 +142,7 @@ public void testArgumentFloatRange() { } @Test - public void testArgumentIntRange() { + void testArgumentIntRange() { var arg = ArgumentType.IntRange("int_range"); assertArg(arg, new IntRange(0, 50), "0..50"); @@ -161,7 +161,7 @@ public void testArgumentIntRange() { } @Test - public void testArgumentItemStack() { + void testArgumentItemStack() { var arg = ArgumentType.ItemStack("item_stack"); assertArg(arg, ItemStack.AIR, "air"); assertArg(arg, ItemStack.of(Material.GLASS_PANE).withTag(Tag.String("tag"), "value"), "glass_pane{tag:value}"); @@ -172,7 +172,7 @@ public void testArgumentItemStack() { } @Test - public void testArgumentNbtCompoundTag() { + void testArgumentNbtCompoundTag() { var arg = ArgumentType.NbtCompound("nbt_compound"); assertArg(arg, CompoundBinaryTag.builder().putLongArray("long_array", new long[]{12, 49, 119}).build(), "{\"long_array\":[L;12L,49L,119L]}"); @@ -186,7 +186,7 @@ public void testArgumentNbtCompoundTag() { } @Test - public void testArgumentNbtTag() { + void testArgumentNbtTag() { var arg = ArgumentType.NBT("nbt"); assertArg(arg, StringBinaryTag.stringBinaryTag("string"), "string"); assertArg(arg, StringBinaryTag.stringBinaryTag("string"), "\"string\""); @@ -202,14 +202,14 @@ public void testArgumentNbtTag() { } @Test - public void testArgumentResource() { + void testArgumentResource() { var arg = ArgumentType.Resource("resource", "minecraft:block"); assertArg(arg, "minecraft:resource_example", "minecraft:resource_example"); assertInvalidArg(arg, "minecraft:invalid resource"); } @Test - public void testArgumentResourceLocation() { + void testArgumentResourceLocation() { var arg = ArgumentType.ResourceLocation("resource_location"); assertArg(arg, "minecraft:resource_location_example", "minecraft:resource_location_example"); assertInvalidArg(arg, "minecraft:invalid resource location"); @@ -217,14 +217,14 @@ public void testArgumentResourceLocation() { } @Test - public void testArgumentResourceOrTag() { + void testArgumentResourceOrTag() { var arg = ArgumentType.ResourceOrTag("resource_or_tag", "data/minecraft/tags/blocks"); assertArg(arg, "minecraft:resource_or_tag_example", "minecraft:resource_or_tag_example"); assertInvalidArg(arg, "minecraft:invalid resource or tag"); } @Test - public void testArgumentTime() { + void testArgumentTime() { var arg = ArgumentType.Time("time"); assertArg(arg, Duration.of(20, TimeUnit.SERVER_TICK), "20"); assertArg(arg, Duration.of(40, TimeUnit.SERVER_TICK), "40t"); @@ -236,14 +236,14 @@ public void testArgumentTime() { } @Test - public void testArgumentUUID() { + void testArgumentUUID() { var arg = ArgumentType.UUID("uuid"); assertInvalidArg(arg, "invalid_uuid"); assertArg(arg, UUID.fromString("10515090-26f2-49fa-b2ba-9594d4d0451f"), "10515090-26f2-49fa-b2ba-9594d4d0451f"); } @Test - public void testArgumentDouble() { + void testArgumentDouble() { var arg = ArgumentType.Double("double"); assertArg(arg, 2564d, "2564"); assertArg(arg, -591.981d, "-591.981"); @@ -252,7 +252,7 @@ public void testArgumentDouble() { } @Test - public void testArgumentFloat() { + void testArgumentFloat() { var arg = ArgumentType.Float("float"); assertArg(arg, 2564f, "2564"); assertArg(arg, -591.981f, "-591.981"); @@ -261,7 +261,7 @@ public void testArgumentFloat() { } @Test - public void testArgumentInteger() { + void testArgumentInteger() { var arg = ArgumentType.Integer("integer"); assertArg(arg, 2564, "2564"); assertInvalidArg(arg, "256.4"); @@ -269,15 +269,15 @@ public void testArgumentInteger() { } @Test - public void testArgumentLong() { + void testArgumentLong() { var arg = ArgumentType.Long("long"); - assertArg(arg, 2564l, "2564"); + assertArg(arg, 2564L, "2564"); assertInvalidArg(arg, "256.4"); assertInvalidArg(arg, "9223372036854775808"); } @Test - public void testArgumentRelativeBlockPosition() { + void testArgumentRelativeBlockPosition() { var arg = ArgumentType.RelativeBlockPosition("relative_block_position"); var vec = new Vec(-3, 14, 255); @@ -301,7 +301,7 @@ public void testArgumentRelativeBlockPosition() { } @Test - public void testArgumentRelativeVec2() { + void testArgumentRelativeVec2() { var arg = ArgumentType.RelativeVec2("relative_vec_2"); var vec = new Vec(-3, 14.25); @@ -322,7 +322,7 @@ public void testArgumentRelativeVec2() { } @Test - public void testArgumentRelativeVec3() { + void testArgumentRelativeVec3() { var arg = ArgumentType.RelativeVec3("relative_vec_3"); var vec = new Vec(-3, 14.25, 255); @@ -343,7 +343,7 @@ public void testArgumentRelativeVec3() { } @Test - public void testArgumentBoolean() { + void testArgumentBoolean() { var arg = ArgumentType.Boolean("boolean"); assertArg(arg, true, "true"); assertArg(arg, false, "false"); @@ -351,7 +351,7 @@ public void testArgumentBoolean() { } @Test - public void testArgumentEnum() { + void testArgumentEnum() { enum ExampleEnum {FIRST, SECOND, Third, fourth} var arg = ArgumentType.Enum("enum", ExampleEnum.class); @@ -379,7 +379,7 @@ enum ExampleEnum {FIRST, SECOND, Third, fourth} } @Test - public void testArgumentGroup() { + void testArgumentGroup() { var arg = ArgumentType.Group("group", ArgumentType.Integer("integer"), ArgumentType.String("string"), ArgumentType.Double("double")); // Test normal input @@ -405,7 +405,7 @@ public void testArgumentGroup() { } @Test - public void testArgumentLiteral() { + void testArgumentLiteral() { var arg = ArgumentType.Literal("literal"); assertArg(arg, "literal", "literal"); assertInvalidArg(arg, "not_literal"); @@ -413,7 +413,7 @@ public void testArgumentLiteral() { } @Test - public void testArgumentLoop() { + void testArgumentLoop() { var arg = ArgumentType.Loop("loop", ArgumentType.String("string"), ArgumentType.String("string2").map(s -> { throw new IllegalArgumentException("This argument should never be triggered"); })); @@ -423,7 +423,7 @@ public void testArgumentLoop() { } @Test - public void testArgumentString() { + void testArgumentString() { var arg = ArgumentType.String("string"); assertArg(arg, "text", "text"); assertArg(arg, "more text", "\"more text\""); @@ -433,7 +433,7 @@ public void testArgumentString() { } @Test - public void testArgumentStringArray() { + void testArgumentStringArray() { var arg = ArgumentType.StringArray("string_array"); assertArrayArg(arg, new String[]{"example", "text"}, "example text"); assertArrayArg(arg, new String[]{"some", "more", "placeholder", "text"}, "some more placeholder text"); @@ -443,7 +443,7 @@ public void testArgumentStringArray() { } @Test - public void testArgumentWord() { + void testArgumentWord() { var arg = ArgumentType.Word("word").from("word1", "word2", "word3"); assertArg(arg, "word1", "word1"); @@ -455,7 +455,7 @@ public void testArgumentWord() { } @Test - public void testArgumentMapWithSender() { + void testArgumentMapWithSender() { var serverSender = new ServerSender(); var arg = ArgumentType.Word("word").from("word1", "word2", "word3") diff --git a/src/test/java/net/minestom/server/command/CommandConditionTest.java b/src/test/java/net/minestom/server/command/CommandConditionTest.java index f7450b020c9..f76f113a161 100644 --- a/src/test/java/net/minestom/server/command/CommandConditionTest.java +++ b/src/test/java/net/minestom/server/command/CommandConditionTest.java @@ -13,10 +13,10 @@ import static org.junit.jupiter.api.Assertions.*; -public class CommandConditionTest { +class CommandConditionTest { @Test - public void mainCondition() { + void mainCondition() { var dispatcher = new CommandDispatcher(); assertNull(dispatcher.findCommand("name")); var sender = new Sender(); @@ -39,7 +39,7 @@ public void mainCondition() { } @Test - public void subCondition() { + void subCondition() { var dispatcher = new CommandDispatcher(); assertNull(dispatcher.findCommand("name")); var sender = new Sender(); @@ -83,7 +83,7 @@ public void subCondition() { } @Test - public void subConditionOverride() { + void subConditionOverride() { var dispatcher = new CommandDispatcher(); assertNull(dispatcher.findCommand("name")); var sender = new Sender(); diff --git a/src/test/java/net/minestom/server/command/CommandManagerTest.java b/src/test/java/net/minestom/server/command/CommandManagerTest.java index 5d9b24d4afc..99cb85e3177 100644 --- a/src/test/java/net/minestom/server/command/CommandManagerTest.java +++ b/src/test/java/net/minestom/server/command/CommandManagerTest.java @@ -11,10 +11,10 @@ import static org.junit.jupiter.api.Assertions.*; -public class CommandManagerTest { +class CommandManagerTest { @Test - public void testCommandRegistration() { + void testCommandRegistration() { var manager = new CommandManager(); var command = new Command("name1", "name2"); @@ -33,7 +33,7 @@ public void testCommandRegistration() { } @Test - public void testUnknownCommandCallback() { + void testUnknownCommandCallback() { var manager = new CommandManager(); AtomicBoolean check = new AtomicBoolean(false); @@ -49,7 +49,7 @@ public void testUnknownCommandCallback() { } @Test - public void testSharedArgumentSyntaxABFirst() { + void testSharedArgumentSyntaxABFirst() { var manager = new CommandManager(); var checkA = new AtomicBoolean(false); @@ -77,7 +77,7 @@ public void testSharedArgumentSyntaxABFirst() { } @Test - public void testSharedArgumentSyntaxAFirst() { + void testSharedArgumentSyntaxAFirst() { var manager = new CommandManager(); var checkA = new AtomicBoolean(false); diff --git a/src/test/java/net/minestom/server/command/CommandPacketFilteringTest.java b/src/test/java/net/minestom/server/command/CommandPacketFilteringTest.java index 0ce8a207fba..f1723d9525b 100644 --- a/src/test/java/net/minestom/server/command/CommandPacketFilteringTest.java +++ b/src/test/java/net/minestom/server/command/CommandPacketFilteringTest.java @@ -10,18 +10,18 @@ import java.util.UUID; @SuppressWarnings("ConstantConditions") -public class CommandPacketFilteringTest { +class CommandPacketFilteringTest { private static final Player PLAYER = new Player(UUID.randomUUID(), "", null); @Test - public void singleCommandFilteredFalse() { + void singleCommandFilteredFalse() { final Command foo = new Command("foo"); foo.setCondition(((sender, commandString) -> false)); assertFiltering(foo, ""); } @Test - public void singleCommandFilteredTrue() { + void singleCommandFilteredTrue() { final Command foo = new Command("foo"); foo.setCondition(((sender, commandString) -> true)); assertFiltering(foo, """ @@ -31,7 +31,7 @@ public void singleCommandFilteredTrue() { } @Test - public void singleCommandUnfiltered() { + void singleCommandUnfiltered() { final Command foo = new Command("foo"); assertFiltering(foo, """ foo=% @@ -40,7 +40,7 @@ public void singleCommandUnfiltered() { } @Test - public void singleCommandFilteredTrueWithFilteredSubcommandTrueWithFilteredSyntaxFalse() { + void singleCommandFilteredTrueWithFilteredSubcommandTrueWithFilteredSyntaxFalse() { final Command foo = new Command("foo"); foo.setCondition((sender, commandString) -> true); final Command bar = new Command("bar"); @@ -55,7 +55,7 @@ public void singleCommandFilteredTrueWithFilteredSubcommandTrueWithFilteredSynta } @Test - public void singleCommandFilteredTrueWithFilteredSubcommandFalse() { + void singleCommandFilteredTrueWithFilteredSubcommandFalse() { final Command foo = new Command("foo"); foo.setCondition((sender, commandString) -> true); final Command bar = new Command("bar"); @@ -68,7 +68,7 @@ public void singleCommandFilteredTrueWithFilteredSubcommandFalse() { } @Test - public void singleCommandFilteredTrueWithFilteredSubcommandTrue() { + void singleCommandFilteredTrueWithFilteredSubcommandTrue() { final Command foo = new Command("foo"); foo.setCondition((sender, commandString) -> true); final Command bar = new Command("bar"); @@ -82,7 +82,7 @@ public void singleCommandFilteredTrueWithFilteredSubcommandTrue() { } @Test - public void singleCommandFilteredTrueWithFilteredSubcommandTrueWithFilteredSyntaxBoth() { + void singleCommandFilteredTrueWithFilteredSubcommandTrueWithFilteredSyntaxBoth() { final Command foo = new Command("foo"); foo.setCondition((sender, commandString) -> true); final Command bar = new Command("bar"); @@ -99,7 +99,7 @@ public void singleCommandFilteredTrueWithFilteredSubcommandTrueWithFilteredSynta } @Test - public void singleCommandConditionalArgGroupTrue() { + void singleCommandConditionalArgGroupTrue() { final Command foo = new Command("foo"); foo.addConditionalSyntax((sender, commandString) -> true, null, ArgumentType.Group("test", ArgumentType.Literal("bar"))); assertFiltering(foo, """ @@ -110,7 +110,7 @@ public void singleCommandConditionalArgGroupTrue() { } @Test - public void singleCommandConditionalArgGroupFalse() { + void singleCommandConditionalArgGroupFalse() { final Command foo = new Command("foo"); foo.addConditionalSyntax((sender, commandString) -> false, null, ArgumentType.Group("test", ArgumentType.Literal("foo"))); assertFiltering(foo, """ @@ -120,7 +120,7 @@ public void singleCommandConditionalArgGroupFalse() { } @Test - public void singleCommandUnconditionalArgGroup() { + void singleCommandUnconditionalArgGroup() { final Command foo = new Command("foo"); foo.addSyntax(null, ArgumentType.Group("test", ArgumentType.Literal("bar"))); assertFiltering(foo, """ @@ -131,7 +131,7 @@ public void singleCommandUnconditionalArgGroup() { } @Test - public void singleCommandConditionalArgGroupTrue2() { + void singleCommandConditionalArgGroupTrue2() { final Command foo = new Command("foo"); foo.addConditionalSyntax((sender, commandString) -> true, null, ArgumentType.Group("test", ArgumentType.Literal("bar"), ArgumentType.Literal("baz"))); assertFiltering(foo, """ @@ -143,7 +143,7 @@ public void singleCommandConditionalArgGroupTrue2() { } @Test - public void singleCommandConditionalArgGroupFalse2() { + void singleCommandConditionalArgGroupFalse2() { final Command foo = new Command("foo"); foo.addConditionalSyntax((sender, commandString) -> false, null, ArgumentType.Group("test", ArgumentType.Literal("foo"), ArgumentType.Literal("baz"))); assertFiltering(foo, """ @@ -153,7 +153,7 @@ public void singleCommandConditionalArgGroupFalse2() { } @Test - public void singleCommandUnconditionalArgGroup2() { + void singleCommandUnconditionalArgGroup2() { final Command foo = new Command("foo"); foo.addSyntax(null, ArgumentType.Group("test", ArgumentType.Literal("bar"), ArgumentType.Literal("baz"))); assertFiltering(foo, """ @@ -165,7 +165,7 @@ public void singleCommandUnconditionalArgGroup2() { } @Test - public void singleCommandUnconditionalArgLoop() { + void singleCommandUnconditionalArgLoop() { final Command foo = new Command("foo"); foo.addSyntax(null, ArgumentType.Loop("test", ArgumentType.Literal("bar"), ArgumentType.Literal("baz"))); assertFiltering(foo, """ @@ -177,7 +177,7 @@ public void singleCommandUnconditionalArgLoop() { } @Test - public void singleCommandConditionalArgLoopTrue() { + void singleCommandConditionalArgLoopTrue() { final Command foo = new Command("foo"); foo.addConditionalSyntax((sender, commandString) -> true, null, ArgumentType.Loop("test", ArgumentType.Literal("bar"), ArgumentType.Literal("baz"))); assertFiltering(foo, """ @@ -189,7 +189,7 @@ public void singleCommandConditionalArgLoopTrue() { } @Test - public void singleCommandConditionalArgLoopFalse() { + void singleCommandConditionalArgLoopFalse() { final Command foo = new Command("foo"); foo.addConditionalSyntax((sender, commandString) -> false, null, ArgumentType.Loop("test", ArgumentType.Literal("bar"), ArgumentType.Literal("baz"))); assertFiltering(foo, """ diff --git a/src/test/java/net/minestom/server/command/CommandPacketTest.java b/src/test/java/net/minestom/server/command/CommandPacketTest.java index 512aadd1123..2b516699473 100644 --- a/src/test/java/net/minestom/server/command/CommandPacketTest.java +++ b/src/test/java/net/minestom/server/command/CommandPacketTest.java @@ -9,9 +9,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -public class CommandPacketTest { +class CommandPacketTest { @Test - public void singleCommandWithOneSyntax() { + void singleCommandWithOneSyntax() { final Command foo = new Command("foo"); foo.addSyntax(CommandPacketTest::dummyExecutor, ArgumentType.Integer("bar")); @@ -34,7 +34,7 @@ public void singleCommandWithOneSyntax() { } @Test - public void executeLike() { + void executeLike() { enum Dimension {OVERWORLD, THE_NETHER, THE_END} final Command execute = new Command("execute"); execute.addSyntax(CommandPacketTest::dummyExecutor, ArgumentType.Loop("params", @@ -62,7 +62,7 @@ enum Dimension {OVERWORLD, THE_NETHER, THE_END} } @Test - public void singleCommandTwoEnum() { + void singleCommandTwoEnum() { var graph = Graph.builder(ArgumentType.Literal("foo")) .append(ArgumentType.Enum("bar", A.class), b -> b.append(ArgumentType.Enum("baz", B.class))) .build(); @@ -76,7 +76,7 @@ public void singleCommandTwoEnum() { } @Test - public void singleCommandRestrictedWord() { + void singleCommandRestrictedWord() { var graph = Graph.builder(ArgumentType.Literal("foo")) .append(ArgumentType.Word("bar").from("A", "B", "C")) .build(); @@ -89,7 +89,7 @@ public void singleCommandRestrictedWord() { } @Test - public void singleCommandWord() { + void singleCommandWord() { var graph = Graph.builder(ArgumentType.Literal("foo")) .append(ArgumentType.Word("bar")) .build(); @@ -102,7 +102,7 @@ public void singleCommandWord() { } @Test - public void singleCommandCommandAfterEnum() { + void singleCommandCommandAfterEnum() { var graph = Graph.builder(ArgumentType.Literal("foo")) .append(ArgumentType.Enum("bar", A.class), b -> b.append(ArgumentType.Command("baz"))) .build(); @@ -117,7 +117,7 @@ public void singleCommandCommandAfterEnum() { } @Test - public void twoCommandIntEnumInt() { + void twoCommandIntEnumInt() { var graph = Graph.builder(ArgumentType.Literal("foo")) .append(ArgumentType.Integer("int1"), b -> b.append(ArgumentType.Enum("test", A.class), c -> c.append(ArgumentType.Integer("int2")))) .build(); @@ -139,7 +139,7 @@ public void twoCommandIntEnumInt() { } @Test - public void singleCommandTwoGroupOfIntInt() { + void singleCommandTwoGroupOfIntInt() { var graph = Graph.builder(ArgumentType.Literal("foo")) .append(ArgumentType.Group("1", ArgumentType.Integer("int1"), ArgumentType.Integer("int2")), b -> b.append(ArgumentType.Group("2", ArgumentType.Integer("int3"), ArgumentType.Integer("int4")))) @@ -155,7 +155,7 @@ public void singleCommandTwoGroupOfIntInt() { """, graph); } @Test - public void twoEnumAndOneLiteralChild() { + void twoEnumAndOneLiteralChild() { var graph = Graph.builder(ArgumentType.Literal("foo")) .append(ArgumentType.Enum("a", A.class)) .append(ArgumentType.Literal("l")) @@ -170,7 +170,7 @@ public void twoEnumAndOneLiteralChild() { } @Test - public void commandAliasWithoutArg() { + void commandAliasWithoutArg() { var graph = Graph.builder(ArgumentType.Word("foo").from("foo", "bar")) .build(); assertPacketGraph(""" @@ -180,7 +180,7 @@ public void commandAliasWithoutArg() { } @Test - public void commandAliasWithArg() { + void commandAliasWithArg() { var graph = Graph.builder(ArgumentType.Word("foo").from("foo", "bar")) .append(ArgumentType.Literal("l")) .build(); @@ -192,7 +192,7 @@ public void commandAliasWithArg() { } @Test - public void cmdArgShortcut() { + void cmdArgShortcut() { var foo = Graph.builder(ArgumentType.Literal("foo")) .append(ArgumentType.String("msg")) .build(); @@ -210,7 +210,7 @@ public void cmdArgShortcut() { } @Test - public void cmdArgShortcutWithPartialArg() { + void cmdArgShortcutWithPartialArg() { var foo = Graph.builder(ArgumentType.Literal("foo")) .append(ArgumentType.String("msg")) .build(); diff --git a/src/test/java/net/minestom/server/command/CommandParseTest.java b/src/test/java/net/minestom/server/command/CommandParseTest.java index 5f2a03b5ee1..6f8143715ba 100644 --- a/src/test/java/net/minestom/server/command/CommandParseTest.java +++ b/src/test/java/net/minestom/server/command/CommandParseTest.java @@ -11,16 +11,16 @@ import static net.minestom.server.command.builder.arguments.ArgumentType.Word; import static org.junit.jupiter.api.Assertions.*; -public class CommandParseTest { +class CommandParseTest { @Test - public void emptyCommand() { + void emptyCommand() { var graph = Graph.merge(Graph.builder(Literal("foo"), createExecutor(new AtomicBoolean())).build()); assertUnknown(graph, ""); } @Test - public void singleParameterlessCommand() { + void singleParameterlessCommand() { final AtomicBoolean b = new AtomicBoolean(); var foo = Graph.merge(Graph.builder(Literal("foo"), createExecutor(b)).build()); assertValid(foo, "foo", b); @@ -29,7 +29,7 @@ public void singleParameterlessCommand() { } @Test - public void twoParameterlessCommand() { + void twoParameterlessCommand() { final AtomicBoolean b = new AtomicBoolean(); final AtomicBoolean b1 = new AtomicBoolean(); var graph = Graph.merge( @@ -44,7 +44,7 @@ public void twoParameterlessCommand() { } @Test - public void singleCommandWithMultipleSyntax() { + void singleCommandWithMultipleSyntax() { final AtomicBoolean add = new AtomicBoolean(); final AtomicBoolean action = new AtomicBoolean(); var foo = Graph.merge(Graph.builder(Literal("foo")) @@ -69,7 +69,7 @@ public void singleCommandWithMultipleSyntax() { } @Test - public void singleCommandOptionalArgs() { + void singleCommandOptionalArgs() { final AtomicBoolean b = new AtomicBoolean(); final AtomicReference expectedFirstArg = new AtomicReference<>("T"); var foo = Graph.merge(Graph.builder(Literal("foo")) @@ -89,10 +89,11 @@ public void singleCommandOptionalArgs() { assertValid(foo, "foo T", b); expectedFirstArg.set("A"); assertValid(foo, "foo", b); + expectedFirstArg.set(null); } @Test - public void singleCommandSingleEnumArg() { + void singleCommandSingleEnumArg() { enum A {a, b} final AtomicBoolean b = new AtomicBoolean(); var foo = Graph.merge(Graph.builder(Literal("foo")) @@ -105,7 +106,7 @@ enum A {a, b} } @Test - public void aliasWithoutArgs() { + void aliasWithoutArgs() { final AtomicBoolean b = new AtomicBoolean(); var foo = Graph.merge(Graph.builder(Word("").from("foo", "bar"), createExecutor(b)) .build()); @@ -115,7 +116,7 @@ public void aliasWithoutArgs() { } @Test - public void aliasWithArgs() { + void aliasWithArgs() { final AtomicBoolean b = new AtomicBoolean(); var foo = Graph.merge(Graph.builder(Word("").from("foo", "bar")) .append(ArgumentType.Integer("test"), createExecutor(b)) diff --git a/src/test/java/net/minestom/server/command/CommandSenderTest.java b/src/test/java/net/minestom/server/command/CommandSenderTest.java index 7cbabb81a23..5fe42d7bdca 100644 --- a/src/test/java/net/minestom/server/command/CommandSenderTest.java +++ b/src/test/java/net/minestom/server/command/CommandSenderTest.java @@ -17,10 +17,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -public class CommandSenderTest { +class CommandSenderTest { @Test - public void testSenderPermissions() { + void testSenderPermissions() { CommandSender sender = new SenderTest(); @@ -37,7 +37,7 @@ public void testSenderPermissions() { } @Test - public void testMessageSending() { + void testMessageSending() { SenderTest sender = new SenderTest(); assertNull(sender.getMostRecentMessage()); diff --git a/src/test/java/net/minestom/server/command/CommandSuggestionIntegrationTest.java b/src/test/java/net/minestom/server/command/CommandSuggestionIntegrationTest.java index 28fc868a864..bca6cd0861c 100644 --- a/src/test/java/net/minestom/server/command/CommandSuggestionIntegrationTest.java +++ b/src/test/java/net/minestom/server/command/CommandSuggestionIntegrationTest.java @@ -6,8 +6,9 @@ import net.minestom.server.network.packet.client.play.ClientTabCompletePacket; import net.minestom.server.network.packet.server.play.TabCompletePacket; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.List; @@ -15,11 +16,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -@EnvTest -public class CommandSuggestionIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class CommandSuggestionIntegrationTest { @Test - public void suggestion(Env env) { + void suggestion(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); @@ -50,7 +51,7 @@ public void suggestion(Env env) { } @Test - public void suggestionWithDefaults(Env env) { + void suggestionWithDefaults(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); @@ -62,20 +63,20 @@ public void suggestionWithDefaults(Env env) { var command = new Command("foo"); - command.addSyntax((sender,context)->{}, suggestArg, defaultArg); + command.addSyntax((sender, context) -> { + }, suggestArg, defaultArg); env.process().command().register(command); var listener = connection.trackIncoming(TabCompletePacket.class); player.addPacketToQueue(new ClientTabCompletePacket(1, "foo 1")); player.interpretPacketQueue(); - listener.assertSingle(tabCompletePacket -> { - assertEquals(List.of(new TabCompletePacket.Match("suggestion", null)), tabCompletePacket.matches()); - }); + listener.assertSingle(tabCompletePacket -> + assertEquals(List.of(new TabCompletePacket.Match("suggestion", null)), tabCompletePacket.matches())); } @Test - public void suggestionWithSubcommand(Env env) { + void suggestionWithSubcommand(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); @@ -109,7 +110,7 @@ public void suggestionWithSubcommand(Env env) { } @Test - public void suggestionWithTwoLiterals(Env env) { + void suggestionWithTwoLiterals(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); diff --git a/src/test/java/net/minestom/server/command/CommandSyntaxMultiTest.java b/src/test/java/net/minestom/server/command/CommandSyntaxMultiTest.java index ca0fec6265f..063ad7f7671 100644 --- a/src/test/java/net/minestom/server/command/CommandSyntaxMultiTest.java +++ b/src/test/java/net/minestom/server/command/CommandSyntaxMultiTest.java @@ -7,7 +7,6 @@ import java.lang.String; import java.util.List; import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import static net.minestom.server.command.builder.arguments.ArgumentType.Float; @@ -16,10 +15,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; -public class CommandSyntaxMultiTest { +class CommandSyntaxMultiTest { @Test - public void integerFloat() { + void integerFloat() { List>> args = List.of( List.of(Literal("integer"), Integer("number")), List.of(Literal("float"), Float("number")) @@ -29,7 +28,7 @@ public void integerFloat() { } @Test - public void argPriority() { + void argPriority() { List>> args = List.of( List.of(Word("word")), List.of(Literal("literal")) @@ -38,7 +37,7 @@ public void argPriority() { } @Test - public void similarArgs() { + void similarArgs() { List>> args = List.of( List.of(Word("a")), List.of(Word("b"), Word("a")) diff --git a/src/test/java/net/minestom/server/command/CommandSyntaxSingleTest.java b/src/test/java/net/minestom/server/command/CommandSyntaxSingleTest.java index 838620a4a1e..57428a4746b 100644 --- a/src/test/java/net/minestom/server/command/CommandSyntaxSingleTest.java +++ b/src/test/java/net/minestom/server/command/CommandSyntaxSingleTest.java @@ -15,9 +15,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; -public class CommandSyntaxSingleTest { +class CommandSyntaxSingleTest { @Test - public void singleInteger() { + void singleInteger() { List> args = List.of(Integer("number")); assertSyntax(args, "5", ExpectedExecution.SYNTAX, Map.of("number", 5)); assertSyntax(args, "5 5", ExpectedExecution.DEFAULT); @@ -25,7 +25,7 @@ public void singleInteger() { } @Test - public void singleIntegerInteger() { + void singleIntegerInteger() { List> args = List.of(Integer("number"), Integer("number2")); assertSyntax(args, "5", ExpectedExecution.DEFAULT); assertSyntax(args, "5 6", ExpectedExecution.SYNTAX, Map.of("number", 5, "number2", 6)); @@ -33,7 +33,7 @@ public void singleIntegerInteger() { } @Test - public void singleString() { + void singleString() { List> args = List.of(String("string")); assertSyntax(args, """ "value" @@ -43,7 +43,7 @@ public void singleString() { } @Test - public void singleStringString() { + void singleStringString() { List> args = List.of(String("string"), String("string2")); assertSyntax(args, "test", ExpectedExecution.DEFAULT); assertSyntax(args, """ @@ -57,7 +57,7 @@ public void singleStringString() { } @Test - public void singleGroup() { + void singleGroup() { List> args = List.of(Group("loop", Integer("first"), Integer("second"))); // 1 2 { @@ -71,7 +71,7 @@ public void singleGroup() { } @Test - public void singleLoop() { + void singleLoop() { List> stringLoop = List.of(Loop("loop", String("value"))); assertSyntax(stringLoop, "one two three", ExpectedExecution.SYNTAX, Map.of("loop", List.of("one", "two", "three"))); @@ -80,7 +80,7 @@ public void singleLoop() { } @Test - public void singleLoopGroup() { + void singleLoopGroup() { List> groupLoop = List.of(Loop("loop", Group("group", Integer("first"), Integer("second")))); // 1 2 { @@ -109,7 +109,7 @@ public void singleLoopGroup() { } @Test - public void singleLoopDoubleGroup() { + void singleLoopDoubleGroup() { List> groupLoop = List.of( Loop("loop", Group("group", BlockState("block"), EntityType("entity_type")), @@ -174,6 +174,9 @@ private static void assertSyntax(List> args, String input, ExpectedE if (expectedValues != null) { assertEquals(expectedValues, values.get()); } + + result.set(null); + values.set(null); } private static void assertSyntax(List> args, String input, ExpectedExecution expectedExecution) { diff --git a/src/test/java/net/minestom/server/command/CommandTest.java b/src/test/java/net/minestom/server/command/CommandTest.java index 420530aa47c..d56c151d1d2 100644 --- a/src/test/java/net/minestom/server/command/CommandTest.java +++ b/src/test/java/net/minestom/server/command/CommandTest.java @@ -10,10 +10,10 @@ import static org.junit.jupiter.api.Assertions.*; -public class CommandTest { +class CommandTest { @Test - public void testNames() { + void testNames() { Command command = new Command("name1", "name2", "name3"); assertEquals("name1", command.getName()); @@ -27,7 +27,7 @@ public void testNames() { } @Test - public void testGlobalListener() { + void testGlobalListener() { var manager = new CommandManager(); AtomicBoolean hasRun = new AtomicBoolean(false); diff --git a/src/test/java/net/minestom/server/command/GraphConversionExecutorTest.java b/src/test/java/net/minestom/server/command/GraphConversionExecutorTest.java index 55e5612f3e4..0bb5c4470c0 100644 --- a/src/test/java/net/minestom/server/command/GraphConversionExecutorTest.java +++ b/src/test/java/net/minestom/server/command/GraphConversionExecutorTest.java @@ -8,9 +8,9 @@ import static net.minestom.server.command.builder.arguments.ArgumentType.Literal; import static org.junit.jupiter.api.Assertions.*; -public class GraphConversionExecutorTest { +class GraphConversionExecutorTest { @Test - public void defaultCondition() { + void defaultCondition() { final Command foo = new Command("foo"); // Constant true { @@ -31,7 +31,7 @@ public void defaultCondition() { } @Test - public void emptySyntaxCondition() { + void emptySyntaxCondition() { final Command foo = new Command("foo"); foo.addSyntax(GraphConversionExecutorTest::dummyExecutor, Literal("first")); @@ -44,7 +44,7 @@ public void emptySyntaxCondition() { } @Test - public void syntaxConditionTrue() { + void syntaxConditionTrue() { final Command foo = new Command("foo"); foo.addConditionalSyntax((sender, context) -> true, GraphConversionExecutorTest::dummyExecutor, Literal("first")); @@ -57,7 +57,7 @@ public void syntaxConditionTrue() { } @Test - public void syntaxConditionFalse() { + void syntaxConditionFalse() { final Command foo = new Command("foo"); foo.addConditionalSyntax((sender, context) -> false, GraphConversionExecutorTest::dummyExecutor, Literal("first")); @@ -70,7 +70,7 @@ public void syntaxConditionFalse() { } @Test - public void commandConditionFalse() { + void commandConditionFalse() { final Command foo = new Command("foo"); foo.setCondition((sender, commandString) -> false); final Graph graph = Graph.fromCommand(foo); diff --git a/src/test/java/net/minestom/server/command/GraphConversionTest.java b/src/test/java/net/minestom/server/command/GraphConversionTest.java index 7c294232ed4..a429406c471 100644 --- a/src/test/java/net/minestom/server/command/GraphConversionTest.java +++ b/src/test/java/net/minestom/server/command/GraphConversionTest.java @@ -9,16 +9,16 @@ import static net.minestom.server.command.builder.arguments.ArgumentType.*; import static org.junit.jupiter.api.Assertions.assertTrue; -public class GraphConversionTest { +class GraphConversionTest { @Test - public void empty() { + void empty() { final Command foo = new Command("foo"); var graph = Graph.builder(Literal("foo")).build(); assertEqualsGraph(graph, foo); } @Test - public void singleLiteral() { + void singleLiteral() { final Command foo = new Command("foo"); var first = Literal("first"); foo.addSyntax(GraphConversionTest::dummyExecutor, first); @@ -28,7 +28,7 @@ public void singleLiteral() { } @Test - public void literalsPath() { + void literalsPath() { final Command foo = new Command("foo"); var first = Literal("first"); var second = Literal("second"); @@ -43,7 +43,7 @@ public void literalsPath() { } @Test - public void doubleSyntax() { + void doubleSyntax() { enum A {A, B, C, D, E} final Command foo = new Command("foo"); @@ -64,7 +64,7 @@ enum A {A, B, C, D, E} } @Test - public void doubleSyntaxMerge() { + void doubleSyntaxMerge() { final Command foo = new Command("foo"); var bar = Literal("bar"); @@ -81,7 +81,7 @@ public void doubleSyntaxMerge() { } @Test - public void subcommand() { + void subcommand() { final Command main = new Command("main"); final Command sub = new Command("sub"); @@ -107,14 +107,14 @@ public void subcommand() { } @Test - public void alias() { + void alias() { final Command main = new Command("main", "alias"); var graph = Graph.builder(Word("main").from("main", "alias")).build(); assertEqualsGraph(graph, main); } @Test - public void aliases() { + void aliases() { final Command main = new Command("main", "first", "second"); var graph = Graph.builder(Word("main").from("main", "first", "second")).build(); assertEqualsGraph(graph, main); diff --git a/src/test/java/net/minestom/server/command/GraphMergeTest.java b/src/test/java/net/minestom/server/command/GraphMergeTest.java index d257c0bd888..bed954ced10 100644 --- a/src/test/java/net/minestom/server/command/GraphMergeTest.java +++ b/src/test/java/net/minestom/server/command/GraphMergeTest.java @@ -8,10 +8,10 @@ import static net.minestom.server.command.builder.arguments.ArgumentType.Literal; import static org.junit.jupiter.api.Assertions.assertTrue; -public class GraphMergeTest { +class GraphMergeTest { @Test - public void commands() { + void commands() { var foo = new Command("foo"); var bar = new Command("bar"); var result = Graph.builder(Literal("")) @@ -22,7 +22,7 @@ public void commands() { } @Test - public void empty() { + void empty() { var graph1 = Graph.builder(Literal("foo")).build(); var graph2 = Graph.builder(Literal("bar")).build(); var result = Graph.builder(Literal("")) @@ -33,7 +33,7 @@ public void empty() { } @Test - public void literals() { + void literals() { var graph1 = Graph.builder(Literal("foo")).append(Literal("1")).build(); var graph2 = Graph.builder(Literal("bar")).append(Literal("2")).build(); var result = Graph.builder(Literal("")) diff --git a/src/test/java/net/minestom/server/command/GraphTest.java b/src/test/java/net/minestom/server/command/GraphTest.java index 388768e3bb3..91dff666e2c 100644 --- a/src/test/java/net/minestom/server/command/GraphTest.java +++ b/src/test/java/net/minestom/server/command/GraphTest.java @@ -9,9 +9,9 @@ import static net.minestom.server.command.builder.arguments.ArgumentType.Literal; import static org.junit.jupiter.api.Assertions.*; -public class GraphTest { +class GraphTest { @Test - public void empty() { + void empty() { var result = Graph.builder(Literal("")) .build(); var node = result.root(); @@ -20,7 +20,7 @@ public void empty() { } @Test - public void next() { + void next() { var result = Graph.builder(Literal("")) .append(Literal("foo")) .build(); @@ -31,7 +31,7 @@ public void next() { } @Test - public void immutableNextBuilder() { + void immutableNextBuilder() { var result = Graph.builder(Literal("")) .append(Literal("foo")) .append(Literal("bar")) @@ -42,7 +42,7 @@ public void immutableNextBuilder() { } @Test - public void immutableNextCommand() { + void immutableNextCommand() { final Command foo = new Command("foo"); var first = Literal("first"); foo.addSyntax(GraphTest::dummyExecutor, first); @@ -54,7 +54,7 @@ public void immutableNextCommand() { } @Test - public void immutableNextCommands() { + void immutableNextCommands() { final Command foo, bar; { diff --git a/src/test/java/net/minestom/server/command/SubcommandTest.java b/src/test/java/net/minestom/server/command/SubcommandTest.java index 6ed762fa232..88968d428de 100644 --- a/src/test/java/net/minestom/server/command/SubcommandTest.java +++ b/src/test/java/net/minestom/server/command/SubcommandTest.java @@ -8,10 +8,10 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -public class SubcommandTest { +class SubcommandTest { @Test - public void testSubCommands() { + void testSubCommands() { var manager = new CommandManager(); var parent = new Command("parent"); @@ -33,7 +33,7 @@ public void testSubCommands() { } @Test - public void testSubCommandConditions() { + void testSubCommandConditions() { var manager = new CommandManager(); var parent = new Command("parent"); diff --git a/src/test/java/net/minestom/server/coordinate/CoordinateTest.java b/src/test/java/net/minestom/server/coordinate/CoordinateTest.java index 560cf470c2c..2ebccae5928 100644 --- a/src/test/java/net/minestom/server/coordinate/CoordinateTest.java +++ b/src/test/java/net/minestom/server/coordinate/CoordinateTest.java @@ -11,10 +11,10 @@ import static net.minestom.server.utils.chunk.ChunkUtils.*; import static org.junit.jupiter.api.Assertions.*; -public class CoordinateTest { +class CoordinateTest { @Test - public void chunkIndex() { + void chunkIndex() { var index = getChunkIndex(2, 5); assertEquals(2, getChunkCoordX(index)); assertEquals(5, getChunkCoordZ(index)); @@ -29,7 +29,7 @@ public void chunkIndex() { } @Test - public void chunkCoordinate() { + void chunkCoordinate() { assertEquals(0, getChunkCoordinate(15)); assertEquals(1, getChunkCoordinate(16)); assertEquals(-1, getChunkCoordinate(-16)); @@ -43,7 +43,7 @@ public void chunkCoordinate() { } @Test - public void chunkCount() { + void chunkCount() { assertEquals(289, getChunkCount(8)); assertEquals(169, getChunkCount(6)); assertEquals(121, getChunkCount(5)); @@ -53,7 +53,7 @@ public void chunkCount() { } @Test - public void vecAddition() { + void vecAddition() { Vec temp = Vec.ZERO; assertEquals(0, temp.x()); assertEquals(0, temp.y()); @@ -81,7 +81,7 @@ public void vecAddition() { } @Test - public void vecWith() { + void vecWith() { Vec temp = Vec.ZERO.withX(1); assertEquals(1, temp.x()); assertEquals(0, temp.y()); @@ -94,7 +94,7 @@ public void vecWith() { } @Test - public void toSectionRelativeCoordinate() { + void toSectionRelativeCoordinate() { assertEquals(8, ChunkUtils.toSectionRelativeCoordinate(-40)); assertEquals(12, ChunkUtils.toSectionRelativeCoordinate(-20)); assertEquals(0, ChunkUtils.toSectionRelativeCoordinate(0)); @@ -107,7 +107,7 @@ public void toSectionRelativeCoordinate() { } @Test - public void blockIndex() { + void blockIndex() { // Test if the block index is correctly converted back and forth List tempEquals = List.of( @@ -151,7 +151,7 @@ public void blockIndex() { } @Test - public void blockIndexDuplicate() { + void blockIndexDuplicate() { LongSet temp = new LongOpenHashSet(); for (int x = 0; x < Chunk.CHUNK_SIZE_X; x++) { diff --git a/src/test/java/net/minestom/server/coordinate/PosViewDirectionTest.java b/src/test/java/net/minestom/server/coordinate/PosViewDirectionTest.java index e0ae029f68f..1072819aa01 100644 --- a/src/test/java/net/minestom/server/coordinate/PosViewDirectionTest.java +++ b/src/test/java/net/minestom/server/coordinate/PosViewDirectionTest.java @@ -4,11 +4,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -public class PosViewDirectionTest { +class PosViewDirectionTest { private static final float EPSILON = 0.01f; @Test - public void withLookAtPos() { + void withLookAtPos() { Pos initialPosition = new Pos(0, 40, 0); Pos position; diff --git a/src/test/java/net/minestom/server/entity/EntityAttributeTest.java b/src/test/java/net/minestom/server/entity/EntityAttributeTest.java index 521d3712add..4dc63446be8 100644 --- a/src/test/java/net/minestom/server/entity/EntityAttributeTest.java +++ b/src/test/java/net/minestom/server/entity/EntityAttributeTest.java @@ -10,13 +10,13 @@ import net.minestom.server.item.component.AttributeList; import net.minestom.server.utils.NamespaceID; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -@EnvTest +@ExtendWith(MicrotusExtension.class) public class EntityAttributeTest { @Test diff --git a/src/test/java/net/minestom/server/entity/EntityBoundingBoxIntegrationTest.java b/src/test/java/net/minestom/server/entity/EntityBoundingBoxIntegrationTest.java index dc20cd87d83..734365b3c38 100644 --- a/src/test/java/net/minestom/server/entity/EntityBoundingBoxIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/EntityBoundingBoxIntegrationTest.java @@ -1,21 +1,22 @@ package net.minestom.server.entity; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.collision.BoundingBox; import net.minestom.server.coordinate.Pos; import net.minestom.server.event.item.PickupItemEvent; import net.minestom.server.instance.Instance; import net.minestom.server.item.ItemStack; import net.minestom.server.item.Material; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest -public class EntityBoundingBoxIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class EntityBoundingBoxIntegrationTest { @Test - public void pose(Env env) { + void pose(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); @@ -36,7 +37,7 @@ public void pose(Env env) { } @Test - public void eyeHeight(Env env) { + void eyeHeight(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); @@ -54,7 +55,7 @@ public void eyeHeight(Env env) { } @Test - public void pickupItem(Env env) { + void pickupItem(Env env) { final var instance = env.createFlatInstance(); final var listener = env.listen(PickupItemEvent.class); final var spawnPos = new Pos(0, 42, 0); diff --git a/src/test/java/net/minestom/server/entity/EntityFireTest.java b/src/test/java/net/minestom/server/entity/EntityFireTest.java index a9c45431e00..b744e4b0f3c 100644 --- a/src/test/java/net/minestom/server/entity/EntityFireTest.java +++ b/src/test/java/net/minestom/server/entity/EntityFireTest.java @@ -4,16 +4,16 @@ import net.minestom.server.event.entity.EntityFireExtinguishEvent; import net.minestom.server.event.entity.EntitySetFireEvent; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.concurrent.atomic.AtomicInteger; import static org.junit.jupiter.api.Assertions.*; -@EnvTest -public class EntityFireTest -{ +@ExtendWith(MicrotusExtension.class) +public class EntityFireTest { @Test public void duration(Env env) { var instance = env.createFlatInstance(); diff --git a/src/test/java/net/minestom/server/entity/EntityInstanceIntegrationTest.java b/src/test/java/net/minestom/server/entity/EntityInstanceIntegrationTest.java index 5a9d128ef0d..0c6b5cede1d 100644 --- a/src/test/java/net/minestom/server/entity/EntityInstanceIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/EntityInstanceIntegrationTest.java @@ -1,20 +1,21 @@ package net.minestom.server.entity; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Pos; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.time.Duration; import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest -public class EntityInstanceIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class EntityInstanceIntegrationTest { @Test - public void entityJoin(Env env) { + void entityJoin(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityTypes.ZOMBIE); entity.setInstance(instance, new Pos(0, 42, 0)).join(); @@ -23,7 +24,7 @@ public void entityJoin(Env env) { } @Test - public void playerJoin(Env env) { + void playerJoin(Env env) { var instance = env.createFlatInstance(); var player = env.createPlayer(instance, new Pos(0, 42, 0)); assertEquals(instance, player.getInstance()); @@ -31,7 +32,7 @@ public void playerJoin(Env env) { } @Test - public void playerSwitch(Env env) { + void playerSwitch(Env env) { var instance = env.createFlatInstance(); var instance2 = env.createFlatInstance(); var connection = env.createConnection(); diff --git a/src/test/java/net/minestom/server/entity/EntityLineOfSightIntegrationTest.java b/src/test/java/net/minestom/server/entity/EntityLineOfSightIntegrationTest.java index a6bb809294a..914f68b7186 100644 --- a/src/test/java/net/minestom/server/entity/EntityLineOfSightIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/EntityLineOfSightIntegrationTest.java @@ -1,17 +1,18 @@ package net.minestom.server.entity; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Pos; import net.minestom.server.instance.block.Block; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.*; -@EnvTest -public class EntityLineOfSightIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class EntityLineOfSightIntegrationTest { @Test - public void entityPhysicsCheckLineOfSight(Env env) { + void entityPhysicsCheckLineOfSight(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityTypes.ZOMBIE); @@ -21,7 +22,7 @@ public void entityPhysicsCheckLineOfSight(Env env) { var entity2 = new Entity(EntityTypes.ZOMBIE); entity2.setInstance(instance, new Pos(10, 42, 0)).join(); - assertEquals(entity2, entity.getLineOfSightEntity(20, (e) -> true)); + assertEquals(entity2, entity.getLineOfSightEntity(20, predicate -> true)); assertTrue(entity.hasLineOfSight(entity2, true)); for (int z = -1; z <= 1; ++z) { @@ -30,12 +31,12 @@ public void entityPhysicsCheckLineOfSight(Env env) { } } - assertNull(entity.getLineOfSightEntity(20, (e) -> true)); + assertNull(entity.getLineOfSightEntity(20, predicate -> true)); assertFalse(entity.hasLineOfSight(entity2, true)); } @Test - public void entityPhysicsCheckLineOfSightBehind(Env env) { + void entityPhysicsCheckLineOfSightBehind(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityTypes.ZOMBIE); @@ -45,7 +46,7 @@ public void entityPhysicsCheckLineOfSightBehind(Env env) { var entity2 = new Entity(EntityTypes.ZOMBIE); entity2.setInstance(instance, new Pos(-10, 42, 0)).join(); - assertNull(entity.getLineOfSightEntity(20, (e) -> true)); + assertNull(entity.getLineOfSightEntity(20, predicate -> true)); assertFalse(entity.hasLineOfSight(entity2, true)); assertTrue(entity.hasLineOfSight(entity2, false)); @@ -59,7 +60,7 @@ public void entityPhysicsCheckLineOfSightBehind(Env env) { } @Test - public void entityPhysicsCheckLineOfSightNearMiss(Env env) { + void entityPhysicsCheckLineOfSightNearMiss(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityTypes.ZOMBIE); @@ -69,7 +70,7 @@ public void entityPhysicsCheckLineOfSightNearMiss(Env env) { var entity2 = new Entity(EntityTypes.ZOMBIE); entity2.setInstance(instance, new Pos(10, 42, 0.31)).join(); - assertNull(entity.getLineOfSightEntity(20, (e) -> true)); + assertNull(entity.getLineOfSightEntity(20, predicate -> true)); assertFalse(entity.hasLineOfSight(entity2, true)); assertTrue(entity.hasLineOfSight(entity2, false)); @@ -83,7 +84,7 @@ public void entityPhysicsCheckLineOfSightNearMiss(Env env) { } @Test - public void entityPhysicsCheckLineOfSightNearHit(Env env) { + void entityPhysicsCheckLineOfSightNearHit(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityTypes.ZOMBIE); @@ -93,7 +94,7 @@ public void entityPhysicsCheckLineOfSightNearHit(Env env) { var entity2 = new Entity(EntityTypes.ZOMBIE); entity2.setInstance(instance, new Pos(10, 42, 0.3)).join(); - assertEquals(entity2, entity.getLineOfSightEntity(20, (e) -> true)); + assertEquals(entity2, entity.getLineOfSightEntity(20, predicate -> true)); assertTrue(entity.hasLineOfSight(entity2, true)); assertTrue(entity.hasLineOfSight(entity2, false)); @@ -103,13 +104,13 @@ public void entityPhysicsCheckLineOfSightNearHit(Env env) { } } - assertNull(entity.getLineOfSightEntity(20, (e) -> true)); + assertNull(entity.getLineOfSightEntity(20, predicate -> true)); assertFalse(entity.hasLineOfSight(entity2, true)); assertFalse(entity.hasLineOfSight(entity2, false)); } @Test - public void entityPhysicsCheckLineOfSightCorrectOrder(Env env) { + void entityPhysicsCheckLineOfSightCorrectOrder(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityTypes.ZOMBIE); @@ -122,7 +123,7 @@ public void entityPhysicsCheckLineOfSightCorrectOrder(Env env) { var entity3 = new Entity(EntityTypes.ZOMBIE); entity3.setInstance(instance, new Pos(5, 42, 0)).join(); - assertEquals(entity3, entity.getLineOfSightEntity(20, (e) -> true)); + assertEquals(entity3, entity.getLineOfSightEntity(20, predicate -> true)); assertTrue(entity.hasLineOfSight(entity2, true)); assertTrue(entity.hasLineOfSight(entity2, false)); assertTrue(entity.hasLineOfSight(entity3, true)); @@ -130,7 +131,7 @@ public void entityPhysicsCheckLineOfSightCorrectOrder(Env env) { } @Test - public void entityPhysicsCheckLineOfSightBigMiss(Env env) { + void entityPhysicsCheckLineOfSightBigMiss(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityTypes.ZOMBIE); @@ -140,12 +141,12 @@ public void entityPhysicsCheckLineOfSightBigMiss(Env env) { var entity2 = new Entity(EntityTypes.ZOMBIE); entity2.setInstance(instance, new Pos(10, 42, 10)).join(); - assertNull(entity.getLineOfSightEntity(20, (e) -> true)); + assertNull(entity.getLineOfSightEntity(20, predicate -> true)); assertFalse(entity.hasLineOfSight(entity2, true)); assertTrue(entity.hasLineOfSight(entity2, false)); } @Test - public void entityPhysicsCheckLineOfSightLargeBoundingBox(Env env) { + void entityPhysicsCheckLineOfSightLargeBoundingBox(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityTypes.ZOMBIE); @@ -162,7 +163,7 @@ public void entityPhysicsCheckLineOfSightLargeBoundingBox(Env env) { } } - assertEquals(entity2, entity.getLineOfSightEntity(20, (e) -> true)); + assertEquals(entity2, entity.getLineOfSightEntity(20, predicate -> true)); assertTrue(entity.hasLineOfSight(entity2, true)); assertTrue(entity.hasLineOfSight(entity2, false)); } diff --git a/src/test/java/net/minestom/server/entity/EntityMetaIntegrationTest.java b/src/test/java/net/minestom/server/entity/EntityMetaIntegrationTest.java index fdd5a255479..e27102317a8 100644 --- a/src/test/java/net/minestom/server/entity/EntityMetaIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/EntityMetaIntegrationTest.java @@ -4,20 +4,21 @@ import net.minestom.server.coordinate.Pos; import net.minestom.server.network.packet.server.play.EntityMetaDataPacket; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.List; import java.util.function.Consumer; import static org.junit.jupiter.api.Assertions.*; -@EnvTest -public class EntityMetaIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class EntityMetaIntegrationTest { @Test - public void notifyAboutChanges(Env env) { + void notifyAboutChanges(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var otherPlayer = connection.connect(instance, new Pos(0, 42, 0)).join(); @@ -85,7 +86,7 @@ private void validMetaDataPackets(List packets, int entity } @Test - public void customName(Env env) { + void customName(Env env) { //Base things. var connection = env.createConnection(); var instance = env.createFlatInstance(); diff --git a/src/test/java/net/minestom/server/entity/EntityMetaTest.java b/src/test/java/net/minestom/server/entity/EntityMetaTest.java index a9e6025d03e..210883d3cbe 100644 --- a/src/test/java/net/minestom/server/entity/EntityMetaTest.java +++ b/src/test/java/net/minestom/server/entity/EntityMetaTest.java @@ -7,10 +7,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue; -public class EntityMetaTest { +class EntityMetaTest { @Test - public void ensureRegistration() throws IllegalAccessException { + void ensureRegistration() throws IllegalAccessException { List list = new ArrayList<>(); for (var field : EntityTypes.class.getDeclaredFields()) { final EntityType entityType = (EntityType) field.get(this); diff --git a/src/test/java/net/minestom/server/entity/EntityPhysicsIntegrationTest.java b/src/test/java/net/minestom/server/entity/EntityPhysicsIntegrationTest.java index c5b04f65c92..46c373872f0 100644 --- a/src/test/java/net/minestom/server/entity/EntityPhysicsIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/EntityPhysicsIntegrationTest.java @@ -3,16 +3,17 @@ import net.minestom.server.coordinate.Pos; import net.minestom.server.instance.block.Block; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.*; -@EnvTest -public class EntityPhysicsIntegrationTest -{ + +@ExtendWith(MicrotusExtension.class) +class EntityPhysicsIntegrationTest { @Test - public void onGround(Env env) { + void onGround(Env env) { var instance = env.createFlatInstance(); instance.setBlock(1, 40, 1, Block.STONE); diff --git a/src/test/java/net/minestom/server/entity/EntityProjectileIntegrationTest.java b/src/test/java/net/minestom/server/entity/EntityProjectileIntegrationTest.java index 814257ce83d..e87668e8420 100644 --- a/src/test/java/net/minestom/server/entity/EntityProjectileIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/EntityProjectileIntegrationTest.java @@ -1,16 +1,17 @@ package net.minestom.server.entity; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Pos; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest -public class EntityProjectileIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class EntityProjectileIntegrationTest { @Test - public void gravityVelocity(Env env) { + void gravityVelocity(Env env) { var instance = env.createFlatInstance(); var shooter = new EntityCreature(EntityType.SKELETON); shooter.setInstance(instance, new Pos(0, 42, 0)).join(); @@ -42,7 +43,7 @@ public void gravityVelocity(Env env) { } @Test - public void noGravityVelocity(Env env) { + void noGravityVelocity(Env env) { var instance = env.createFlatInstance(); var shooter = new EntityCreature(EntityType.SKELETON); shooter.setInstance(instance, new Pos(0, 42, 0)).join(); diff --git a/src/test/java/net/minestom/server/entity/EntityRemovalIntegrationTest.java b/src/test/java/net/minestom/server/entity/EntityRemovalIntegrationTest.java index 42d6e2f2377..5810255f742 100644 --- a/src/test/java/net/minestom/server/entity/EntityRemovalIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/EntityRemovalIntegrationTest.java @@ -1,12 +1,13 @@ package net.minestom.server.entity; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Pos; import net.minestom.server.event.entity.EntityTickEvent; import net.minestom.server.network.packet.server.play.DestroyEntitiesPacket; import net.minestom.server.utils.time.TimeUnit; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.lang.ref.WeakReference; import java.time.temporal.TemporalUnit; @@ -15,11 +16,11 @@ import static net.minestom.testing.TestUtils.waitUntilCleared; import static org.junit.jupiter.api.Assertions.*; -@EnvTest -public class EntityRemovalIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class EntityRemovalIntegrationTest { @Test - public void destructionPacket(Env env) { + void destructionPacket(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); connection.connect(instance, new Pos(0, 40, 0)).join(); @@ -33,7 +34,7 @@ public void destructionPacket(Env env) { } @Test - public void instanceRemoval(Env env) { + void instanceRemoval(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityType.ZOMBIE); entity.setInstance(instance, new Pos(0, 40, 0)).join(); @@ -45,7 +46,7 @@ public void instanceRemoval(Env env) { } @Test - public void tickTimedRemoval(Env env) throws InterruptedException { + void tickTimedRemoval(Env env) throws InterruptedException { var instance = env.createFlatInstance(); var entity = new TestEntity(2, TimeUnit.SERVER_TICK); entity.setInstance(instance, new Pos(0, 40, 0)).join(); @@ -65,7 +66,7 @@ public void tickTimedRemoval(Env env) throws InterruptedException { } @Test - public void entityGC(Env env) { + void entityGC(Env env) { // Ensure that entities do not stay in memory after they are removed var instance = env.createFlatInstance(); var entity = new Entity(EntityType.ZOMBIE); @@ -80,7 +81,7 @@ public void entityGC(Env env) { } @Test - public void entityNodeGC(Env env) { + void entityNodeGC(Env env) { // Ensure that the entities GCed when a local listener is present var node = env.process().eventHandler(); var entity = new Entity(EntityType.ZOMBIE); @@ -97,7 +98,7 @@ public void entityNodeGC(Env env) { } static final class TestEntity extends Entity { - public TestEntity(long delay, TemporalUnit unit) { + TestEntity(long delay, TemporalUnit unit) { super(EntityType.ZOMBIE); scheduleRemove(delay, unit); } diff --git a/src/test/java/net/minestom/server/entity/EntityTeleportIntegrationTest.java b/src/test/java/net/minestom/server/entity/EntityTeleportIntegrationTest.java index f9d5cc148cd..86fb0c6b6bd 100644 --- a/src/test/java/net/minestom/server/entity/EntityTeleportIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/EntityTeleportIntegrationTest.java @@ -2,22 +2,23 @@ import net.minestom.server.network.packet.server.play.EntityHeadLookPacket; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Pos; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.play.EntityTeleportPacket; import net.minestom.server.network.packet.server.play.PlayerPositionAndLookPacket; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest -public class EntityTeleportIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class EntityTeleportIntegrationTest { @Test - public void entityChunkTeleport(Env env) { + void entityChunkTeleport(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityTypes.ZOMBIE); entity.setInstance(instance, new Pos(0, 42, 0)).join(); @@ -29,7 +30,7 @@ public void entityChunkTeleport(Env env) { } @Test - public void entityTeleport(Env env) { + void entityTeleport(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityTypes.ZOMBIE); entity.setInstance(instance, new Pos(0, 42, 0)).join(); @@ -41,7 +42,7 @@ public void entityTeleport(Env env) { } @Test - public void playerChunkTeleport(Env env) { + void playerChunkTeleport(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 40, 0)).join(); @@ -74,7 +75,7 @@ public void playerChunkTeleport(Env env) { } @Test - public void playerTeleport(Env env) { + void playerTeleport(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 40, 0)).join(); @@ -90,7 +91,7 @@ public void playerTeleport(Env env) { } @Test - public void playerTeleportWithFlagsTest(Env env) { + void playerTeleportWithFlagsTest(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 0, 0)).join(); diff --git a/src/test/java/net/minestom/server/entity/EntityVelocityIntegrationTest.java b/src/test/java/net/minestom/server/entity/EntityVelocityIntegrationTest.java index b9605b60d05..a4d508a6418 100644 --- a/src/test/java/net/minestom/server/entity/EntityVelocityIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/EntityVelocityIntegrationTest.java @@ -2,23 +2,24 @@ import net.minestom.server.instance.block.Block; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Vec; import net.minestom.server.instance.Instance; import net.minestom.server.network.packet.server.play.EntityVelocityPacket; import net.minestom.server.utils.chunk.ChunkUtils; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.BooleanSupplier; import static org.junit.jupiter.api.Assertions.*; -@EnvTest -public class EntityVelocityIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class EntityVelocityIntegrationTest { @Test - public void gravity(Env env) { + void gravity(Env env) { var instance = env.createFlatInstance(); loadChunks(instance); @@ -37,7 +38,7 @@ public void gravity(Env env) { } @Test - public void singleKnockback(Env env) { + void singleKnockback(Env env) { var instance = env.createFlatInstance(); loadChunks(instance); @@ -68,7 +69,7 @@ public void singleKnockback(Env env) { } @Test - public void doubleKnockback(Env env) { + void doubleKnockback(Env env) { var instance = env.createFlatInstance(); loadChunks(instance); @@ -103,7 +104,7 @@ public void doubleKnockback(Env env) { } @Test - public void flyingVelocity(Env env) { + void flyingVelocity(Env env) { var instance = env.createFlatInstance(); loadChunks(instance); @@ -128,7 +129,7 @@ public void flyingVelocity(Env env) { } @Test - public void flyingPlayerMovement(Env env) { + void flyingPlayerMovement(Env env) { // Player movement should not send velocity packets as already client predicted var instance = env.createFlatInstance(); var player = env.createPlayer(instance, new Pos(0, 42, 0)); @@ -142,7 +143,7 @@ public void flyingPlayerMovement(Env env) { } @Test - public void testHasVelocity(Env env) { + void testHasVelocity(Env env) { var instance = env.createFlatInstance(); loadChunks(instance); @@ -169,7 +170,7 @@ public void testHasVelocity(Env env) { } @Test - public void countVelocityPackets(Env env) { + void countVelocityPackets(Env env) { var instance = env.createFlatInstance(); var viewerConnection = env.createConnection(); viewerConnection.connect(instance, new Pos(1, 40, 1)).join(); diff --git a/src/test/java/net/minestom/server/entity/EntityViewDirectionIntegrationTest.java b/src/test/java/net/minestom/server/entity/EntityViewDirectionIntegrationTest.java index a6cb8e7aa75..a1d211d200e 100644 --- a/src/test/java/net/minestom/server/entity/EntityViewDirectionIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/EntityViewDirectionIntegrationTest.java @@ -2,18 +2,19 @@ import net.minestom.server.coordinate.Pos; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -@EnvTest -public class EntityViewDirectionIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class EntityViewDirectionIntegrationTest { private static final float EPSILON = 0.01f; @Test - public void viewYawAndPitch(Env env) { + void viewYawAndPitch(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityType.ZOMBIE); entity.setInstance(instance, new Pos(0, 40, 0)).join(); @@ -48,7 +49,7 @@ public void viewYawAndPitch(Env env) { } @Test - public void lookAtPos(Env env) { + void lookAtPos(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityType.ZOMBIE); double eyeHeight = entity.getEyeHeight(); // adding this to some position Y coordinates, to look horizontally @@ -87,7 +88,7 @@ public void lookAtPos(Env env) { } @Test - public void lookAtEntitySameType(Env env) { + void lookAtEntitySameType(Env env) { var instance = env.createFlatInstance(); // same type, same eye height var e1 = new Entity(EntityType.ZOMBIE); @@ -121,7 +122,7 @@ public void lookAtEntitySameType(Env env) { } @Test - public void lookAtEntityDifferentType(Env env) { + void lookAtEntityDifferentType(Env env) { var instance = env.createFlatInstance(); // same type, same eye height var e1 = new Entity(EntityType.ZOMBIE); diff --git a/src/test/java/net/minestom/server/entity/EntityViewIntegrationTest.java b/src/test/java/net/minestom/server/entity/EntityViewIntegrationTest.java index 181b303252a..34129fff6d5 100644 --- a/src/test/java/net/minestom/server/entity/EntityViewIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/EntityViewIntegrationTest.java @@ -1,18 +1,19 @@ package net.minestom.server.entity; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Pos; import net.minestom.server.network.packet.server.play.SpawnEntityPacket; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.*; -@EnvTest -public class EntityViewIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class EntityViewIntegrationTest { @Test - public void emptyEntity(Env env) { + void emptyEntity(Env env) { var instance = env.createFlatInstance(); var entity = new Entity(EntityType.ZOMBIE); entity.setInstance(instance, new Pos(0, 40, 42)).join(); @@ -20,14 +21,14 @@ public void emptyEntity(Env env) { } @Test - public void emptyPlayer(Env env) { + void emptyPlayer(Env env) { var instance = env.createFlatInstance(); var player = env.createPlayer(instance, new Pos(0, 42, 0)); assertEquals(0, player.getViewers().size()); } @Test - public void multiPlayers(Env env) { + void multiPlayers(Env env) { var instance = env.createFlatInstance(); var p1 = env.createPlayer(instance, new Pos(0, 42, 42)); var p2 = env.createPlayer(instance, new Pos(0, 42, 42)); @@ -48,7 +49,7 @@ public void multiPlayers(Env env) { } @Test - public void manualViewers(Env env) { + void manualViewers(Env env) { var instance = env.createFlatInstance(); var p1 = env.createPlayer(instance, new Pos(0, 42, 0)); var p2 = env.createPlayer(instance, new Pos(0, 42, 5_000)); @@ -65,7 +66,7 @@ public void manualViewers(Env env) { } @Test - public void movements(Env env) { + void movements(Env env) { var instance = env.createFlatInstance(); var p1 = env.createPlayer(instance, new Pos(0, 42, 0)); var p2 = env.createPlayer(instance, new Pos(0, 42, 96)); @@ -79,7 +80,7 @@ public void movements(Env env) { } @Test - public void autoViewable(Env env) { + void autoViewable(Env env) { var instance = env.createFlatInstance(); var p1 = env.createPlayer(instance, new Pos(0, 42, 0)); assertTrue(p1.isAutoViewable()); @@ -96,7 +97,7 @@ public void autoViewable(Env env) { } @Test - public void predictableViewers(Env env) { + void predictableViewers(Env env) { var instance = env.createFlatInstance(); var p = env.createPlayer(instance, new Pos(0, 42, 0)); assertTrue(p.hasPredictableViewers()); @@ -123,7 +124,7 @@ public void predictableViewers(Env env) { } @Test - public void livingVehicle(Env env) { + void livingVehicle(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 40, 0)).join(); @@ -153,7 +154,7 @@ public void livingVehicle(Env env) { } @Test - public void vehicleInheritance(Env env) { + void vehicleInheritance(Env env) { var instance = env.createFlatInstance(); var p1 = env.createPlayer(instance, new Pos(0, 40, 0)); var p2 = env.createPlayer(instance, new Pos(0, 40, 0)); diff --git a/src/test/java/net/minestom/server/entity/EntityViewerRuleIntegrationTest.java b/src/test/java/net/minestom/server/entity/EntityViewerRuleIntegrationTest.java index 40038cf6f25..71bbbe2091b 100644 --- a/src/test/java/net/minestom/server/entity/EntityViewerRuleIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/EntityViewerRuleIntegrationTest.java @@ -1,19 +1,20 @@ package net.minestom.server.entity; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Pos; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.concurrent.atomic.AtomicBoolean; import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest -public class EntityViewerRuleIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class EntityViewerRuleIntegrationTest { @Test - public void viewableRule(Env env) { + void viewableRule(Env env) { var instance = env.createFlatInstance(); var p1 = env.createPlayer(instance, new Pos(0, 42, 0)); p1.updateViewableRule(p -> p.getEntityId() == p1.getEntityId() + 1); @@ -30,7 +31,7 @@ public void viewableRule(Env env) { } @Test - public void viewableRuleUpdate(Env env) { + void viewableRuleUpdate(Env env) { var instance = env.createFlatInstance(); var p1 = env.createPlayer(instance, new Pos(0, 42, 0)); @@ -48,7 +49,7 @@ public void viewableRuleUpdate(Env env) { } @Test - public void viewableRuleDouble(Env env) { + void viewableRuleDouble(Env env) { var instance = env.createFlatInstance(); var p1 = env.createPlayer(instance, new Pos(0, 42, 0)); var p2 = env.createPlayer(instance, new Pos(0, 42, 0)); @@ -80,7 +81,7 @@ public void viewableRuleDouble(Env env) { } @Test - public void viewerRule(Env env) { + void viewerRule(Env env) { var instance = env.createFlatInstance(); var p1 = env.createPlayer(instance, new Pos(0, 42, 0)); p1.updateViewerRule(e -> e.getEntityId() == p1.getEntityId() + 1); @@ -97,7 +98,7 @@ public void viewerRule(Env env) { } @Test - public void viewerRuleUpdate(Env env) { + void viewerRuleUpdate(Env env) { var instance = env.createFlatInstance(); var p1 = env.createPlayer(instance, new Pos(0, 42, 0)); AtomicBoolean enabled = new AtomicBoolean(false); @@ -114,7 +115,7 @@ public void viewerRuleUpdate(Env env) { } @Test - public void viewerRuleDouble(Env env) { + void viewerRuleDouble(Env env) { var instance = env.createFlatInstance(); var p1 = env.createPlayer(instance, new Pos(0, 42, 0)); var p2 = env.createPlayer(instance, new Pos(0, 42, 0)); diff --git a/src/test/java/net/minestom/server/entity/GameModeTest.java b/src/test/java/net/minestom/server/entity/GameModeTest.java index 2d7ea85dd07..f249cac8065 100644 --- a/src/test/java/net/minestom/server/entity/GameModeTest.java +++ b/src/test/java/net/minestom/server/entity/GameModeTest.java @@ -4,18 +4,18 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -public class GameModeTest { +class GameModeTest { @Test - public void toId() { - assertEquals(GameMode.SURVIVAL.id(), 0); - assertEquals(GameMode.CREATIVE.id(), 1); - assertEquals(GameMode.ADVENTURE.id(), 2); - assertEquals(GameMode.SPECTATOR.id(), 3); + void toId() { + assertEquals(0, GameMode.SURVIVAL.id()); + assertEquals(1, GameMode.CREATIVE.id()); + assertEquals(2, GameMode.ADVENTURE.id()); + assertEquals(3, GameMode.SPECTATOR.id()); } @Test - public void fromId() { + void fromId() { assertEquals(GameMode.SURVIVAL, GameMode.fromId(0)); assertEquals(GameMode.CREATIVE, GameMode.fromId(1)); assertEquals(GameMode.ADVENTURE, GameMode.fromId(2)); diff --git a/src/test/java/net/minestom/server/entity/PassengerIntegrationTest.java b/src/test/java/net/minestom/server/entity/PassengerIntegrationTest.java index 2ce48c46d71..7ad4a2b630b 100644 --- a/src/test/java/net/minestom/server/entity/PassengerIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/PassengerIntegrationTest.java @@ -3,17 +3,18 @@ import net.minestom.server.network.packet.server.play.SetPassengersPacket; import net.minestom.server.network.packet.server.play.SpawnEntityPacket; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Pos; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.*; -@EnvTest -public class PassengerIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class PassengerIntegrationTest { @Test - public void passenger(Env env) { + void passenger(Env env) { var instance = env.createFlatInstance(); var vehicle = new Entity(EntityType.ZOMBIE); var passenger = new Entity(EntityType.ZOMBIE); @@ -30,7 +31,7 @@ public void passenger(Env env) { } @Test - public void passengerTeleport(Env env) { + void passengerTeleport(Env env) { var instance = env.createFlatInstance(); var vehicle = new Entity(EntityType.ZOMBIE); var passenger = new Entity(EntityType.ZOMBIE); @@ -49,7 +50,7 @@ public void passengerTeleport(Env env) { } @Test - public void passengerPacketOrder(Env env) { + void passengerPacketOrder(Env env) { var instance = env.createFlatInstance(); var vehicle = new Entity(EntityType.ZOMBIE); vehicle.setInstance(instance, new Pos(0, 40, 0)).join(); diff --git a/src/test/java/net/minestom/server/entity/PlayerHeldIntegrationTest.java b/src/test/java/net/minestom/server/entity/PlayerHeldIntegrationTest.java index ecd9a07bdf7..626e37504ed 100644 --- a/src/test/java/net/minestom/server/entity/PlayerHeldIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/PlayerHeldIntegrationTest.java @@ -6,16 +6,17 @@ import net.minestom.server.item.Material; import net.minestom.server.network.packet.client.play.ClientHeldItemChangePacket; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest -public class PlayerHeldIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class PlayerHeldIntegrationTest { @Test - public void playerHeld(Env env) { + void playerHeld(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 40, 0)).join(); @@ -32,7 +33,7 @@ public void playerHeld(Env env) { } @Test - public void playerHeldEvent(Env env) { + void playerHeldEvent(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 40, 0)).join(); diff --git a/src/test/java/net/minestom/server/entity/PlayerSkinTest.java b/src/test/java/net/minestom/server/entity/PlayerSkinTest.java index 6446903da29..27629136e4b 100644 --- a/src/test/java/net/minestom/server/entity/PlayerSkinTest.java +++ b/src/test/java/net/minestom/server/entity/PlayerSkinTest.java @@ -6,18 +6,18 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; -public class PlayerSkinTest { +class PlayerSkinTest { @Disabled @Test - public void validName() { + void validName() { var skin = PlayerSkin.fromUsername("jeb_"); assertNotNull(skin); } @Disabled @Test - public void invalidName() { + void invalidName() { var skin = PlayerSkin.fromUsername("jfdsa84vvcxadubasdfcvn"); assertNull(skin); } diff --git a/src/test/java/net/minestom/server/entity/ai/ClosestEntityTargetTest.java b/src/test/java/net/minestom/server/entity/ai/ClosestEntityTargetTest.java index 5c34c621e1b..97e1f353d8e 100644 --- a/src/test/java/net/minestom/server/entity/ai/ClosestEntityTargetTest.java +++ b/src/test/java/net/minestom/server/entity/ai/ClosestEntityTargetTest.java @@ -1,21 +1,22 @@ package net.minestom.server.entity.ai; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.EntityCreature; import net.minestom.server.entity.EntityType; import net.minestom.server.entity.ai.target.ClosestEntityTarget; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -@EnvTest -public class ClosestEntityTargetTest { +@ExtendWith(MicrotusExtension.class) +class ClosestEntityTargetTest { @Test - public void validFindTarget(Env env) { + void validFindTarget(Env env) { var instance = env.createFlatInstance(); var self = new EntityCreature(EntityType.ZOMBIE); diff --git a/src/test/java/net/minestom/server/entity/metadata/animal/FrogMetaTest.java b/src/test/java/net/minestom/server/entity/metadata/animal/FrogMetaTest.java new file mode 100644 index 00000000000..1ba1805b527 --- /dev/null +++ b/src/test/java/net/minestom/server/entity/metadata/animal/FrogMetaTest.java @@ -0,0 +1,19 @@ +package net.minestom.server.entity.metadata.animal; + +import net.minestom.server.entity.metadata.animal.FrogMeta.Variant; +import net.minestom.server.network.NetworkBuffer; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +// Microtus - meta update + add test for the variant read method +class FrogMetaTest { + + @Test + void testFrogVariantRead() { + /*assertEquals(Variant.WARM, Variant.getVariant(Variant.WARM.ordinal())); + assertEquals(Variant.TEMPERATE, Variant.getVariant(0)); + assertNull(Variant.getVariant(-1)); + assertNull(Variant.getVariant(100));*/ + } +} \ No newline at end of file diff --git a/src/test/java/net/minestom/server/entity/pathfinding/PathfinderIntegrationTest.java b/src/test/java/net/minestom/server/entity/pathfinding/PathfinderIntegrationTest.java index dd203dae8be..e47c277af3c 100644 --- a/src/test/java/net/minestom/server/entity/pathfinding/PathfinderIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/pathfinding/PathfinderIntegrationTest.java @@ -8,8 +8,9 @@ import net.minestom.server.instance.block.Block; import net.minestom.server.utils.chunk.ChunkUtils; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.HashSet; import java.util.List; @@ -18,7 +19,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; -@EnvTest +@ExtendWith(MicrotusExtension.class) public class PathfinderIntegrationTest { /** diff --git a/src/test/java/net/minestom/server/entity/player/PlayerBlockPlacementIntegrationTest.java b/src/test/java/net/minestom/server/entity/player/PlayerBlockPlacementIntegrationTest.java index 60b296aaf07..90ef13af8f7 100644 --- a/src/test/java/net/minestom/server/entity/player/PlayerBlockPlacementIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/player/PlayerBlockPlacementIntegrationTest.java @@ -14,7 +14,8 @@ import net.minestom.server.item.component.BlockPredicates; import net.minestom.server.network.packet.client.play.ClientPlayerBlockPlacementPacket; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; +import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -23,12 +24,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest -public class PlayerBlockPlacementIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class PlayerBlockPlacementIntegrationTest { @ParameterizedTest @MethodSource("placeBlockFromAdventureModeParams") - public void placeBlockFromAdventureMode(Block baseBlock, BlockPredicates canPlaceOn, Env env) { + void placeBlockFromAdventureMode(Block baseBlock, BlockPredicates canPlaceOn, Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); diff --git a/src/test/java/net/minestom/server/entity/player/PlayerIntegrationTest.java b/src/test/java/net/minestom/server/entity/player/PlayerIntegrationTest.java index 98b914f82c9..6fbd2370601 100644 --- a/src/test/java/net/minestom/server/entity/player/PlayerIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/player/PlayerIntegrationTest.java @@ -15,9 +15,10 @@ import net.minestom.server.world.DimensionType; import net.minestom.testing.Collector; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.time.Duration; import java.util.ArrayList; @@ -25,15 +26,15 @@ import static org.junit.jupiter.api.Assertions.*; -@EnvTest -public class PlayerIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class PlayerIntegrationTest { /** * Test to see whether player abilities are updated correctly and events * are handled properly when changing gamemode. */ @Test - public void gamemodeTest(Env env) { + void gamemodeTest(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); @@ -74,7 +75,7 @@ public void gamemodeTest(Env env) { } @Test - public void handSwapTest(Env env) { + void handSwapTest(Env env) { ClientSettingsPacket packet = new ClientSettingsPacket("en_us", (byte) 16, ChatMessageType.FULL, true, (byte) 127, Player.MainHand.LEFT, true, true); @@ -112,7 +113,7 @@ private void assertAbilities(Player player, boolean isInvulnerable, boolean isFl } @Test - public void playerJoinPackets(Env env) { + void playerJoinPackets(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); @@ -143,7 +144,7 @@ public void playerJoinPackets(Env env) { * when changing dimensions */ @Test - public void refreshPlayerTest(Env env) { + void refreshPlayerTest(Env env) { final int TEST_PERMISSION_LEVEL = 2; final var testDimension = env.process().dimensionType().register(NamespaceID.from("minestom:test_dimension"), DimensionType.builder().build()); @@ -178,7 +179,7 @@ public void refreshPlayerTest(Env env) { } @Test - public void deathLocationTest(Env env) { + void deathLocationTest(Env env) { String dimensionNamespace = "minestom:test_dimension"; final var testDimension = env.process().dimensionType().register(NamespaceID.from(dimensionNamespace), DimensionType.builder().build()); @@ -195,7 +196,7 @@ public void deathLocationTest(Env env) { } @Test - public void displayNameTest(Env env) { + void displayNameTest(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var tracker = connection.trackIncoming(PlayerInfoUpdatePacket.class); @@ -207,8 +208,8 @@ public void displayNameTest(Env env) { var tracker2 = connection2.trackIncoming(PlayerInfoUpdatePacket.class); connection2.connect(instance, new Pos(0, 42, 0)).join(); - var displayNamePackets = tracker2.collect().stream().filter((packet) -> - packet.actions().stream().anyMatch((act) -> act == PlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME)) + var displayNamePackets = tracker2.collect().stream().filter(packet -> + packet.actions().stream().anyMatch(act -> act == PlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME)) .count(); assertEquals(1, displayNamePackets); @@ -216,19 +217,19 @@ public void displayNameTest(Env env) { player.setDisplayName(Component.text("Other Name!")); - var displayNamePackets2 = tracker3.collect().stream().filter((packet) -> - packet.actions().stream().anyMatch((act) -> act == PlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME)) + var displayNamePackets2 = tracker3.collect().stream().filter(packet -> + packet.actions().stream().anyMatch(act -> act == PlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME)) .count(); assertEquals(1, displayNamePackets2); - var displayNamePackets3 = tracker.collect().stream().filter((packet) -> - packet.actions().stream().anyMatch((act) -> act == PlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME)) + var displayNamePackets3 = tracker.collect().stream().filter(packet -> + packet.actions().stream().anyMatch(act -> act == PlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME)) .count(); assertEquals(2, displayNamePackets3); } @Test - public void setView(Env env) { + void setView(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); Pos startingPlayerPos = new Pos(0, 42, 0); @@ -245,7 +246,7 @@ public void setView(Env env) { } @Test - public void lookAt(Env env) { + void lookAt(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var tracker = connection.trackIncoming(FacePlayerPacket.class); diff --git a/src/test/java/net/minestom/server/entity/player/PlayerMovementIntegrationTest.java b/src/test/java/net/minestom/server/entity/player/PlayerMovementIntegrationTest.java index 713d641483b..747b75ddc65 100644 --- a/src/test/java/net/minestom/server/entity/player/PlayerMovementIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/player/PlayerMovementIntegrationTest.java @@ -1,6 +1,5 @@ package net.minestom.server.entity.player; -import net.minestom.server.MinecraftServer; import net.minestom.server.ServerFlag; import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Vec; @@ -18,10 +17,11 @@ import net.minestom.server.utils.chunk.ChunkUtils; import net.minestom.testing.Collector; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.testing.TestConnection; +import net.minestom.testing.extension.MicrotusExtension; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.time.Duration; import java.time.temporal.ChronoUnit; @@ -31,11 +31,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest -public class PlayerMovementIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class PlayerMovementIntegrationTest { @Test - public void teleportConfirm(Env env) { + void teleportConfirm(Env env) { var instance = env.createFlatInstance(); var p1 = env.createPlayer(instance, new Pos(0, 40, 0)); // No confirmation @@ -47,11 +47,13 @@ public void teleportConfirm(Env env) { p1.addPacketToQueue(new ClientPlayerPositionPacket(new Pos(0.2, 40, 0), true)); p1.interpretPacketQueue(); assertEquals(new Pos(0.2, 40, 0), p1.getPosition()); + p1.remove(); + env.destroyInstance(instance); } // FIXME //@Test - public void singleTickMovementUpdate(Env env) { + void singleTickMovementUpdate(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var p1 = env.createPlayer(instance, new Pos(0, 40, 0)); @@ -68,7 +70,7 @@ public void singleTickMovementUpdate(Env env) { } @Test - public void chunkUpdateDebounceTest(Env env) { + void chunkUpdateDebounceTest(Env env) { final Instance flatInstance = env.createFlatInstance(); final int viewDiameter = ServerFlag.CHUNK_VIEW_DISTANCE * 2 + 1; // Preload all possible chunks to avoid issues due to async loading @@ -119,10 +121,12 @@ public void chunkUpdateDebounceTest(Env env) { player.addPacketToQueue(new ClientPlayerPositionPacket(new Vec(16.5, 40, -16.5), true)); player.interpretPacketQueue(); chunkDataPacketCollector.assertCount(viewDiameter * 2 - 1); + player.remove(); + env.destroyInstance(flatInstance); } @Test - public void testClientViewDistanceSettings(Env env) { + void testClientViewDistanceSettings(Env env) { int viewDistance = 4; final Instance flatInstance = env.createFlatInstance(); var connection = env.createConnection(); @@ -140,6 +144,8 @@ public void testClientViewDistanceSettings(Env env) { player.addPacketToQueue(new ClientPlayerPositionPacket(new Vec(160.5, 40, 160.5), true)); player.interpretPacketQueue(); chunkDataPacketCollector.assertCount(MathUtils.square(viewDistance * 2 + 1)); + player.remove(); + env.destroyInstance(flatInstance); } @Test @@ -153,9 +159,10 @@ public void testSettingsViewDistanceExpansionAndShrink(Env env) { var player = connection.connect(instance, startingPlayerPos).join(); int chunkDifference = ChunkUtils.getChunkCount(endViewDistance) - ChunkUtils.getChunkCount(startingViewDistance); - // Preload chunks, otherwise our first tracker.assertCount call will fail randomly due to chunks being loaded off the main thread - ChunkUtils.forChunksInRange(0, 0, endViewDistance, instance::loadChunk); + Set> chunks = new HashSet<>(); + ChunkUtils.forChunksInRange(0, 0, endViewDistance, (v1, v2) -> chunks.add(instance.loadChunk(v1, v2))); + CompletableFuture.allOf(chunks.toArray(CompletableFuture[]::new)).join(); var tracker = connection.trackIncoming(ChunkDataPacket.class); player.addPacketToQueue(new ClientSettingsPacket("en_US", endViewDistance, ChatMessageType.FULL, false, (byte) 0, Player.MainHand.RIGHT, false, true)); @@ -168,5 +175,7 @@ public void testSettingsViewDistanceExpansionAndShrink(Env env) { int chunkDifference1 = ChunkUtils.getChunkCount(endViewDistance) - ChunkUtils.getChunkCount(finalViewDistance); tracker1.assertCount(chunkDifference1); + player.remove(); + env.destroyInstance(instance); } } diff --git a/src/test/java/net/minestom/server/entity/player/PlayerResourcePackIntegrationTest.java b/src/test/java/net/minestom/server/entity/player/PlayerResourcePackIntegrationTest.java index 44c52f509cf..8fa1d717c31 100644 --- a/src/test/java/net/minestom/server/entity/player/PlayerResourcePackIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/player/PlayerResourcePackIntegrationTest.java @@ -6,8 +6,9 @@ import net.minestom.server.coordinate.Pos; import net.minestom.server.network.packet.client.common.ClientResourcePackStatusPacket; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.net.URI; import java.util.UUID; @@ -17,7 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -@EnvTest +@ExtendWith(MicrotusExtension.class) class PlayerResourcePackIntegrationTest { private static final ResourcePackInfo INFO = ResourcePackInfo.resourcePackInfo(UUID.randomUUID(), URI.create("http://localhost:8080/missing.zip"), "i am not a hash!"); diff --git a/src/test/java/net/minestom/server/entity/player/PlayerRespawnChunkIntegrationTest.java b/src/test/java/net/minestom/server/entity/player/PlayerRespawnChunkIntegrationTest.java index b870c0ec8d6..b9dd7e44f72 100644 --- a/src/test/java/net/minestom/server/entity/player/PlayerRespawnChunkIntegrationTest.java +++ b/src/test/java/net/minestom/server/entity/player/PlayerRespawnChunkIntegrationTest.java @@ -1,6 +1,5 @@ package net.minestom.server.entity.player; -import net.minestom.server.MinecraftServer; import net.minestom.server.ServerFlag; import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.Player; @@ -9,8 +8,9 @@ import net.minestom.server.network.packet.server.play.UnloadChunkPacket; import net.minestom.server.utils.chunk.ChunkUtils; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.HashSet; import java.util.List; @@ -19,12 +19,11 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; - -@EnvTest -public class PlayerRespawnChunkIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class PlayerRespawnChunkIntegrationTest { @Test - public void testChunkUnloadsOnRespawn(Env env) { + void testChunkUnloadsOnRespawn(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); Player player = connection.connect(instance, new Pos(0, 40, 0)).join(); @@ -38,7 +37,7 @@ public void testChunkUnloadsOnRespawn(Env env) { } @Test - public void testChunkReloadCount(Env env) { + void testChunkReloadCount(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); Player player = connection.connect(instance, new Pos(0, 40, 0)).join(); @@ -52,7 +51,7 @@ public void testChunkReloadCount(Env env) { } @Test - public void testPlayerTryRespawn(Env env) { + void testPlayerTryRespawn(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); Player player = connection.connect(instance, new Pos(0, 40, 0)).join(); diff --git a/src/test/java/net/minestom/server/event/EventNodeGraphTest.java b/src/test/java/net/minestom/server/event/EventNodeGraphTest.java index c9f650b9eca..37d80074407 100644 --- a/src/test/java/net/minestom/server/event/EventNodeGraphTest.java +++ b/src/test/java/net/minestom/server/event/EventNodeGraphTest.java @@ -6,16 +6,16 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -public class EventNodeGraphTest { +class EventNodeGraphTest { @Test - public void single() { + void single() { EventNode node = EventNode.all("main"); verifyGraph(node, new EventNodeImpl.Graph("main", "Event", 0, List.of())); } @Test - public void singleChild() { + void singleChild() { EventNode node = EventNode.all("main"); node.addChild(EventNode.all("child")); verifyGraph(node, new EventNodeImpl.Graph("main", "Event", 0, @@ -24,7 +24,7 @@ public void singleChild() { } @Test - public void childrenPriority() { + void childrenPriority() { { EventNode node = EventNode.all("main"); node.addChild(EventNode.all("child1").setPriority(5)); diff --git a/src/test/java/net/minestom/server/event/EventNodeMapTest.java b/src/test/java/net/minestom/server/event/EventNodeMapTest.java index e803aa3e531..28c019a1c67 100644 --- a/src/test/java/net/minestom/server/event/EventNodeMapTest.java +++ b/src/test/java/net/minestom/server/event/EventNodeMapTest.java @@ -13,10 +13,10 @@ import static net.minestom.testing.TestUtils.waitUntilCleared; import static org.junit.jupiter.api.Assertions.*; -public class EventNodeMapTest { +class EventNodeMapTest { @Test - public void uniqueMapping() { + void uniqueMapping() { var item = ItemStack.of(Material.DIAMOND); var node = EventNode.all("main"); var itemNode1 = node.map(item, EventFilter.ITEM); @@ -31,7 +31,7 @@ public void uniqueMapping() { } @Test - public void lazyRegistration() { + void lazyRegistration() { var item = ItemStack.of(Material.DIAMOND); var node = (EventNodeImpl) EventNode.all("main"); var itemNode = node.map(item, EventFilter.ITEM); @@ -42,7 +42,7 @@ public void lazyRegistration() { } @Test - public void secondMap() { + void secondMap() { var item = ItemStack.of(Material.DIAMOND); var node = (EventNodeImpl) EventNode.all("main"); var itemNode = node.map(item, EventFilter.ITEM); @@ -51,7 +51,7 @@ public void secondMap() { } @Test - public void map() { + void map() { var item = ItemStack.of(Material.DIAMOND); var node = EventNode.all("main"); @@ -76,7 +76,7 @@ public void map() { } @Test - public void entityLocal() { + void entityLocal() { var process = MinecraftServer.updateProcess(); var node = process.eventHandler(); var entity = new Entity(EntityType.ZOMBIE); @@ -102,7 +102,7 @@ public void entityLocal() { } @Test - public void ownerGC() { + void ownerGC() { // Ensure that the mapped object gets GCed var item = ItemStack.of(Material.DIAMOND); var node = EventNode.all("main"); diff --git a/src/test/java/net/minestom/server/event/EventNodeQueryTest.java b/src/test/java/net/minestom/server/event/EventNodeQueryTest.java index 9e035b0f764..fd481a2b8ff 100644 --- a/src/test/java/net/minestom/server/event/EventNodeQueryTest.java +++ b/src/test/java/net/minestom/server/event/EventNodeQueryTest.java @@ -9,10 +9,10 @@ import static net.minestom.testing.TestUtils.assertEqualsIgnoreOrder; import static org.junit.jupiter.api.Assertions.assertEquals; -public class EventNodeQueryTest { +class EventNodeQueryTest { @Test - public void find() { + void find() { var node = EventNode.all("main"); assertEquals(List.of(), node.findChildren("test")); @@ -33,7 +33,7 @@ public void find() { } @Test - public void findType() { + void findType() { var node = EventNode.all("main"); assertEquals(List.of(), node.findChildren("test", Event.class)); @@ -58,7 +58,7 @@ public void findType() { } @Test - public void replace() { + void replace() { var node = EventNode.all("main"); var child1 = EventNode.all("test"); diff --git a/src/test/java/net/minestom/server/event/EventNodeTest.java b/src/test/java/net/minestom/server/event/EventNodeTest.java index 114033a08a7..b1e46999c54 100644 --- a/src/test/java/net/minestom/server/event/EventNodeTest.java +++ b/src/test/java/net/minestom/server/event/EventNodeTest.java @@ -17,7 +17,7 @@ import static net.minestom.testing.TestUtils.waitUntilCleared; import static org.junit.jupiter.api.Assertions.*; -public class EventNodeTest { +class EventNodeTest { static class EventTest implements Event { } @@ -57,7 +57,7 @@ record EntityTestEvent(Entity entity) implements EntityEvent { } @Test - public void testCall() { + void testCall() { var node = EventNode.all("main"); AtomicBoolean result = new AtomicBoolean(false); var listener = EventListener.of(EventTest.class, eventTest -> result.set(true)); @@ -74,7 +74,7 @@ public void testCall() { } @Test - public void testHandle() { + void testHandle() { var node = EventNode.all("main"); var handle = node.getHandle(EventTest.class); assertSame(handle, node.getHandle(EventTest.class)); @@ -84,7 +84,7 @@ public void testHandle() { } @Test - public void testCancellable() { + void testCancellable() { var node = EventNode.all("main"); AtomicBoolean result = new AtomicBoolean(false); var listener = EventListener.builder(CancellableTest.class) @@ -103,7 +103,7 @@ public void testCancellable() { } @Test - public void recursiveSub() { + void recursiveSub() { var node = EventNode.all("main"); AtomicBoolean result1 = new AtomicBoolean(false); AtomicBoolean result2 = new AtomicBoolean(false); @@ -144,7 +144,7 @@ public void recursiveSub() { //} @Test - public void testChildren() { + void testChildren() { var node = EventNode.all("main"); AtomicInteger result = new AtomicInteger(0); var child1 = EventNode.all("child1").setPriority(1) @@ -159,14 +159,14 @@ public void testChildren() { }); node.addChild(child1); node.addChild(child2); - assertEquals(node.getChildren().size(), 2, "The node should have 2 children"); + assertEquals(2, node.getChildren().size(), "The node should have 2 children"); node.call(new EventTest()); assertEquals(2, result.get(), "The event should be called after the call"); // Test removal result.set(0); node.removeChild(child2); - assertEquals(node.getChildren().size(), 1, "The node should have 1 child"); + assertEquals(1, node.getChildren().size() , "The node should have 1 child"); node.call(new EventTest()); assertEquals(1, result.get(), "child2 should has been removed"); @@ -178,7 +178,7 @@ public void testChildren() { } @Test - public void testFiltering() { + void testFiltering() { AtomicBoolean result = new AtomicBoolean(false); AtomicBoolean childResult = new AtomicBoolean(false); @@ -202,7 +202,7 @@ public void testFiltering() { } @Test - public void testBinding() { + void testBinding() { var node = EventNode.all("main"); AtomicBoolean result = new AtomicBoolean(false); @@ -224,7 +224,7 @@ public void testBinding() { } @Test - public void nodeEmptyGC() { + void nodeEmptyGC() { var node = EventNode.all("main"); var ref = new WeakReference<>(node); @@ -234,7 +234,7 @@ public void nodeEmptyGC() { } @Test - public void nodeGC() { + void nodeGC() { var node = EventNode.all("main"); var ref = new WeakReference<>(node); node.addListener(EventTest.class, event -> { @@ -261,7 +261,7 @@ public void nodeGC() { // } @Test - public void nodeMapGC() { + void nodeMapGC() { var node = EventNode.all("main"); var handler = ItemStack.AIR; diff --git a/src/test/java/net/minestom/server/instance/BlockClientNbtTest.java b/src/test/java/net/minestom/server/instance/BlockClientNbtTest.java index 712780344b5..da788786704 100644 --- a/src/test/java/net/minestom/server/instance/BlockClientNbtTest.java +++ b/src/test/java/net/minestom/server/instance/BlockClientNbtTest.java @@ -15,10 +15,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -public class BlockClientNbtTest { +class BlockClientNbtTest { @Test - public void basic() { + void basic() { assertNull(BlockUtils.extractClientNbt(Block.STONE)); assertNull(BlockUtils.extractClientNbt(Block.GRASS_BLOCK)); assertEquals(CompoundBinaryTag.empty(), BlockUtils.extractClientNbt(Block.CHEST)); @@ -28,7 +28,7 @@ public void basic() { } @Test - public void handler() { + void handler() { var handler = new BlockHandler() { @Override public @NotNull Collection> getBlockEntityTags() { diff --git a/src/test/java/net/minestom/server/instance/BlockLightMergeIntegrationTest.java b/src/test/java/net/minestom/server/instance/BlockLightMergeIntegrationTest.java index 522beecc6c2..1f14a5f22f9 100644 --- a/src/test/java/net/minestom/server/instance/BlockLightMergeIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/BlockLightMergeIntegrationTest.java @@ -3,8 +3,9 @@ import net.minestom.server.coordinate.Vec; import net.minestom.server.instance.block.Block; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.ArrayList; import java.util.HashMap; @@ -15,10 +16,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; -@EnvTest +@ExtendWith(MicrotusExtension.class) public class BlockLightMergeIntegrationTest { @Test - public void testPropagationAir(Env env) { + void testPropagationAir(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); for (int x = -3; x <= 3; x++) { @@ -39,7 +40,7 @@ public void testPropagationAir(Env env) { } @Test - public void testTorch(Env env) { + void testTorch(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); instance.setGenerator(unit -> { @@ -65,7 +66,7 @@ public void testTorch(Env env) { } @Test - public void testTorch2(Env env) { + void testTorch2(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); @@ -91,7 +92,7 @@ public void testTorch2(Env env) { } @Test - public void testPropagationAir2(Env env) { + void testPropagationAir2(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); for (int x = -3; x <= 3; x++) { @@ -116,7 +117,7 @@ public void testPropagationAir2(Env env) { } @Test - public void testPropagationAirRemoval(Env env) { + void testPropagationAirRemoval(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); for (int x = -3; x <= 3; x++) { @@ -145,7 +146,7 @@ public void testPropagationAirRemoval(Env env) { } @Test - public void testBorderOcclusion(Env env) { + void testBorderOcclusion(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); for (int x = -3; x <= 3; x++) { @@ -178,7 +179,7 @@ public void testBorderOcclusion(Env env) { } @Test - public void testBorderOcclusion2(Env env) { + void testBorderOcclusion2(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); for (int x = -3; x <= 3; x++) { @@ -210,7 +211,7 @@ public void testBorderOcclusion2(Env env) { } @Test - public void testBorderOcclusion3(Env env) { + void testBorderOcclusion3(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); for (int x = -3; x <= 3; x++) { @@ -241,7 +242,7 @@ public void testBorderOcclusion3(Env env) { } @Test - public void testBorderCrossing(Env env) { + void testBorderCrossing(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); for (int x = -3; x <= 3; x++) { @@ -293,7 +294,7 @@ public void testBorderCrossing(Env env) { } @Test - public void testBorderOcclusionRemoval(Env env) { + void testBorderOcclusionRemoval(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); for (int x = -3; x <= 3; x++) { @@ -332,7 +333,7 @@ public void testBorderOcclusionRemoval(Env env) { } @Test - public void chunkIntersection(Env env) { + void chunkIntersection(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); for (int x = 4; x <= 7; x++) { @@ -353,7 +354,7 @@ public void chunkIntersection(Env env) { } @Test - public void lightLookupTest(Env env) { + void lightLookupTest(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); for (int x = 4; x <= 7; x++) { @@ -378,7 +379,7 @@ public void lightLookupTest(Env env) { } @Test - public void lightLookupTestCrossBorder(Env env) { + void lightLookupTestCrossBorder(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); for (int x = 4; x <= 7; x++) { @@ -397,7 +398,7 @@ public void lightLookupTestCrossBorder(Env env) { } @Test - public void skylight(Env env) { + void skylight(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); for (int x = 4; x <= 7; x++) { @@ -416,7 +417,7 @@ public void skylight(Env env) { @Test - public void skylightShortGrass(Env env) { + void skylightShortGrass(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); for (int x = 4; x <= 7; x++) { @@ -434,7 +435,7 @@ public void skylightShortGrass(Env env) { } @Test - public void skylightContained(Env env) { + void skylightContained(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); for (int x = 4; x <= 7; x++) { @@ -460,7 +461,7 @@ public void skylightContained(Env env) { } @Test - public void testDiagonalRemoval(Env env) { + void testDiagonalRemoval(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); for (int x = -3; x <= 3; x++) { @@ -494,7 +495,7 @@ public void testDiagonalRemoval(Env env) { } @Test - public void testDiagonalRemoval2(Env env) { + void testDiagonalRemoval2(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); for (int x = -3; x <= 3; x++) { @@ -520,7 +521,7 @@ public void testDiagonalRemoval2(Env env) { } @Test - public void testDouble(Env env) { + void testDouble(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); for (int x = -3; x <= 3; x++) { @@ -554,7 +555,7 @@ public void testDouble(Env env) { } @Test - public void testBlockRemoval(Env env) { + void testBlockRemoval(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); for (int x = -3; x <= 3; x++) { diff --git a/src/test/java/net/minestom/server/instance/BlockPlaceIntegrationTest.java b/src/test/java/net/minestom/server/instance/BlockPlaceIntegrationTest.java index f353e4aa823..447709ac0be 100644 --- a/src/test/java/net/minestom/server/instance/BlockPlaceIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/BlockPlaceIntegrationTest.java @@ -9,14 +9,15 @@ import net.minestom.server.listener.BlockPlacementListener; import net.minestom.server.network.packet.client.play.ClientPlayerBlockPlacementPacket; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest -public class BlockPlaceIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class BlockPlaceIntegrationTest { @Test void testPlacementOutOfLimit(Env env) { diff --git a/src/test/java/net/minestom/server/instance/BlockPropertiesTest.java b/src/test/java/net/minestom/server/instance/BlockPropertiesTest.java index 3fbe44370df..ca0bf1cf03e 100644 --- a/src/test/java/net/minestom/server/instance/BlockPropertiesTest.java +++ b/src/test/java/net/minestom/server/instance/BlockPropertiesTest.java @@ -7,16 +7,16 @@ import static net.minestom.server.utils.block.BlockUtils.parseProperties; import static org.junit.jupiter.api.Assertions.assertEquals; -public class BlockPropertiesTest { +class BlockPropertiesTest { @Test - public void empty() { + void empty() { assertEquals(Map.of(), parseProperties("[]")); assertEquals(Map.of(), parseProperties("")); } @Test - public void noBrackets() { + void noBrackets() { assertEquals(Map.of(), parseProperties("random test without brackets")); assertEquals(Map.of(), parseProperties("[")); assertEquals(Map.of(), parseProperties("[end")); @@ -27,28 +27,28 @@ public void noBrackets() { } @Test - public void spaces() { + void spaces() { assertEquals(Map.of(), parseProperties("[ ]")); } @Test - public void comma() { + void comma() { assertEquals(Map.of(), parseProperties("[ , , ,,,, ]")); } @Test - public void single() { + void single() { assertEquals(Map.of("facing", "east"), parseProperties("[facing=east]")); } @Test - public void doubleSpace() { + void doubleSpace() { assertEquals(Map.of("facing", "east", "key", "value"), parseProperties("[facing=east,key=value ]")); assertEquals(Map.of("facing", "east", "key", "value"), parseProperties("[ facing = east, key= value ]")); } @Test - public void allLengths() { + void allLengths() { // Verify all length variations for (int i = 0; i < 13; i++) { StringBuilder properties = new StringBuilder("["); @@ -67,7 +67,7 @@ public void allLengths() { } @Test - public void corrupted() { + void corrupted() { final int size = 12; StringBuilder properties = new StringBuilder("["); for (int j = 0; j < size; j++) { diff --git a/src/test/java/net/minestom/server/instance/ChunkHeightmapIntegrationTest.java b/src/test/java/net/minestom/server/instance/ChunkHeightmapIntegrationTest.java index 269492302ff..53ee8c771f5 100644 --- a/src/test/java/net/minestom/server/instance/ChunkHeightmapIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/ChunkHeightmapIntegrationTest.java @@ -2,15 +2,16 @@ import net.minestom.server.instance.block.Block; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest -public class ChunkHeightmapIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class ChunkHeightmapIntegrationTest { @Test - public void testChunkHeightmap(Env env) { + void testChunkHeightmap(Env env) { var instance = env.createFlatInstance(); instance.loadChunk(0, 0).join(); var chunk = instance.getChunk(0, 0); @@ -20,7 +21,7 @@ public void testChunkHeightmap(Env env) { } @Test - public void heightMapPlaceTest(Env env) { + void heightMapPlaceTest(Env env) { var instance = env.createFlatInstance(); instance.loadChunk(0, 0).join(); var chunk = instance.getChunk(0, 0); @@ -39,7 +40,7 @@ public void heightMapPlaceTest(Env env) { } @Test - public void heightMapRemoveTest(Env env) { + void heightMapRemoveTest(Env env) { var instance = env.createFlatInstance(); instance.loadChunk(0, 0).join(); var chunk = instance.getChunk(0, 0); diff --git a/src/test/java/net/minestom/server/instance/ChunkViewerIntegrationTest.java b/src/test/java/net/minestom/server/instance/ChunkViewerIntegrationTest.java index 429a26a0a49..a121d30b523 100644 --- a/src/test/java/net/minestom/server/instance/ChunkViewerIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/ChunkViewerIntegrationTest.java @@ -5,19 +5,20 @@ import net.minestom.server.network.packet.server.play.ChunkDataPacket; import net.minestom.server.utils.chunk.ChunkUtils; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest -public class ChunkViewerIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class ChunkViewerIntegrationTest { @ParameterizedTest @ValueSource(booleans = {false, true}) - public void basicJoin(boolean sharedInstance, Env env) { + void basicJoin(boolean sharedInstance, Env env) { Instance instance = env.createFlatInstance(); if (sharedInstance) { // Chunks get their viewers from the instance @@ -36,7 +37,7 @@ public void basicJoin(boolean sharedInstance, Env env) { } @Test - public void renderDistance(Env env) { + void renderDistance(Env env) { final int viewRadius = MinecraftServer.getChunkViewDistance(); final int count = ChunkUtils.getChunkCount(viewRadius); var instance = env.createFlatInstance(); diff --git a/src/test/java/net/minestom/server/instance/EntityTrackerIntegrationTest.java b/src/test/java/net/minestom/server/instance/EntityTrackerIntegrationTest.java index bc306382d49..c2b9c8658fc 100644 --- a/src/test/java/net/minestom/server/instance/EntityTrackerIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/EntityTrackerIntegrationTest.java @@ -1,30 +1,26 @@ package net.minestom.server.instance; -import net.minestom.server.MinecraftServer; import net.minestom.server.ServerFlag; import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.Entity; import net.minestom.server.entity.EntityType; import net.minestom.server.entity.Player; -import net.minestom.server.network.packet.server.SendablePacket; -import net.minestom.server.network.player.PlayerConnection; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; -import java.net.SocketAddress; -import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertSame; -@EnvTest -public class EntityTrackerIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class EntityTrackerIntegrationTest { @Test - public void maxDistance(Env env) { + void maxDistance(Env env) { final Instance instance = env.createFlatInstance(); final Pos spawnPos = new Pos(0, 41, 0); final int viewDistanceInChunks = ServerFlag.ENTITY_VIEW_DISTANCE; @@ -53,7 +49,7 @@ public void updateOldViewer(@NotNull Player player) { } @Test - public void cornerInstanceSwap(Env env) { + void cornerInstanceSwap(Env env) { final Instance instance = env.createFlatInstance(); final Instance anotherInstance = env.createFlatInstance(); final Pos spawnPos = new Pos(0, 41, 0); @@ -83,7 +79,7 @@ public void updateOldViewer(@NotNull Player player) { } @Test - public void viewable(Env env) { + void viewable(Env env) { final Instance instance = env.createFlatInstance(); final Pos spawnPos = new Pos(0, 41, 0); var viewable = instance.getEntityTracker().viewable(spawnPos.chunkX(), spawnPos.chunkZ()); @@ -101,7 +97,7 @@ public void viewable(Env env) { } @Test - public void viewableShared(Env env) { + void viewableShared(Env env) { final InstanceContainer instance = (InstanceContainer) env.createFlatInstance(); var shared = env.process().instance().createSharedInstance(instance); var sharedList = instance.getSharedInstances(); diff --git a/src/test/java/net/minestom/server/instance/EntityTrackerTest.java b/src/test/java/net/minestom/server/instance/EntityTrackerTest.java index 45508ef388c..fa1ed75e21b 100644 --- a/src/test/java/net/minestom/server/instance/EntityTrackerTest.java +++ b/src/test/java/net/minestom/server/instance/EntityTrackerTest.java @@ -11,9 +11,9 @@ import static org.junit.jupiter.api.Assertions.*; -public class EntityTrackerTest { +class EntityTrackerTest { @Test - public void register() { + void register() { var ent1 = new Entity(EntityType.ZOMBIE); var updater = new EntityTracker.Update<>() { @Override @@ -40,7 +40,7 @@ public void remove(@NotNull Entity entity) { } @Test - public void move() { + void move() { var ent1 = new Entity(EntityType.ZOMBIE); var updater = new EntityTracker.Update<>() { @Override @@ -65,7 +65,7 @@ public void remove(@NotNull Entity entity) { } @Test - public void tracking() { + void tracking() { var ent1 = new Entity(EntityType.ZOMBIE); var ent2 = new Entity(EntityType.ZOMBIE); @@ -124,7 +124,7 @@ public void remove(@NotNull Entity entity) { } @Test - public void nearby() { + void nearby() { var ent1 = new Entity(EntityType.ZOMBIE); var ent2 = new Entity(EntityType.ZOMBIE); var ent3 = new Entity(EntityType.ZOMBIE); @@ -177,7 +177,7 @@ public void remove(@NotNull Entity entity) { } @Test - public void nearbySingleChunk() { + void nearbySingleChunk() { var ent1 = new Entity(EntityType.ZOMBIE); var ent2 = new Entity(EntityType.ZOMBIE); var ent3 = new Entity(EntityType.ZOMBIE); @@ -217,7 +217,7 @@ public void remove(@NotNull Entity entity) { } @Test - public void collectionView() { + void collectionView() { var ent1 = new Entity(EntityType.ZOMBIE); var updater = new EntityTracker.Update<>() { @Override diff --git a/src/test/java/net/minestom/server/instance/ExplosionIntegrationTest.java b/src/test/java/net/minestom/server/instance/ExplosionIntegrationTest.java new file mode 100644 index 00000000000..7e76f0b9abd --- /dev/null +++ b/src/test/java/net/minestom/server/instance/ExplosionIntegrationTest.java @@ -0,0 +1,62 @@ +package net.minestom.server.instance; + +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.minestom.server.coordinate.Point; +import net.minestom.server.coordinate.Pos; +import net.minestom.server.network.packet.server.play.ExplosionPacket; +import net.minestom.testing.Env; +import net.minestom.testing.extension.MicrotusExtension; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import java.util.List; + + +@ExtendWith(MicrotusExtension.class) +class ExplosionIntegrationTest { + + // Checks that only nearby players actually receive the packet from the server + @Test + void sendToNearbyPlayers(Env env) { + var instance = env.createFlatInstance(); + instance.setExplosionSupplier(new TestExplosionSupplierImpl()); + + var connection1 = env.createConnection(); + var connection2 = env.createConnection(); + var connection3 = env.createConnection(); + + // Assumes that the default ServerFlag.EXPLOSION_SEND_DISTANCE is set to 100 blocks + var player1 = connection1.connect(instance, new Pos(0, 41, 0)); + var player2 = connection2.connect(instance, new Pos(50, 41, 0)); + var player3 = connection3.connect(instance, new Pos(0, 41, 110)); + + var packetTracker1 = connection1.trackIncoming(ExplosionPacket.class); + var packetTracker2 = connection2.trackIncoming(ExplosionPacket.class); + var packetTracker3 = connection3.trackIncoming(ExplosionPacket.class); + + instance.explode(0, 41, 0, 1); + packetTracker1.assertSingle(); + packetTracker2.assertSingle(); + packetTracker3.assertEmpty(); + env.destroyInstance(instance, true); + } + + + class TestExplosionSupplierImpl implements ExplosionSupplier { + @Override + public Explosion createExplosion(float centerX, float centerY, float centerZ, float strength, CompoundBinaryTag additionalData) { + return new TestExplosionImpl(centerX, centerY, centerZ, strength); + } + + class TestExplosionImpl extends Explosion { + + TestExplosionImpl(float centerX, float centerY, float centerZ, float strength) { + super(centerX, centerY, centerZ, strength); + } + @Override + protected List prepare(Instance instance) { + return List.of(new Pos(getCenterX(), getCenterY(), getCenterZ())); + } + } + } + +} diff --git a/src/test/java/net/minestom/server/instance/GeneratorForkIntegrationTest.java b/src/test/java/net/minestom/server/instance/GeneratorForkIntegrationTest.java index 13d48448a3b..27632fe47d7 100644 --- a/src/test/java/net/minestom/server/instance/GeneratorForkIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/GeneratorForkIntegrationTest.java @@ -5,16 +5,17 @@ import net.minestom.server.instance.generator.GenerationUnit; import net.minestom.server.world.biome.Biome; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.*; -@EnvTest -public class GeneratorForkIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class GeneratorForkIntegrationTest { @Test - public void local(Env env) { + void local(Env env) { var manager = env.process().instance(); var instance = manager.createInstanceContainer(); var block = Block.STONE; @@ -29,7 +30,7 @@ public void local(Env env) { } @Test - public void size(Env env) { + void size(Env env) { var manager = env.process().instance(); var instance = manager.createInstanceContainer(); // Set the Generator @@ -46,7 +47,7 @@ public void size(Env env) { } @Test - public void signal(Env env) { + void signal(Env env) { var manager = env.process().instance(); var instance = manager.createInstanceContainer(); var block = Block.STONE; @@ -65,7 +66,7 @@ public void signal(Env env) { } @Test - public void air(Env env) { + void air(Env env) { var manager = env.process().instance(); var instance = manager.createInstanceContainer(); instance.setGenerator(unit -> { @@ -79,7 +80,7 @@ public void air(Env env) { } @Test - public void fillHeight(Env env) { + void fillHeight(Env env) { var manager = env.process().instance(); var instance = manager.createInstanceContainer(); instance.setGenerator(unit -> { @@ -95,7 +96,7 @@ public void fillHeight(Env env) { } @Test - public void biome(Env env) { + void biome(Env env) { var manager = env.process().instance(); var instance = manager.createInstanceContainer(); diff --git a/src/test/java/net/minestom/server/instance/GeneratorIntegrationTest.java b/src/test/java/net/minestom/server/instance/GeneratorIntegrationTest.java index 280fd487106..3aa407ca42b 100644 --- a/src/test/java/net/minestom/server/instance/GeneratorIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/GeneratorIntegrationTest.java @@ -3,8 +3,9 @@ import net.kyori.adventure.nbt.CompoundBinaryTag; import net.minestom.server.instance.block.Block; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -13,12 +14,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertSame; -@EnvTest -public class GeneratorIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class GeneratorIntegrationTest { @ParameterizedTest @ValueSource(booleans = {false, true}) - public void loader(boolean data, Env env) { + void loader(boolean data, Env env) { var manager = env.process().instance(); var block = data ? Block.STONE.withNbt(CompoundBinaryTag.builder().putString("key", "value").build()) : Block.STONE; var instance = manager.createInstanceContainer(); @@ -31,7 +32,7 @@ public void loader(boolean data, Env env) { } @Test - public void exceptionCatch(Env env) { + void exceptionCatch(Env env) { var manager = env.process().instance(); var instance = manager.createInstanceContainer(); @@ -46,10 +47,11 @@ public void exceptionCatch(Env env) { instance.loadChunk(0, 0).join(); assertSame(exception, ref.get()); + ref.set(null); } @Test - public void fillHeightNegative(Env env) { + void fillHeightNegative(Env env) { var manager = env.process().instance(); var instance = manager.createInstanceContainer(); instance.setGenerator(unit -> unit.modifier().fillHeight(-64, -60, Block.STONE)); @@ -63,7 +65,7 @@ public void fillHeightNegative(Env env) { } @Test - public void fillHeightSingleSectionFull(Env env) { + void fillHeightSingleSectionFull(Env env) { var manager = env.process().instance(); var instance = manager.createInstanceContainer(); instance.setGenerator(unit -> unit.modifier().fillHeight(0, 16, Block.GRASS_BLOCK)); @@ -74,7 +76,7 @@ public void fillHeightSingleSectionFull(Env env) { } @Test - public void fillHeightSingleSection(Env env) { + void fillHeightSingleSection(Env env) { var manager = env.process().instance(); var instance = manager.createInstanceContainer(); instance.setGenerator(unit -> unit.modifier().fillHeight(4, 5, Block.GRASS_BLOCK)); @@ -85,7 +87,7 @@ public void fillHeightSingleSection(Env env) { } @Test - public void fillHeightOverride(Env env) { + void fillHeightOverride(Env env) { var manager = env.process().instance(); var instance = manager.createInstanceContainer(); instance.setGenerator(unit -> { diff --git a/src/test/java/net/minestom/server/instance/InstanceBlockIntegrationTest.java b/src/test/java/net/minestom/server/instance/InstanceBlockIntegrationTest.java index 7a01e703f56..ae7dad49c2f 100644 --- a/src/test/java/net/minestom/server/instance/InstanceBlockIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/InstanceBlockIntegrationTest.java @@ -6,21 +6,22 @@ import net.minestom.server.instance.block.rule.BlockPlacementRule; import net.minestom.server.tag.Tag; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.concurrent.atomic.AtomicReference; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -@EnvTest -public class InstanceBlockIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class InstanceBlockIntegrationTest { @Test - public void basic(Env env) { + void basic(Env env) { var instance = env.createFlatInstance(); assertThrows(NullPointerException.class, () -> instance.getBlock(0, 0, 0), "No exception throw when getting a block in an unloaded chunk"); @@ -41,7 +42,7 @@ public void basic(Env env) { } @Test - public void unloadCache(Env env) { + void unloadCache(Env env) { var instance = env.createFlatInstance(); instance.loadChunk(0, 0).join(); @@ -57,7 +58,7 @@ public void unloadCache(Env env) { } @Test - public void blockNbt(Env env) { + void blockNbt(Env env) { var instance = env.createFlatInstance(); assertThrows(NullPointerException.class, () -> instance.getBlock(0, 0, 0), "No exception throw when getting a block in an unloaded chunk"); @@ -82,7 +83,6 @@ public void blockNbt(Env env) { @Test public void handlerPresentInPlacementRuleUpdate(Env env) { - AtomicReference currentBlock = new AtomicReference<>(); env.process().block().registerHandler(SuspiciousGravelBlockHandler.INSTANCE.getNamespaceId(), () -> SuspiciousGravelBlockHandler.INSTANCE); env.process().block().registerBlockPlacementRule(new BlockPlacementRule(Block.SUSPICIOUS_GRAVEL) { @@ -104,5 +104,6 @@ public void handlerPresentInPlacementRuleUpdate(Env env) { instance.setBlock(1, 50, 0, theBlock); assertEquals(theBlock, currentBlock.get()); + currentBlock.set(null); } } diff --git a/src/test/java/net/minestom/server/instance/InstanceBlockPacketIntegrationTest.java b/src/test/java/net/minestom/server/instance/InstanceBlockPacketIntegrationTest.java index 1c73062d6af..971de66af5d 100644 --- a/src/test/java/net/minestom/server/instance/InstanceBlockPacketIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/InstanceBlockPacketIntegrationTest.java @@ -11,20 +11,21 @@ import net.minestom.server.tag.Tag; import net.minestom.server.utils.NamespaceID; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.Collection; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest -public class InstanceBlockPacketIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class InstanceBlockPacketIntegrationTest { @Test - public void replaceAir(Env env) { + void replaceAir(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); connection.connect(instance, new Pos(0, 40, 0)).join(); @@ -44,7 +45,7 @@ public void replaceAir(Env env) { } @Test - public void placeBlockEntity(Env env) { + void placeBlockEntity(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); connection.connect(instance, new Pos(0, 40, 0)).join(); diff --git a/src/test/java/net/minestom/server/instance/InstanceContainerTest.java b/src/test/java/net/minestom/server/instance/InstanceContainerTest.java index 5c2548b7f18..d1c31d51c04 100644 --- a/src/test/java/net/minestom/server/instance/InstanceContainerTest.java +++ b/src/test/java/net/minestom/server/instance/InstanceContainerTest.java @@ -8,13 +8,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -public class InstanceContainerTest { +class InstanceContainerTest { static { } @Test - public void copyPreservesTag() { + void copyPreservesTag() { var tag = Tag.String("test"); var instance = new InstanceContainer(UUID.randomUUID(), DimensionType.OVERWORLD); instance.setTag(tag, "123"); diff --git a/src/test/java/net/minestom/server/instance/InstanceEventsIntegrationTest.java b/src/test/java/net/minestom/server/instance/InstanceEventsIntegrationTest.java index 8f2404e5a4c..44e35fde6d2 100644 --- a/src/test/java/net/minestom/server/instance/InstanceEventsIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/InstanceEventsIntegrationTest.java @@ -3,13 +3,14 @@ import net.minestom.server.event.instance.InstanceRegisterEvent; import net.minestom.server.event.instance.InstanceUnregisterEvent; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; -@EnvTest -public class InstanceEventsIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class InstanceEventsIntegrationTest { @Test - public void registerAndUnregisterInstance(Env env) { + void registerAndUnregisterInstance(Env env) { var registerListener = env.listen(InstanceRegisterEvent.class); var unregisterListener = env.listen(InstanceUnregisterEvent.class); diff --git a/src/test/java/net/minestom/server/instance/InstancePlayerIntegrationTest.java b/src/test/java/net/minestom/server/instance/InstancePlayerIntegrationTest.java new file mode 100644 index 00000000000..f09da59497a --- /dev/null +++ b/src/test/java/net/minestom/server/instance/InstancePlayerIntegrationTest.java @@ -0,0 +1,48 @@ +package net.minestom.server.instance; + +import net.minestom.server.coordinate.Pos; +import net.minestom.server.entity.Player; +import net.minestom.testing.Env; +import net.minestom.testing.extension.MicrotusExtension; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import static org.junit.jupiter.api.Assertions.*; + +@ExtendWith(MicrotusExtension.class) +public class InstancePlayerIntegrationTest { + + @Test + void testInstanceDestroyWithPlayersInside(Env env) { + Instance instance = env.createFlatInstance(); + for (int i = 0; i < 3; i++) { + // Default position is Pos.ZERO + env.createPlayer(instance); + } + + assertFalse(instance.getPlayers().isEmpty()); + for (Player player : instance.getPlayers()) { + assertEquals(Pos.ZERO, player.getPosition()); + } + assertDoesNotThrow(() -> env.destroyInstance(instance, true)); + assertTrue(instance.getPlayers().isEmpty()); + } + + @Test + void testInstanceDestroyWithExceptionThrow(Env env) { + Instance instance = env.createFlatInstance(); + for (int i = 0; i < 3; i++) { + // Default position is Pos.ZERO + env.createPlayer(instance); + } + assertFalse(instance.getPlayers().isEmpty()); + assertThrows( + IllegalStateException.class, + () -> env.destroyInstance(instance), + "You cannot unregister an instance with players inside." + ); + assertFalse(instance.getPlayers().isEmpty()); + env.destroyInstance(instance, true); + assertTrue(instance.getPlayers().isEmpty()); + } +} diff --git a/src/test/java/net/minestom/server/instance/InstanceUnregisterIntegrationTest.java b/src/test/java/net/minestom/server/instance/InstanceUnregisterIntegrationTest.java index ed7173f89fe..7d086e6e3a5 100644 --- a/src/test/java/net/minestom/server/instance/InstanceUnregisterIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/InstanceUnregisterIntegrationTest.java @@ -6,19 +6,20 @@ import net.minestom.server.event.player.PlayerTickEvent; import net.minestom.server.world.DimensionType; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.lang.ref.WeakReference; import java.util.UUID; import static net.minestom.testing.TestUtils.waitUntilCleared; -@EnvTest -public class InstanceUnregisterIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class InstanceUnregisterIntegrationTest { @Test - public void sharedInstance(Env env) { + void sharedInstance(Env env) { // Ensure that unregistering a shared instance does not unload the container chunks var instanceManager = env.process().instance(); var instance = instanceManager.createInstanceContainer(); @@ -40,7 +41,7 @@ public void sharedInstance(Env env) { } @Test - public void instanceGC(Env env) { + void instanceGC(Env env) { var instance = env.createFlatInstance(); var ref = new WeakReference<>(instance); env.process().instance().unregisterInstance(instance); @@ -51,7 +52,7 @@ public void instanceGC(Env env) { } @Test - public void instanceNodeGC(Env env) { + void instanceNodeGC(Env env) { final class Game { final Instance instance; @@ -70,7 +71,7 @@ final class Game { } @Test - public void chunkGC(Env env) { + void chunkGC(Env env) { // Ensure that unregistering an instance does release its chunks var instance = env.createFlatInstance(); var chunk = instance.loadChunk(0, 0).join(); @@ -85,7 +86,7 @@ public void chunkGC(Env env) { } @Test - public void testGCWithEventsLambda(Env env) { + void testGCWithEventsLambda(Env env) { var ref = new WeakReference<>(new InstanceContainer(UUID.randomUUID(), DimensionType.OVERWORLD)); env.process().instance().registerInstance(ref.get()); diff --git a/src/test/java/net/minestom/server/instance/InstanceWorldPositionIntegrationTest.java b/src/test/java/net/minestom/server/instance/InstanceWorldPositionIntegrationTest.java new file mode 100644 index 00000000000..0db1fab2c60 --- /dev/null +++ b/src/test/java/net/minestom/server/instance/InstanceWorldPositionIntegrationTest.java @@ -0,0 +1,49 @@ +package net.minestom.server.instance; + +import net.minestom.server.coordinate.Pos; +import net.minestom.server.event.instance.InstanceWorldPositionChangeEvent; +import net.minestom.testing.Env; +import net.minestom.testing.extension.MicrotusExtension; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import static org.junit.jupiter.api.Assertions.*; + +//Microtus start - integrate world spawn position +@ExtendWith(MicrotusExtension.class) +class InstanceWorldPositionIntegrationTest { + + @Test + void testInstanceWorldPositionUpdate(@NotNull Env env) { + var instance = env.createFlatInstance(); + assertEquals(Pos.ZERO, instance.getWorldSpawnPosition()); + instance.setWorldSpawnPosition(new Pos(1, 2, 3)); + assertNotEquals(Pos.ZERO, instance.getWorldSpawnPosition()); + Pos newSpawnPosition = new Pos(100, 200, 35, 90, 0); + instance.setWorldSpawnPosition(newSpawnPosition); + assertEquals(newSpawnPosition, instance.getWorldSpawnPosition()); + env.destroyInstance(instance); + } + + @Test + void testCancelledWorldPositionUpdate(@NotNull Env env) { + var instance = env.createFlatInstance(); + assertFalse(instance.setWorldSpawnPosition(Pos.ZERO)); + env.destroyInstance(instance); + } + + @Test + void testInstanceWorldPositionChangeEvent(@NotNull Env env) { + var instance = env.createFlatInstance(); + var listener = env.listen(InstanceWorldPositionChangeEvent.class); + Pos newSpawnPosition = new Pos(100, 200, 35, 90, 0); + listener.followup(event -> { + assertEquals(Pos.ZERO, event.getOldPosition()); + assertEquals(newSpawnPosition, event.getNewPosition()); + }); + instance.setWorldSpawnPosition(newSpawnPosition); + env.destroyInstance(instance); + } +} +//Microtus end - integrate world spawn position diff --git a/src/test/java/net/minestom/server/instance/WeatherTest.java b/src/test/java/net/minestom/server/instance/WeatherTest.java index 42e4a037133..e1d7bd95427 100644 --- a/src/test/java/net/minestom/server/instance/WeatherTest.java +++ b/src/test/java/net/minestom/server/instance/WeatherTest.java @@ -3,18 +3,19 @@ import net.minestom.server.coordinate.Pos; import net.minestom.server.network.packet.server.play.ChangeGameStatePacket; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; -@EnvTest -public class WeatherTest { +@ExtendWith(MicrotusExtension.class) +class WeatherTest { @Test - public void weatherTest(Env env) { + void weatherTest(Env env) { var instance = env.createFlatInstance(); // Defaults diff --git a/src/test/java/net/minestom/server/instance/WorldBorderIntegrationTest.java b/src/test/java/net/minestom/server/instance/WorldBorderIntegrationTest.java index 81b34071d20..78c33cc903d 100644 --- a/src/test/java/net/minestom/server/instance/WorldBorderIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/WorldBorderIntegrationTest.java @@ -1,14 +1,15 @@ package net.minestom.server.instance; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -@EnvTest -public class WorldBorderIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class WorldBorderIntegrationTest { @Test public void setWorldborderSize(Env env) { diff --git a/src/test/java/net/minestom/server/instance/anvil/AnvilLoaderIntegrationTest.java b/src/test/java/net/minestom/server/instance/anvil/AnvilLoaderIntegrationTest.java index 04a5e03bb06..efc1dc606d6 100644 --- a/src/test/java/net/minestom/server/instance/anvil/AnvilLoaderIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/anvil/AnvilLoaderIntegrationTest.java @@ -8,13 +8,18 @@ import net.minestom.server.registry.DynamicRegistry; import net.minestom.server.world.biome.Biome; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.io.IOException; -import java.nio.file.*; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; @@ -22,7 +27,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -@EnvTest +@ExtendWith(MicrotusExtension.class) public class AnvilLoaderIntegrationTest { private static final Path testRoot = Path.of("src", "test", "resources", "net", "minestom", "server", "instance"); @@ -73,6 +78,7 @@ public void parallelSaveNonexistentFiles(Env env) throws Exception { }); instance.saveChunksToStorage().join(); assertNull(exception.get()); + exception.set(null); } @Test diff --git a/src/test/java/net/minestom/server/instance/generator/BiomeIntegrationTest.java b/src/test/java/net/minestom/server/instance/generator/BiomeIntegrationTest.java index d53e4063b62..fe34fe0445d 100644 --- a/src/test/java/net/minestom/server/instance/generator/BiomeIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/generator/BiomeIntegrationTest.java @@ -4,15 +4,16 @@ import net.minestom.server.instance.generator.GeneratorImpl.GenSection; import net.minestom.server.world.biome.Biome; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.Arrays; import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest +@ExtendWith(MicrotusExtension.class) public class BiomeIntegrationTest { private static int PLAINS_ID, BADLANDS_ID; diff --git a/src/test/java/net/minestom/server/instance/generator/GeneratorForkConsumerIntegrationTest.java b/src/test/java/net/minestom/server/instance/generator/GeneratorForkConsumerIntegrationTest.java index 11de225ec4c..c1447794ac1 100644 --- a/src/test/java/net/minestom/server/instance/generator/GeneratorForkConsumerIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/generator/GeneratorForkConsumerIntegrationTest.java @@ -3,8 +3,9 @@ import net.minestom.server.coordinate.Point; import net.minestom.server.instance.block.Block; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -13,11 +14,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -@EnvTest -public class GeneratorForkConsumerIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class GeneratorForkConsumerIntegrationTest { @Test - public void empty(Env env) { + void empty(Env env) { var manager = env.process().instance(); var instance = manager.createInstanceContainer(); AtomicReference failed = new AtomicReference<>(); @@ -31,47 +32,44 @@ public void empty(Env env) { }); instance.loadChunk(0, 0).join(); assertNull(failed.get(), "Failed: " + failed.get()); + failed.set(null); } @Test - public void local(Env env) { + void local(Env env) { var manager = env.process().instance(); var instance = manager.createInstanceContainer(); - instance.setGenerator(unit -> { - unit.fork(setter -> { - var dynamic = (GeneratorImpl.DynamicFork) setter; - assertNull(dynamic.minSection); - assertEquals(0, dynamic.width); - assertEquals(0, dynamic.height); - assertEquals(0, dynamic.depth); - setter.setBlock(unit.absoluteStart(), Block.STONE); - assertEquals(unit.absoluteStart(), dynamic.minSection); - assertEquals(1, dynamic.width); - assertEquals(1, dynamic.height); - assertEquals(1, dynamic.depth); - }); - }); + instance.setGenerator(unit -> unit.fork(setter -> { + var dynamic = (GeneratorImpl.DynamicFork) setter; + assertNull(dynamic.minSection); + assertEquals(0, dynamic.width); + assertEquals(0, dynamic.height); + assertEquals(0, dynamic.depth); + setter.setBlock(unit.absoluteStart(), Block.STONE); + assertEquals(unit.absoluteStart(), dynamic.minSection); + assertEquals(1, dynamic.width); + assertEquals(1, dynamic.height); + assertEquals(1, dynamic.depth); + })); instance.loadChunk(0, 0).join(); assertEquals(Block.STONE, instance.getBlock(0, -64, 0)); } @Test - public void doubleLocal(Env env) { + void doubleLocal(Env env) { var manager = env.process().instance(); var instance = manager.createInstanceContainer(); - instance.setGenerator(unit -> { - unit.fork(setter -> { - setter.setBlock(unit.absoluteStart(), Block.STONE); - setter.setBlock(unit.absoluteStart().add(1, 0, 0), Block.STONE); - }); - }); + instance.setGenerator(unit -> unit.fork(setter -> { + setter.setBlock(unit.absoluteStart(), Block.STONE); + setter.setBlock(unit.absoluteStart().add(1, 0, 0), Block.STONE); + })); instance.loadChunk(0, 0).join(); assertEquals(Block.STONE, instance.getBlock(0, -64, 0)); assertEquals(Block.STONE, instance.getBlock(1, -64, 0)); } @Test - public void neighborZ(Env env) { + void neighborZ(Env env) { var manager = env.process().instance(); var instance = manager.createInstanceContainer(); instance.setGenerator(unit -> { @@ -97,7 +95,7 @@ public void neighborZ(Env env) { } @Test - public void neighborX(Env env) { + void neighborX(Env env) { var manager = env.process().instance(); var instance = manager.createInstanceContainer(); instance.setGenerator(unit -> { @@ -123,7 +121,7 @@ public void neighborX(Env env) { } @Test - public void neighborY(Env env) { + void neighborY(Env env) { var manager = env.process().instance(); var instance = manager.createInstanceContainer(); instance.setGenerator(unit -> { @@ -147,7 +145,7 @@ public void neighborY(Env env) { } @Test - public void verticalAndHorizontalSectionBorders(Env env) { + void verticalAndHorizontalSectionBorders(Env env) { var manager = env.process().instance(); var instance = manager.createInstanceContainer(); Set points = ConcurrentHashMap.newKeySet(); diff --git a/src/test/java/net/minestom/server/instance/generator/GeneratorTest.java b/src/test/java/net/minestom/server/instance/generator/GeneratorTest.java index f961a8ead8c..cb8c4ad1682 100644 --- a/src/test/java/net/minestom/server/instance/generator/GeneratorTest.java +++ b/src/test/java/net/minestom/server/instance/generator/GeneratorTest.java @@ -22,9 +22,10 @@ import static net.minestom.server.utils.chunk.ChunkUtils.floorSection; import static org.junit.jupiter.api.Assertions.*; -public class GeneratorTest { +class GeneratorTest { + @Test - public void unitSize() { + void unitSize() { assertDoesNotThrow(() -> dummyUnit(Vec.ZERO, Vec.SECTION)); assertDoesNotThrow(() -> dummyUnit(Vec.SECTION, new Vec(32))); assertThrows(IllegalArgumentException.class, () -> dummyUnit(new Vec(15), Vec.ZERO)); @@ -35,7 +36,7 @@ public void unitSize() { @ParameterizedTest @MethodSource("sectionFloorParam") - public void sectionFloor(int expected, int input) { + void sectionFloor(int expected, int input) { assertEquals(expected, floorSection(input), "floorSection(" + input + ")"); } @@ -54,7 +55,7 @@ private static Stream sectionFloorParam() { @ParameterizedTest @MethodSource("sectionCeilParam") - public void sectionCeil(int expected, int input) { + void sectionCeil(int expected, int input) { assertEquals(expected, ceilSection(input), "ceilSection(" + input + ")"); } @@ -72,7 +73,7 @@ private static Stream sectionCeilParam() { } @Test - public void chunkSize() { + void chunkSize() { final int minSection = 0; final int maxSection = 5; final int chunkX = 3; @@ -87,7 +88,7 @@ public void chunkSize() { } @Test - public void chunkSizeNeg() { + void chunkSizeNeg() { final int minSection = -1; final int maxSection = 5; final int chunkX = 3; @@ -102,7 +103,7 @@ public void chunkSizeNeg() { } @Test - public void sectionSize() { + void sectionSize() { final int sectionX = 3; final int sectionY = -5; final int sectionZ = -2; @@ -113,7 +114,7 @@ public void sectionSize() { } @Test - public void chunkSubdivide() { + void chunkSubdivide() { final int minSection = -1; final int maxSection = 5; final int chunkX = 3; @@ -133,7 +134,7 @@ public void chunkSubdivide() { } @Test - public void chunkAbsolute() { + void chunkAbsolute() { final int minSection = 0; final int maxSection = 5; final int chunkX = 3; @@ -154,7 +155,7 @@ public void chunkAbsolute() { } @Test - public void chunkAbsoluteAll() { + void chunkAbsoluteAll() { final int minSection = 0; final int maxSection = 5; final int chunkX = 3; @@ -182,7 +183,7 @@ public void chunkAbsoluteAll() { } @Test - public void chunkRelative() { + void chunkRelative() { final int minSection = -1; final int maxSection = 5; final int chunkX = 3; @@ -209,7 +210,7 @@ public void chunkRelative() { } @Test - public void chunkRelativeAll() { + void chunkRelativeAll() { final int minSection = -1; final int maxSection = 5; final int chunkX = 3; @@ -238,7 +239,7 @@ public void chunkRelativeAll() { } @Test - public void chunkFillHeightExact() { + void chunkFillHeightExact() { final int minSection = -1; final int maxSection = 5; final int sectionCount = maxSection - minSection; @@ -262,7 +263,7 @@ public void chunkFillHeightExact() { } @Test - public void chunkFillHeightOneOff() { + void chunkFillHeightOneOff() { final int minSection = -1; final int maxSection = 5; final int sectionCount = maxSection - minSection; @@ -300,7 +301,7 @@ public void chunkFillHeightOneOff() { } @Test - public void sectionFill() { + void sectionFill() { GenSection section = new GenSection(); var chunkUnit = GeneratorImpl.section(null, section, -1, -1, 0); Generator generator = chunk -> chunk.modifier().fill(Block.STONE); @@ -310,7 +311,7 @@ public void sectionFill() { } @Test - public void testForkAcrossBorders() { + void testForkAcrossBorders() { final int minSection = -4; final int maxSection = 4; diff --git a/src/test/java/net/minestom/server/instance/light/BlockIsOccludedTest.java b/src/test/java/net/minestom/server/instance/light/BlockIsOccludedTest.java index 5cded9c29fb..c2457c6b128 100644 --- a/src/test/java/net/minestom/server/instance/light/BlockIsOccludedTest.java +++ b/src/test/java/net/minestom/server/instance/light/BlockIsOccludedTest.java @@ -10,48 +10,48 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -public class BlockIsOccludedTest { +class BlockIsOccludedTest { @Test - public void blockAir() { + void blockAir() { Shape airBlock = Block.AIR.registry().collisionShape(); - for (BlockFace face : BlockFace.values()) { + for (BlockFace face : BlockFace.getValues()) { assertFalse(airBlock.isOccluded(airBlock, face)); } } @Test - public void blockLantern() { + void blockLantern() { Shape shape = Block.LANTERN.registry().collisionShape(); Shape airBlock = Block.AIR.registry().collisionShape(); - for (BlockFace face : BlockFace.values()) { + for (BlockFace face : BlockFace.getValues()) { assertFalse(shape.isOccluded(airBlock, face)); } } @Test - public void blockSpruceLeaves() { + void blockSpruceLeaves() { Shape shape = Block.SPRUCE_LEAVES.registry().collisionShape(); Shape airBlock = Block.AIR.registry().collisionShape(); - for (BlockFace face : BlockFace.values()) { + for (BlockFace face : BlockFace.getValues()) { assertFalse(shape.isOccluded(airBlock, face)); } } @Test - public void blockCauldron() { + void blockCauldron() { Shape shape = Block.CAULDRON.registry().collisionShape(); Shape airBlock = Block.AIR.registry().collisionShape(); - for (BlockFace face : BlockFace.values()) { + for (BlockFace face : BlockFace.getValues()) { assertFalse(shape.isOccluded(airBlock, face)); } } @Test - public void blockSlabBottomAir() { + void blockSlabBottomAir() { Shape shape = Block.SANDSTONE_SLAB.registry().collisionShape(); Shape airBlock = Block.AIR.registry().collisionShape(); @@ -65,7 +65,7 @@ public void blockSlabBottomAir() { } @Test - public void blockSlabTopEnchantingTable() { + void blockSlabTopEnchantingTable() { Shape shape1 = Block.SANDSTONE_SLAB.withProperty("type", "top").registry().collisionShape(); Shape shape2 = Block.ENCHANTING_TABLE.registry().collisionShape(); @@ -79,7 +79,7 @@ public void blockSlabTopEnchantingTable() { } @Test - public void blockStairWest() { + void blockStairWest() { Shape shape = Block.SANDSTONE_STAIRS.withProperties(Map.of( "facing", "west", "half", "bottom", @@ -97,7 +97,7 @@ public void blockStairWest() { } @Test - public void blockSlabBottomStone() { + void blockSlabBottomStone() { Shape shape = Block.SANDSTONE_SLAB.registry().collisionShape(); Shape stoneBlock = Block.STONE.registry().collisionShape(); @@ -110,17 +110,17 @@ public void blockSlabBottomStone() { } @Test - public void blockStone() { + void blockStone() { Shape shape = Block.STONE.registry().collisionShape(); Shape airBlock = Block.AIR.registry().collisionShape(); - for (BlockFace face : BlockFace.values()) { + for (BlockFace face : BlockFace.getValues()) { assertTrue(shape.isOccluded(airBlock, face)); } } @Test - public void blockStair() { + void blockStair() { Shape shape = Block.SANDSTONE_STAIRS.registry().collisionShape(); Shape airBlock = Block.AIR.registry().collisionShape(); @@ -134,7 +134,7 @@ public void blockStair() { } @Test - public void blockSlab() { + void blockSlab() { Shape shape = Block.SANDSTONE_SLAB.registry().collisionShape(); Shape airBlock = Block.AIR.registry().collisionShape(); @@ -148,7 +148,7 @@ public void blockSlab() { } @Test - public void blockSlabBottomAndSlabTop() { + void blockSlabBottomAndSlabTop() { Shape shape1 = Block.SANDSTONE_SLAB.registry().collisionShape(); Shape shape2 = Block.SANDSTONE_SLAB.withProperty("type", "top").registry().collisionShape(); @@ -162,7 +162,7 @@ public void blockSlabBottomAndSlabTop() { } @Test - public void blockSlabBottomAndSlabBottom() { + void blockSlabBottomAndSlabBottom() { Shape shape = Block.SANDSTONE_SLAB.registry().collisionShape(); assertTrue(shape.isOccluded(shape, BlockFace.BOTTOM)); @@ -175,7 +175,7 @@ public void blockSlabBottomAndSlabBottom() { } @Test - public void blockStairAndSlabBottom() { + void blockStairAndSlabBottom() { Shape shape1 = Block.STONE_STAIRS.registry().collisionShape(); Shape shape2 = Block.SANDSTONE_SLAB.registry().collisionShape(); @@ -189,7 +189,7 @@ public void blockStairAndSlabBottom() { } @Test - public void blockStairAndSlabTop() { + void blockStairAndSlabTop() { Shape shape1 = Block.STONE_STAIRS.registry().collisionShape(); Shape shape2 = Block.SANDSTONE_SLAB.withProperty("type", "top").registry().collisionShape(); diff --git a/src/test/java/net/minestom/server/instance/light/BlockLightTest.java b/src/test/java/net/minestom/server/instance/light/BlockLightTest.java index 2280d01192b..dd93d686e7d 100644 --- a/src/test/java/net/minestom/server/instance/light/BlockLightTest.java +++ b/src/test/java/net/minestom/server/instance/light/BlockLightTest.java @@ -13,10 +13,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; -public class BlockLightTest { +class BlockLightTest { @Test - public void empty() { + void empty() { var palette = Palette.blocks(); var result = LightCompute.compute(palette, BlockLight.buildInternalQueue(palette)); for (byte light : result) { @@ -25,7 +25,7 @@ public void empty() { } @Test - public void glowstone() { + void glowstone() { var palette = Palette.blocks(); palette.set(0, 1, 0, Block.GLOWSTONE.stateId()); assertLight(palette, Map.of( @@ -35,7 +35,7 @@ public void glowstone() { } @Test - public void doubleGlowstone() { + void doubleGlowstone() { var palette = Palette.blocks(); palette.set(0, 1, 0, Block.GLOWSTONE.stateId()); palette.set(4, 1, 4, Block.GLOWSTONE.stateId()); @@ -48,7 +48,7 @@ public void doubleGlowstone() { } @Test - public void glowstoneBorder() { + void glowstoneBorder() { var palette = Palette.blocks(); palette.set(0, 1, 0, Block.GLOWSTONE.stateId()); assertLight(palette, Map.of( @@ -65,7 +65,7 @@ public void glowstoneBorder() { } @Test - public void glowstoneBlock() { + void glowstoneBlock() { var palette = Palette.blocks(); palette.set(0, 1, 0, Block.GLOWSTONE.stateId()); palette.set(0, 1, 1, Block.STONE.stateId()); @@ -76,7 +76,7 @@ public void glowstoneBlock() { } @Test - public void isolated() { + void isolated() { var palette = Palette.blocks(); palette.set(4, 1, 4, Block.GLOWSTONE.stateId()); @@ -102,7 +102,7 @@ public void isolated() { } @Test - public void isolatedStair() { + void isolatedStair() { var palette = Palette.blocks(); palette.set(4, 1, 4, Block.GLOWSTONE.stateId()); palette.set(3, 1, 4, Block.OAK_STAIRS.withProperties(Map.of( @@ -123,7 +123,7 @@ public void isolatedStair() { } @Test - public void isolatedStairOpposite() { + void isolatedStairOpposite() { var palette = Palette.blocks(); palette.set(4, 1, 4, Block.GLOWSTONE.stateId()); palette.set(3, 1, 4, Block.OAK_STAIRS.withProperties(Map.of( @@ -149,7 +149,7 @@ public void isolatedStairOpposite() { } @Test - public void isolatedStairWest() { + void isolatedStairWest() { var palette = Palette.blocks(); palette.set(4, 1, 4, Block.GLOWSTONE.stateId()); palette.set(3, 1, 4, Block.OAK_STAIRS.withProperties(Map.of( @@ -178,7 +178,7 @@ public void isolatedStairWest() { } @Test - public void isolatedStairSouth() { + void isolatedStairSouth() { var palette = Palette.blocks(); palette.set(4, 1, 4, Block.GLOWSTONE.stateId()); palette.set(3, 1, 4, Block.OAK_STAIRS.withProperties(Map.of( diff --git a/src/test/java/net/minestom/server/instance/light/LightParityIntegrationTest.java b/src/test/java/net/minestom/server/instance/light/LightParityIntegrationTest.java index 10d6c8598b6..92d2fe1bc52 100644 --- a/src/test/java/net/minestom/server/instance/light/LightParityIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/light/LightParityIntegrationTest.java @@ -9,20 +9,26 @@ import net.minestom.server.instance.palette.Palette; import net.minestom.server.world.DimensionType; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; import java.util.concurrent.CompletableFuture; import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest -public class LightParityIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class LightParityIntegrationTest { private static final int REGION_SIZE = 3; @Test diff --git a/src/test/java/net/minestom/server/instance/light/WorldRelightIntegrationTest.java b/src/test/java/net/minestom/server/instance/light/WorldRelightIntegrationTest.java index a3147e5b014..e62795e0a79 100644 --- a/src/test/java/net/minestom/server/instance/light/WorldRelightIntegrationTest.java +++ b/src/test/java/net/minestom/server/instance/light/WorldRelightIntegrationTest.java @@ -6,17 +6,18 @@ import net.minestom.server.instance.LightingChunk; import net.minestom.server.instance.block.Block; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.Map; import static java.util.Map.entry; import static net.minestom.server.instance.BlockLightMergeIntegrationTest.assertLightInstance; -@EnvTest -public class WorldRelightIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class WorldRelightIntegrationTest { private @NotNull Instance createLightingInstance(@NotNull ServerProcess process) { var instance = process.instance().createInstanceContainer(); instance.setGenerator(unit -> { @@ -28,7 +29,7 @@ public class WorldRelightIntegrationTest { } @Test - public void testBorderLava(Env env) { + void testBorderLava(Env env) { Instance instance = env.createFlatInstance(); instance.setChunkSupplier(LightingChunk::new); instance.loadChunk(6, 16).join(); @@ -46,7 +47,7 @@ public void testBorderLava(Env env) { } @Test - public void testBlockRemoval(Env env) { + void testBlockRemoval(Env env) { Instance instance = createLightingInstance(env.process()); instance.setChunkSupplier(LightingChunk::new); for (int x = -3; x <= 3; x++) { diff --git a/src/test/java/net/minestom/server/instance/palette/PaletteOptimizationTest.java b/src/test/java/net/minestom/server/instance/palette/PaletteOptimizationTest.java index 9916d52ab23..877f265955d 100644 --- a/src/test/java/net/minestom/server/instance/palette/PaletteOptimizationTest.java +++ b/src/test/java/net/minestom/server/instance/palette/PaletteOptimizationTest.java @@ -8,23 +8,23 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -public class PaletteOptimizationTest { +class PaletteOptimizationTest { @Test - public void empty() { + void empty() { var palette = createPalette(); paletteEquals(palette.palette, palette.optimizedPalette()); } @Test - public void single() { + void single() { var palette = createPalette(); palette.set(0, 0, 0, 1); paletteEquals(palette.palette, palette.optimizedPalette()); } @Test - public void random() { + void random() { var random = new Random(12345); var palette = createPalette(); palette.setAll((x, y, z) -> random.nextInt(256)); @@ -34,7 +34,7 @@ public void random() { } @Test - public void manualFill() { + void manualFill() { var palette = createPalette(); palette.setAll((x, y, z) -> 1); paletteEquals(palette.palette, palette.optimizedPalette()); diff --git a/src/test/java/net/minestom/server/instance/palette/PaletteTest.java b/src/test/java/net/minestom/server/instance/palette/PaletteTest.java index 3372ade4565..583214ea6d1 100644 --- a/src/test/java/net/minestom/server/instance/palette/PaletteTest.java +++ b/src/test/java/net/minestom/server/instance/palette/PaletteTest.java @@ -11,17 +11,17 @@ import static org.junit.jupiter.api.Assertions.*; -public class PaletteTest { +class PaletteTest { @Test - public void singlePlacement() { + void singlePlacement() { var palette = Palette.blocks(); palette.set(0, 0, 1, 1); assertEquals(1, palette.get(0, 0, 1)); } @Test - public void placement() { + void placement() { var palettes = testPalettes(); for (Palette palette : palettes) { final int dimension = palette.dimension(); @@ -56,7 +56,7 @@ public void placement() { } @Test - public void placementHighValue() { + void placementHighValue() { final int value = 250_000; for (Palette palette : testPalettes()) { palette.set(0, 0, 1, value); @@ -65,7 +65,7 @@ public void placementHighValue() { } @Test - public void negPlacement() { + void negPlacement() { var palettes = testPalettes(); for (Palette palette : palettes) { assertThrows(IllegalArgumentException.class, () -> palette.set(-1, 0, 0, 64)); @@ -79,7 +79,7 @@ public void negPlacement() { } @Test - public void resize() { + void resize() { Palette palette = Palette.newPalette(16, 5, 2); palette.set(0, 0, 0, 1); assertEquals(2, palette.bitsPerEntry()); @@ -98,7 +98,7 @@ public void resize() { @Test - public void fill() { + void fill() { var palettes = testPalettes(); for (Palette palette : palettes) { assertEquals(0, palette.count()); @@ -129,7 +129,7 @@ public void fill() { } @Test - public void bulk() { + void bulk() { var palettes = testPalettes(); for (Palette palette : palettes) { final int dimension = palette.dimension(); @@ -154,7 +154,7 @@ public void bulk() { } @Test - public void bulkAll() { + void bulkAll() { var palettes = testPalettes(); for (Palette palette : palettes) { // Fill all entries @@ -172,7 +172,7 @@ public void bulkAll() { } @Test - public void bulkAllOrder() { + void bulkAllOrder() { var palettes = testPalettes(); for (Palette palette : palettes) { AtomicInteger count = new AtomicInteger(); @@ -210,7 +210,7 @@ public void bulkAllOrder() { } @Test - public void setAllConstant() { + void setAllConstant() { var palettes = testPalettes(); for (Palette palette : palettes) { palette.setAll((x, y, z) -> 1); @@ -219,7 +219,7 @@ public void setAllConstant() { } @Test - public void getAllPresent() { + void getAllPresent() { var palettes = testPalettes(); for (Palette palette : palettes) { palette.getAllPresent((x, y, z, value) -> fail("The palette should be empty")); @@ -234,7 +234,7 @@ public void getAllPresent() { } @Test - public void replaceAll() { + void replaceAll() { var palettes = testPalettes(); for (Palette palette : palettes) { palette.setAll((x, y, z) -> x + y + z + 1); @@ -247,7 +247,7 @@ public void replaceAll() { } @Test - public void replace() { + void replace() { var palettes = testPalettes(); for (Palette palette : palettes) { palette.set(0, 0, 0, 1); @@ -260,7 +260,7 @@ public void replace() { } @Test - public void replaceLoop() { + void replaceLoop() { var palette = Palette.newPalette(2, 15, 4); palette.setAll((x, y, z) -> x + y + z); final int dimension = palette.dimension(); @@ -274,7 +274,7 @@ public void replaceLoop() { } @Test - public void dimension() { + void dimension() { assertThrows(Exception.class, () -> Palette.newPalette(-4, 5, 3)); assertThrows(Exception.class, () -> Palette.newPalette(0, 5, 3)); assertThrows(Exception.class, () -> Palette.newPalette(1, 5, 3)); diff --git a/src/test/java/net/minestom/server/inventory/InventoryCloseStateTest.java b/src/test/java/net/minestom/server/inventory/InventoryCloseStateTest.java index 21d92088f43..1997fd7eabf 100644 --- a/src/test/java/net/minestom/server/inventory/InventoryCloseStateTest.java +++ b/src/test/java/net/minestom/server/inventory/InventoryCloseStateTest.java @@ -5,17 +5,18 @@ import net.minestom.server.network.packet.client.play.ClientCloseWindowPacket; import net.minestom.server.network.packet.server.play.CloseWindowPacket; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest -public class InventoryCloseStateTest { +@ExtendWith(MicrotusExtension.class) +class InventoryCloseStateTest { @Test - public void doNotReceiveClosePacketFromServerWhenSendingClientCloseWindowPacket(Env env) { + void doNotReceiveClosePacketFromServerWhenSendingClientCloseWindowPacket(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); diff --git a/src/test/java/net/minestom/server/inventory/InventoryIntegrationTest.java b/src/test/java/net/minestom/server/inventory/InventoryIntegrationTest.java index 0dd16e9c362..8d2290e3286 100644 --- a/src/test/java/net/minestom/server/inventory/InventoryIntegrationTest.java +++ b/src/test/java/net/minestom/server/inventory/InventoryIntegrationTest.java @@ -3,7 +3,6 @@ import net.kyori.adventure.text.Component; import net.minestom.server.utils.inventory.PlayerInventoryUtils; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Pos; import net.minestom.server.event.item.ItemDropEvent; import net.minestom.server.item.ItemStack; @@ -11,17 +10,20 @@ import net.minestom.server.network.packet.server.play.EntityEquipmentPacket; import net.minestom.server.network.packet.server.play.SetSlotPacket; import net.minestom.server.network.packet.server.play.WindowItemsPacket; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.*; -@EnvTest -public class InventoryIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class InventoryIntegrationTest { + private static final Component TITLE = Component.text("title"); private static final ItemStack MAGIC_STACK = ItemStack.of(Material.DIAMOND, 3); @Test - public void setSlotDuplicateTest(Env env) { + void setSlotDuplicateTest(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); @@ -45,7 +47,7 @@ public void setSlotDuplicateTest(Env env) { } @Test - public void setCursorItemDuplicateTest(Env env) { + void setCursorItemDuplicateTest(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); @@ -69,7 +71,7 @@ public void setCursorItemDuplicateTest(Env env) { } @Test - public void clearInventoryTest(Env env) { + void clearInventoryTest(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); @@ -145,11 +147,11 @@ public void clearingPlayerInventoryClearsCursorTest(Env env) { } @Test - public void closeInventoryTest(Env env) { + void closeInventoryTest(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); - final var inventory = new Inventory(InventoryType.CHEST_1_ROW, "title"); + final var inventory = new Inventory(InventoryType.CHEST_1_ROW, TITLE); player.openInventory(inventory); assertSame(inventory, player.getOpenInventory()); player.closeInventory(); @@ -157,12 +159,12 @@ public void closeInventoryTest(Env env) { } @Test - public void openInventoryOnItemDropFromInventoryClosingTest(Env env) { + void openInventoryOnItemDropFromInventoryClosingTest(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); var listener = env.listen(ItemDropEvent.class); - final var firstInventory = new Inventory(InventoryType.CHEST_1_ROW, "title"); + final var firstInventory = new Inventory(InventoryType.CHEST_1_ROW, TITLE); player.openInventory(firstInventory); assertSame(firstInventory, player.getOpenInventory()); player.getInventory().setCursorItem(ItemStack.of(Material.STONE)); @@ -172,15 +174,15 @@ public void openInventoryOnItemDropFromInventoryClosingTest(Env env) { assertNull(player.getOpenInventory()); player.openInventory(firstInventory); - player.getInventory().setCursorItem(ItemStack.of(Material.STONE)); - final var secondInventory = new Inventory(InventoryType.CHEST_1_ROW, "title"); + firstInventory.setCursorItem(player, ItemStack.of(Material.STONE)); + final var secondInventory = new Inventory(InventoryType.CHEST_1_ROW, TITLE); listener.followup(event -> event.getPlayer().openInventory(secondInventory)); player.closeInventory(); assertSame(secondInventory, player.getOpenInventory()); } @Test - public void testInnerInventorySlotSending(Env env) { + void testInnerInventorySlotSending(Env env) { // Inner inventory changes are sent along with the open inventory // Otherwise, they are sent separately diff --git a/src/test/java/net/minestom/server/inventory/InventoryTest.java b/src/test/java/net/minestom/server/inventory/InventoryTest.java index 5ca8aaf6518..8dded330e60 100644 --- a/src/test/java/net/minestom/server/inventory/InventoryTest.java +++ b/src/test/java/net/minestom/server/inventory/InventoryTest.java @@ -9,7 +9,9 @@ import static org.junit.jupiter.api.Assertions.*; -public class InventoryTest { +class InventoryTest { + + private static final Component TITLE = Component.text("title"); static { // Required to prevent initialization error during event call @@ -17,8 +19,8 @@ public class InventoryTest { } @Test - public void testCreation() { - Inventory inventory = new Inventory(InventoryType.CHEST_1_ROW, "title"); + void testCreation() { + Inventory inventory = new Inventory(InventoryType.CHEST_1_ROW, TITLE); assertEquals(InventoryType.CHEST_1_ROW, inventory.getInventoryType()); assertEquals(Component.text("title"), inventory.getTitle()); @@ -27,11 +29,11 @@ public void testCreation() { } @Test - public void testEntry() { + void testEntry() { var item1 = ItemStack.of(Material.DIAMOND); var item2 = ItemStack.of(Material.GOLD_INGOT); - Inventory inventory = new Inventory(InventoryType.CHEST_1_ROW, "title"); + Inventory inventory = new Inventory(InventoryType.CHEST_1_ROW, TITLE); assertSame(ItemStack.AIR, inventory.getItemStack(0)); inventory.setItemStack(0, item1); assertSame(item1, inventory.getItemStack(0)); @@ -53,9 +55,9 @@ public void testEntry() { } @Test - public void testTake() { + void testTake() { ItemStack item = ItemStack.of(Material.DIAMOND, 32); - Inventory inventory = new Inventory(InventoryType.CHEST_1_ROW, "title"); + Inventory inventory = new Inventory(InventoryType.CHEST_1_ROW, TITLE); inventory.setItemStack(0, item); assertTrue(inventory.takeItemStack(item, TransactionOption.DRY_RUN)); assertTrue(inventory.takeItemStack(item.withAmount(31), TransactionOption.DRY_RUN)); @@ -67,8 +69,8 @@ public void testTake() { } @Test - public void testAdd() { - Inventory inventory = new Inventory(InventoryType.HOPPER, "title"); + void testAdd() { + Inventory inventory = new Inventory(InventoryType.HOPPER, TITLE); assertTrue(inventory.addItemStack(ItemStack.of(Material.DIAMOND, 32), TransactionOption.ALL_OR_NOTHING)); assertTrue(inventory.addItemStack(ItemStack.of(Material.GOLD_BLOCK, 32), TransactionOption.ALL_OR_NOTHING)); assertTrue(inventory.addItemStack(ItemStack.of(Material.MAP, 32), TransactionOption.ALL_OR_NOTHING)); @@ -78,16 +80,16 @@ public void testAdd() { } @Test - public void testIds() { + void testIds() { for (int i = 0; i <= 1000; ++i) { - final byte windowId = new Inventory(InventoryType.CHEST_1_ROW, "title").getWindowId(); + final byte windowId = new Inventory(InventoryType.CHEST_1_ROW, TITLE).getWindowId(); assertTrue(windowId > 0); } } @Test public void testStackSize99() { - var inventory = new Inventory(InventoryType.CHEST_1_ROW, "title"); + var inventory = new Inventory(InventoryType.CHEST_1_ROW, Component.text("title")); var item = ItemStack.builder(Material.DIAMOND).set(ItemComponent.MAX_STACK_SIZE, 99).amount(99).build(); assertTrue(inventory.addItemStack(item, TransactionOption.ALL_OR_NOTHING)); @@ -96,7 +98,7 @@ public void testStackSize99() { @Test public void testStackSize99OnSmaller() { - var inventory = new Inventory(InventoryType.CHEST_1_ROW, "title"); + var inventory = new Inventory(InventoryType.CHEST_1_ROW, Component.text("title")); var item44 = ItemStack.builder(Material.DIAMOND).set(ItemComponent.MAX_STACK_SIZE, 44).amount(43).build(); var item99 = ItemStack.builder(Material.DIAMOND).set(ItemComponent.MAX_STACK_SIZE, 99).amount(99).build(); diff --git a/src/test/java/net/minestom/server/inventory/PlayerCreativeSlotTest.java b/src/test/java/net/minestom/server/inventory/PlayerCreativeSlotTest.java index a18215debc1..7e841fe6c7a 100644 --- a/src/test/java/net/minestom/server/inventory/PlayerCreativeSlotTest.java +++ b/src/test/java/net/minestom/server/inventory/PlayerCreativeSlotTest.java @@ -8,17 +8,18 @@ import net.minestom.server.network.packet.client.play.ClientCreativeInventoryActionPacket; import net.minestom.server.utils.inventory.PlayerInventoryUtils; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest -public class PlayerCreativeSlotTest { +@ExtendWith(MicrotusExtension.class) +class PlayerCreativeSlotTest { @Test - public void testCreativeSlots(Env env) { + void testCreativeSlots(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); @@ -31,7 +32,7 @@ public void testCreativeSlots(Env env) { } @Test - public void testBoundsCheck(Env env) { + void testBoundsCheck(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); diff --git a/src/test/java/net/minestom/server/inventory/PlayerInventoryIntegrationTest.java b/src/test/java/net/minestom/server/inventory/PlayerInventoryIntegrationTest.java index d3eb036644e..870ccbd86ec 100644 --- a/src/test/java/net/minestom/server/inventory/PlayerInventoryIntegrationTest.java +++ b/src/test/java/net/minestom/server/inventory/PlayerInventoryIntegrationTest.java @@ -1,7 +1,6 @@ package net.minestom.server.inventory; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.EquipmentSlot; import net.minestom.server.item.ItemStack; @@ -9,19 +8,21 @@ import net.minestom.server.network.packet.server.play.EntityEquipmentPacket; import net.minestom.server.network.packet.server.play.SetSlotPacket; import net.minestom.server.network.packet.server.play.WindowItemsPacket; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.Map; import static org.junit.jupiter.api.Assertions.*; -@EnvTest -public class PlayerInventoryIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class PlayerInventoryIntegrationTest { private static final ItemStack MAGIC_STACK = ItemStack.of(Material.DIAMOND, 3); @Test - public void setSlotDuplicateTest(Env env) { + void setSlotDuplicateTest(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); @@ -41,7 +42,7 @@ public void setSlotDuplicateTest(Env env) { } @Test - public void setCursorItemDuplicateTest(Env env) { + void setCursorItemDuplicateTest(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); @@ -61,7 +62,7 @@ public void setCursorItemDuplicateTest(Env env) { } @Test - public void clearInventoryTest(Env env) { + void clearInventoryTest(Env env) { var instance = env.createFlatInstance(); var connection = env.createConnection(); var player = connection.connect(instance, new Pos(0, 42, 0)).join(); @@ -105,7 +106,7 @@ public void clearInventoryTest(Env env) { } @Test - public void equipmentViewTest(Env env) { + void equipmentViewTest(Env env) { var instance = env.createFlatInstance(); var connectionArmored = env.createConnection(); var playerArmored = connectionArmored.connect(instance, new Pos(0, 42, 0)).join(); @@ -119,9 +120,7 @@ public void equipmentViewTest(Env env) { // Setting to an item should send EntityEquipmentPacket to viewer playerArmored.getInventory().setEquipment(EquipmentSlot.HELMET, MAGIC_STACK); - equipmentTracker.assertSingle(entityEquipmentPacket -> { - assertEquals(MAGIC_STACK, entityEquipmentPacket.equipments().get(EquipmentSlot.HELMET)); - }); + equipmentTracker.assertSingle(entityEquipmentPacket -> assertEquals(MAGIC_STACK, entityEquipmentPacket.equipments().get(EquipmentSlot.HELMET))); // Setting to the same item shouldn't send packet equipmentTracker = connectionViewer.trackIncoming(EntityEquipmentPacket.class); @@ -131,13 +130,11 @@ public void equipmentViewTest(Env env) { // Setting to air should send packet equipmentTracker = connectionViewer.trackIncoming(EntityEquipmentPacket.class); playerArmored.getInventory().setEquipment(EquipmentSlot.HELMET, ItemStack.AIR); - equipmentTracker.assertSingle(entityEquipmentPacket -> { - assertEquals(ItemStack.AIR, entityEquipmentPacket.equipments().get(EquipmentSlot.HELMET)); - }); + equipmentTracker.assertSingle(entityEquipmentPacket -> assertEquals(ItemStack.AIR, entityEquipmentPacket.equipments().get(EquipmentSlot.HELMET))); } @Test - public void heldItemViewTest(Env env) { + void heldItemViewTest(Env env) { var instance = env.createFlatInstance(); var connectionHolder = env.createConnection(); var playerHolder = connectionHolder.connect(instance, new Pos(0, 42, 0)).join(); @@ -152,23 +149,17 @@ public void heldItemViewTest(Env env) { // Setting held item var equipmentTracker = connectionViewer.trackIncoming(EntityEquipmentPacket.class); playerHolder.setItemInMainHand(MAGIC_STACK); - equipmentTracker.assertSingle(entityEquipmentPacket -> { - assertEquals(MAGIC_STACK, entityEquipmentPacket.equipments().get(EquipmentSlot.MAIN_HAND)); - }); + equipmentTracker.assertSingle(entityEquipmentPacket -> assertEquals(MAGIC_STACK, entityEquipmentPacket.equipments().get(EquipmentSlot.MAIN_HAND))); // Changing held slot to an empty slot should update MAIN_HAND to empty item equipmentTracker = connectionViewer.trackIncoming(EntityEquipmentPacket.class); playerHolder.setHeldItemSlot((byte) 3); - equipmentTracker.assertSingle(entityEquipmentPacket -> { - assertEquals(ItemStack.AIR, entityEquipmentPacket.equipments().get(EquipmentSlot.MAIN_HAND)); - }); + equipmentTracker.assertSingle(entityEquipmentPacket -> assertEquals(ItemStack.AIR, entityEquipmentPacket.equipments().get(EquipmentSlot.MAIN_HAND))); // Changing held slot to the original slot should update MAIN_HAND to original item equipmentTracker = connectionViewer.trackIncoming(EntityEquipmentPacket.class); playerHolder.setHeldItemSlot((byte) 0); - equipmentTracker.assertSingle(entityEquipmentPacket -> { - assertEquals(MAGIC_STACK, entityEquipmentPacket.equipments().get(EquipmentSlot.MAIN_HAND)); - }); + equipmentTracker.assertSingle(entityEquipmentPacket -> assertEquals(MAGIC_STACK, entityEquipmentPacket.equipments().get(EquipmentSlot.MAIN_HAND))); } } diff --git a/src/test/java/net/minestom/server/inventory/PlayerSlotConversionTest.java b/src/test/java/net/minestom/server/inventory/PlayerSlotConversionTest.java index 99205103912..20e11292072 100644 --- a/src/test/java/net/minestom/server/inventory/PlayerSlotConversionTest.java +++ b/src/test/java/net/minestom/server/inventory/PlayerSlotConversionTest.java @@ -8,10 +8,10 @@ /** * Test conversion from packet slots to internal ones (used in events and inventory methods) */ -public class PlayerSlotConversionTest { +class PlayerSlotConversionTest { @Test - public void hotbar() { + void hotbar() { // Convert 36-44 into 0-8 for (int i = 0; i < 9; i++) { assertEquals(i, convertPlayerInventorySlot(i + 36, OFFSET)); @@ -19,7 +19,7 @@ public void hotbar() { } @Test - public void mainInventory() { + void mainInventory() { // No conversion, slots should stay 9-35 for (int i = 9; i < 9 * 4; i++) { assertEquals(i, convertPlayerInventorySlot(i, OFFSET)); @@ -27,7 +27,7 @@ public void mainInventory() { } @Test - public void armor() { + void armor() { assertEquals(HELMET_SLOT, 41); assertEquals(CHESTPLATE_SLOT, 42); assertEquals(LEGGINGS_SLOT, 43); @@ -43,7 +43,7 @@ public void armor() { } @Test - public void craft() { + void craft() { assertEquals(CRAFT_RESULT, 36); assertEquals(CRAFT_SLOT_1, 37); assertEquals(CRAFT_SLOT_2, 38); diff --git a/src/test/java/net/minestom/server/inventory/click/integration/HeldClickIntegrationTest.java b/src/test/java/net/minestom/server/inventory/click/integration/HeldClickIntegrationTest.java index 5b9918f973e..4e55c3f8713 100644 --- a/src/test/java/net/minestom/server/inventory/click/integration/HeldClickIntegrationTest.java +++ b/src/test/java/net/minestom/server/inventory/click/integration/HeldClickIntegrationTest.java @@ -1,5 +1,7 @@ package net.minestom.server.inventory.click.integration; +import net.kyori.adventure.text.Component; +import net.minestom.testing.Env; import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.Player; import net.minestom.server.event.inventory.InventoryPreClickEvent; @@ -10,19 +12,19 @@ import net.minestom.server.item.Material; import net.minestom.server.network.packet.client.play.ClientClickWindowPacket; import net.minestom.server.utils.inventory.PlayerInventoryUtils; -import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.List; import static org.junit.jupiter.api.Assertions.*; -@EnvTest -public class HeldClickIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class HeldClickIntegrationTest { @Test - public void heldSelf(Env env) { + void heldSelf(Env env) { var instance = env.createFlatInstance(); var player = env.createPlayer(instance, new Pos(0, 40, 0)); var inventory = player.getInventory(); @@ -96,10 +98,10 @@ public void heldSelf(Env env) { } @Test - public void heldExternal(Env env) { + void heldExternal(Env env) { var instance = env.createFlatInstance(); var player = env.createPlayer(instance, new Pos(0, 40, 0)); - var inventory = new Inventory(InventoryType.HOPPER, "test"); + var inventory = new Inventory(InventoryType.HOPPER, Component.text("test")); var playerInv = player.getInventory(); player.openInventory(inventory); var listener = env.listen(InventoryPreClickEvent.class); diff --git a/src/test/java/net/minestom/server/inventory/click/integration/LeftClickIntegrationTest.java b/src/test/java/net/minestom/server/inventory/click/integration/LeftClickIntegrationTest.java index f7eb8f68963..9ded178842e 100644 --- a/src/test/java/net/minestom/server/inventory/click/integration/LeftClickIntegrationTest.java +++ b/src/test/java/net/minestom/server/inventory/click/integration/LeftClickIntegrationTest.java @@ -1,6 +1,8 @@ package net.minestom.server.inventory.click.integration; +import net.kyori.adventure.text.Component; +import net.minestom.testing.Env; import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.Player; import net.minestom.server.event.inventory.InventoryPreClickEvent; @@ -11,20 +13,20 @@ import net.minestom.server.item.Material; import net.minestom.server.network.packet.client.play.ClientClickWindowPacket; import net.minestom.server.utils.inventory.PlayerInventoryUtils; -import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -@EnvTest -public class LeftClickIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class LeftClickIntegrationTest { @Test - public void leftSelf(Env env) { + void leftSelf(Env env) { var instance = env.createFlatInstance(); var player = env.createPlayer(instance, new Pos(0, 40, 0)); var inventory = player.getInventory(); @@ -82,10 +84,10 @@ public void leftSelf(Env env) { } @Test - public void leftExternal(Env env) { + void leftExternal(Env env) { var instance = env.createFlatInstance(); var player = env.createPlayer(instance, new Pos(0, 40, 0)); - var inventory = new Inventory(InventoryType.HOPPER, "test"); + var inventory = new Inventory(InventoryType.HOPPER, Component.text("test")); player.openInventory(inventory); var listener = env.listen(InventoryPreClickEvent.class); inventory.setItemStack(1, ItemStack.of(Material.DIAMOND)); diff --git a/src/test/java/net/minestom/server/inventory/click/integration/RightClickIntegrationTest.java b/src/test/java/net/minestom/server/inventory/click/integration/RightClickIntegrationTest.java index 73868fd700a..e99f92c37e9 100644 --- a/src/test/java/net/minestom/server/inventory/click/integration/RightClickIntegrationTest.java +++ b/src/test/java/net/minestom/server/inventory/click/integration/RightClickIntegrationTest.java @@ -1,5 +1,7 @@ package net.minestom.server.inventory.click.integration; +import net.kyori.adventure.text.Component; +import net.minestom.testing.Env; import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.Player; import net.minestom.server.event.inventory.InventoryPreClickEvent; @@ -10,20 +12,20 @@ import net.minestom.server.item.Material; import net.minestom.server.network.packet.client.play.ClientClickWindowPacket; import net.minestom.server.utils.inventory.PlayerInventoryUtils; -import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -@EnvTest -public class RightClickIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class RightClickIntegrationTest { @Test - public void rightSelf(Env env) { + void rightSelf(Env env) { var instance = env.createFlatInstance(); var player = env.createPlayer(instance, new Pos(0, 40, 0)); var inventory = player.getInventory(); @@ -104,10 +106,10 @@ public void rightSelf(Env env) { } @Test - public void rightExternal(Env env) { + void rightExternal(Env env) { var instance = env.createFlatInstance(); var player = env.createPlayer(instance, new Pos(0, 40, 0)); - var inventory = new Inventory(InventoryType.HOPPER, "test"); + var inventory = new Inventory(InventoryType.HOPPER, Component.text("test")); player.openInventory(inventory); var listener = env.listen(InventoryPreClickEvent.class); inventory.setItemStack(1, ItemStack.of(Material.DIAMOND)); diff --git a/src/test/java/net/minestom/server/item/ItemAirTest.java b/src/test/java/net/minestom/server/item/ItemAirTest.java index 1dd8a87d1ae..39a04f71cd8 100644 --- a/src/test/java/net/minestom/server/item/ItemAirTest.java +++ b/src/test/java/net/minestom/server/item/ItemAirTest.java @@ -4,9 +4,9 @@ import static org.junit.jupiter.api.Assertions.*; -public class ItemAirTest { +class ItemAirTest { @Test - public void testAir() { + void testAir() { var item = ItemStack.of(Material.DIAMOND_SWORD); assertFalse(item.isAir()); assertTrue(ItemStack.AIR.isAir()); diff --git a/src/test/java/net/minestom/server/item/ItemTest.java b/src/test/java/net/minestom/server/item/ItemTest.java index dea4fb717ab..6a1f1170966 100644 --- a/src/test/java/net/minestom/server/item/ItemTest.java +++ b/src/test/java/net/minestom/server/item/ItemTest.java @@ -8,15 +8,16 @@ import net.minestom.server.item.component.EnchantmentList; import net.minestom.server.item.enchant.Enchantment; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.util.List; import java.util.Map; import static org.junit.jupiter.api.Assertions.*; -@EnvTest +@ExtendWith(MicrotusExtension.class) public class ItemTest { static { diff --git a/src/test/java/net/minestom/server/item/MaterialReadTest.java b/src/test/java/net/minestom/server/item/MaterialReadTest.java index af294b965ef..f9e756c31cd 100644 --- a/src/test/java/net/minestom/server/item/MaterialReadTest.java +++ b/src/test/java/net/minestom/server/item/MaterialReadTest.java @@ -1,12 +1,13 @@ package net.minestom.server.item; import net.minestom.server.MinecraftServer; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertNotNull; -@EnvTest +@ExtendWith(MicrotusExtension.class) public class MaterialReadTest { static { diff --git a/src/test/java/net/minestom/server/item/component/AbstractItemComponentTest.java b/src/test/java/net/minestom/server/item/component/AbstractItemComponentTest.java index 04d42aa17f9..c9e026a44c4 100644 --- a/src/test/java/net/minestom/server/item/component/AbstractItemComponentTest.java +++ b/src/test/java/net/minestom/server/item/component/AbstractItemComponentTest.java @@ -4,9 +4,10 @@ import net.minestom.server.network.NetworkBuffer; import net.minestom.server.utils.nbt.BinaryTagSerializer; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -19,7 +20,7 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest +@ExtendWith(MicrotusExtension.class) @TestInstance(TestInstance.Lifecycle.PER_CLASS) public abstract class AbstractItemComponentTest { diff --git a/src/test/java/net/minestom/server/listener/TestUseItemListenerIntegration.java b/src/test/java/net/minestom/server/listener/TestUseItemListenerIntegration.java index ade807db30c..b0bba4696a0 100644 --- a/src/test/java/net/minestom/server/listener/TestUseItemListenerIntegration.java +++ b/src/test/java/net/minestom/server/listener/TestUseItemListenerIntegration.java @@ -9,12 +9,13 @@ import net.minestom.server.item.Material; import net.minestom.server.network.packet.client.play.ClientUseItemPacket; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest +@ExtendWith(MicrotusExtension.class) public class TestUseItemListenerIntegration { @Test diff --git a/src/test/java/net/minestom/server/network/PacketWriteReadTest.java b/src/test/java/net/minestom/server/network/PacketWriteReadTest.java index 19e86f0e2ac..41097deef63 100644 --- a/src/test/java/net/minestom/server/network/PacketWriteReadTest.java +++ b/src/test/java/net/minestom/server/network/PacketWriteReadTest.java @@ -161,12 +161,12 @@ public static void setupClient() { } @Test - public void serverTest() { + void serverTest() { SERVER_PACKETS.forEach(PacketWriteReadTest::testPacket); } @Test - public void clientTest() { + void clientTest() { CLIENT_PACKETS.forEach(PacketWriteReadTest::testPacket); } diff --git a/src/test/java/net/minestom/server/network/SendablePacketTest.java b/src/test/java/net/minestom/server/network/SendablePacketTest.java index c7d046a6c5e..c9744ddeb31 100644 --- a/src/test/java/net/minestom/server/network/SendablePacketTest.java +++ b/src/test/java/net/minestom/server/network/SendablePacketTest.java @@ -11,10 +11,10 @@ import static org.junit.jupiter.api.Assertions.*; -public class SendablePacketTest { +class SendablePacketTest { @Test - public void lazy() { + void lazy() { var packet = new SystemChatPacket(Component.text("Hello World!"), false); AtomicBoolean called = new AtomicBoolean(false); var lazy = new LazyPacket(() -> { @@ -27,7 +27,7 @@ public void lazy() { } @Test - public void cached() { + void cached() { var packet = new SystemChatPacket(Component.text("Hello World!"), false); var cached = new CachedPacket(packet); assertSame(packet, cached.packet(ConnectionState.PLAY)); diff --git a/src/test/java/net/minestom/server/network/SocketReadTest.java b/src/test/java/net/minestom/server/network/SocketReadTest.java index 4c8db097022..0b97ff1b1ec 100644 --- a/src/test/java/net/minestom/server/network/SocketReadTest.java +++ b/src/test/java/net/minestom/server/network/SocketReadTest.java @@ -16,11 +16,11 @@ import static org.junit.jupiter.api.Assertions.*; -public class SocketReadTest { +class SocketReadTest { @ParameterizedTest @ValueSource(booleans = {false, true}) - public void complete(boolean compressed) throws DataFormatException { + void complete(boolean compressed) throws DataFormatException { var packet = new ClientPluginMessagePacket("channel", new byte[2000]); var buffer = ObjectPool.PACKET_POOL.get(); @@ -44,7 +44,7 @@ public void complete(boolean compressed) throws DataFormatException { @ParameterizedTest @ValueSource(booleans = {false, true}) - public void completeTwo(boolean compressed) throws DataFormatException { + void completeTwo(boolean compressed) throws DataFormatException { var packet = new ClientPluginMessagePacket("channel", new byte[2000]); var buffer = ObjectPool.PACKET_POOL.get(); @@ -70,7 +70,7 @@ public void completeTwo(boolean compressed) throws DataFormatException { @ParameterizedTest @ValueSource(booleans = {false, true}) - public void insufficientLength(boolean compressed) throws DataFormatException { + void insufficientLength(boolean compressed) throws DataFormatException { // Write a complete packet then the next packet length without any payload var packet = new ClientPluginMessagePacket("channel", new byte[2000]); @@ -98,7 +98,7 @@ public void insufficientLength(boolean compressed) throws DataFormatException { @ParameterizedTest @ValueSource(booleans = {false, true}) - public void incomplete(boolean compressed) throws DataFormatException { + void incomplete(boolean compressed) throws DataFormatException { // Write a complete packet and incomplete var-int length for the next packet var packet = new ClientPluginMessagePacket("channel", new byte[2000]); diff --git a/src/test/java/net/minestom/server/network/SocketWriteTest.java b/src/test/java/net/minestom/server/network/SocketWriteTest.java index bcaadeade4d..cb450e32e59 100644 --- a/src/test/java/net/minestom/server/network/SocketWriteTest.java +++ b/src/test/java/net/minestom/server/network/SocketWriteTest.java @@ -14,7 +14,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; -public class SocketWriteTest { +class SocketWriteTest { record IntPacket(int value) implements ServerPacket.Play { @Override @@ -41,7 +41,7 @@ public int playId() { } @Test - public void writeSingleUncompressed() { + void writeSingleUncompressed() { var packet = new IntPacket(5); var buffer = ObjectPool.PACKET_POOL.get(); @@ -53,7 +53,7 @@ public void writeSingleUncompressed() { } @Test - public void writeMultiUncompressed() { + void writeMultiUncompressed() { var packet = new IntPacket(5); var buffer = ObjectPool.PACKET_POOL.get(); @@ -66,7 +66,7 @@ public void writeMultiUncompressed() { } @Test - public void writeSingleCompressed() { + void writeSingleCompressed() { var string = "Hello world!".repeat(200); var stringLength = string.getBytes(StandardCharsets.UTF_8).length; var lengthLength = Utils.getVarIntSize(stringLength); @@ -82,7 +82,7 @@ public void writeSingleCompressed() { } @Test - public void writeSingleCompressedSmall() { + void writeSingleCompressedSmall() { var packet = new IntPacket(5); var buffer = ObjectPool.PACKET_POOL.get(); @@ -94,7 +94,7 @@ public void writeSingleCompressedSmall() { } @Test - public void writeMultiCompressedSmall() { + void writeMultiCompressedSmall() { var packet = new IntPacket(5); var buffer = ObjectPool.PACKET_POOL.get(); diff --git a/src/test/java/net/minestom/server/network/packet/UpdateEnabledFeaturesPacketTest.java b/src/test/java/net/minestom/server/network/packet/UpdateEnabledFeaturesPacketTest.java new file mode 100644 index 00000000000..b7f8406cb7c --- /dev/null +++ b/src/test/java/net/minestom/server/network/packet/UpdateEnabledFeaturesPacketTest.java @@ -0,0 +1,60 @@ +package net.minestom.server.network.packet; + +import net.minestom.server.network.NetworkBuffer; +import net.minestom.server.network.packet.server.ServerPacketIdentifier; +import net.minestom.server.network.packet.server.configuration.UpdateEnabledFeaturesPacket; +import net.minestom.server.utils.NamespaceID; +import org.junit.jupiter.api.Test; + +import java.util.HashSet; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.*; + +class UpdateEnabledFeaturesPacketTest { + + @Test + void constructorWithBufferReadsCorrectly() { + NetworkBuffer buffer = new NetworkBuffer(); + UpdateEnabledFeaturesPacket updateEnabledFeaturesPacket = new UpdateEnabledFeaturesPacket(Set.of(NamespaceID.from("namespace:feature1"), NamespaceID.from("namespace:feature2"))); + updateEnabledFeaturesPacket.write(buffer); + UpdateEnabledFeaturesPacket packet = new UpdateEnabledFeaturesPacket(buffer); + + assertEquals(2, packet.features().size()); + assertTrue(packet.features().contains(NamespaceID.from("namespace:feature1"))); + assertTrue(packet.features().contains(NamespaceID.from("namespace:feature2"))); + } + + + @Test + void configurationIdReturnsCorrectId() { + UpdateEnabledFeaturesPacket packet = new UpdateEnabledFeaturesPacket(Set.of()); + assertEquals(ServerPacketIdentifier.CONFIGURATION_UPDATE_ENABLED_FEATURES, packet.configurationId()); + } + + @Test + void constructorWithBufferHandlesEmptySet() { + NetworkBuffer buffer = new NetworkBuffer(); + UpdateEnabledFeaturesPacket updateEnabledFeaturesPacket = new UpdateEnabledFeaturesPacket(Set.of()); + updateEnabledFeaturesPacket.write(buffer); + + UpdateEnabledFeaturesPacket packet = new UpdateEnabledFeaturesPacket(buffer); + + assertTrue(packet.features().isEmpty()); + } + + @Test + void constructorWithBufferHandlesMaxFeatures() { + Set maxFeatures = new HashSet<>(); + for (int i = 0; i < UpdateEnabledFeaturesPacket.MAX_FEATURES; i++) { + maxFeatures.add(NamespaceID.from("namespace:feature" + i)); + } + NetworkBuffer buffer = new NetworkBuffer(); + UpdateEnabledFeaturesPacket updateEnabledFeaturesPacket = new UpdateEnabledFeaturesPacket(maxFeatures); + updateEnabledFeaturesPacket.write(buffer); + + UpdateEnabledFeaturesPacket packet = new UpdateEnabledFeaturesPacket(buffer); + + assertEquals(UpdateEnabledFeaturesPacket.MAX_FEATURES, packet.features().size()); + } +} \ No newline at end of file diff --git a/src/test/java/net/minestom/server/network/socket/ServerAddressTest.java b/src/test/java/net/minestom/server/network/socket/ServerAddressTest.java index e3d5357e812..49dec17a054 100644 --- a/src/test/java/net/minestom/server/network/socket/ServerAddressTest.java +++ b/src/test/java/net/minestom/server/network/socket/ServerAddressTest.java @@ -11,11 +11,12 @@ import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; -public class ServerAddressTest { +class ServerAddressTest { @Test - public void inetAddressTest() throws IOException { + void inetAddressTest() throws IOException { // These like to fail on github actions assumeTrue(System.getenv("GITHUB_ACTIONS") == null); @@ -31,7 +32,7 @@ public void inetAddressTest() throws IOException { } @Test - public void inetAddressDynamicTest() throws IOException { + void inetAddressDynamicTest() throws IOException { // These like to fail on github actions assumeTrue(System.getenv("GITHUB_ACTIONS") == null); @@ -47,7 +48,7 @@ public void inetAddressDynamicTest() throws IOException { } @Test - public void unixAddressTest() throws IOException { + void unixAddressTest() throws IOException { // These like to fail on github actions assumeTrue(System.getenv("GITHUB_ACTIONS") == null); @@ -65,7 +66,7 @@ public void unixAddressTest() throws IOException { } @Test - public void noAddressTest() throws IOException { + void noAddressTest() throws IOException { var server = new Server(new PacketProcessor(new PacketListenerManager())); assertDoesNotThrow(server::stop); } diff --git a/src/test/java/net/minestom/server/notifications/NotificationIntegrationTest.java b/src/test/java/net/minestom/server/notifications/NotificationIntegrationTest.java new file mode 100644 index 00000000000..4ef269bf024 --- /dev/null +++ b/src/test/java/net/minestom/server/notifications/NotificationIntegrationTest.java @@ -0,0 +1,59 @@ +package net.minestom.server.notifications; + +import net.kyori.adventure.text.Component; +import net.minestom.server.advancements.FrameType; +import net.minestom.server.coordinate.Pos; +import net.minestom.server.item.ItemStack; +import net.minestom.server.item.Material; +import net.minestom.server.network.packet.server.play.AdvancementsPacket; +import net.minestom.testing.Collector; +import net.minestom.testing.Env; +import net.minestom.testing.extension.MicrotusExtension; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +@ExtendWith(MicrotusExtension.class) +class NotificationIntegrationTest { + + @Test + void testBuilder() { + var notification = Notification.builder() + .icon(Material.ITEM_FRAME) + .title(Component.text("unit test")) + .frameType(FrameType.TASK) + .build(); + assertEquals(FrameType.TASK, notification.type()); + assertEquals(ItemStack.of(Material.ITEM_FRAME), notification.icon()); + assertEquals(Component.text("unit test"), notification.title()); + } + + @Test + void testSend(Env env) { + var instance = env.createFlatInstance(); + var connection = env.createConnection(); + Collector advancementsPacketCollector = connection.trackIncoming(AdvancementsPacket.class); + var player = connection.connect(instance, new Pos(0, 42, 0)).join(); + var notification = Notification.builder() + .icon(Material.ITEM_FRAME) + .title(Component.text("unit test")) + .frameType(FrameType.TASK) + .build(); + notification.send(player); + advancementsPacketCollector.assertCount(2); + AdvancementsPacket advancementsPacket = advancementsPacketCollector.collect().get(1); + assertNotNull(advancementsPacket); + Optional advancementMapping = advancementsPacket.advancementMappings().stream().findFirst(); + advancementMapping.ifPresent(advancementMapping1 -> { + AdvancementsPacket.Advancement advancement = advancementMapping1.value(); + assertFalse(advancement.sendTelemetryData()); + var displayData = advancement.displayData(); + assertEquals(ItemStack.of(Material.ITEM_FRAME), displayData.icon()); + assertEquals(Component.text("unit test"), displayData.title()); + assertEquals(FrameType.TASK, displayData.frameType()); + }); + } +} diff --git a/src/test/java/net/minestom/server/permission/TestPermissions.java b/src/test/java/net/minestom/server/permission/TestPermissions.java index f6bcde9c641..5df1d985ac9 100644 --- a/src/test/java/net/minestom/server/permission/TestPermissions.java +++ b/src/test/java/net/minestom/server/permission/TestPermissions.java @@ -14,14 +14,14 @@ import static org.junit.jupiter.api.Assertions.assertTrue; // TODO: more tests -public class TestPermissions { +class TestPermissions { private Player player; private Permission permission1, permission2, permission3, wildcard; @BeforeEach - public void init() { + void init() { MinecraftServer.init(); // for entity manager player = new Player(UUID.randomUUID(), "TestPlayer", null) { @Override @@ -49,13 +49,13 @@ public boolean isOnline() { } @Test - public void noPermission() { + void noPermission() { assertFalse(player.hasPermission("")); assertFalse(player.hasPermission("random.permission")); } @Test - public void hasPermissionClass() { + void hasPermissionClass() { assertFalse(player.hasPermission(permission1)); player.addPermission(permission1); @@ -67,7 +67,7 @@ public void hasPermissionClass() { } @Test - public void hasPermissionNameNbt() { + void hasPermissionNameNbt() { player.addPermission(permission1); assertTrue(player.hasPermission("perm.name")); assertTrue(player.hasPermission("perm.name", @@ -81,7 +81,7 @@ public void hasPermissionNameNbt() { } @Test - public void hasPatternMatchingWildcard() { + void hasPatternMatchingWildcard() { Permission permission = new Permission("foo.b*r.baz"); Permission match = new Permission("foo.baaar.baz"); Permission match2 = new Permission("foo.br.baz"); @@ -105,7 +105,7 @@ public void hasPatternMatchingWildcard() { } @Test - public void hasPermissionWildcard() { + void hasPermissionWildcard() { Permission permission = new Permission("foo.b*"); Permission match = new Permission("foo.baaar.baz"); Permission match2 = new Permission("foo.b"); @@ -129,7 +129,7 @@ public void hasPermissionWildcard() { } @Test - public void hasAllPermissionsWithWildcard() { + void hasAllPermissionsWithWildcard() { assertFalse(player.hasPermission(permission2)); assertFalse(player.hasPermission(permission3)); player.addPermission(wildcard); @@ -138,7 +138,7 @@ public void hasAllPermissionsWithWildcard() { } @AfterEach - public void cleanup() { + void cleanup() { } } diff --git a/src/test/java/net/minestom/server/snapshot/ChunkSnapshotIntegrationTest.java b/src/test/java/net/minestom/server/snapshot/ChunkSnapshotIntegrationTest.java index 6f0809d0cba..ddf7ba0ec57 100644 --- a/src/test/java/net/minestom/server/snapshot/ChunkSnapshotIntegrationTest.java +++ b/src/test/java/net/minestom/server/snapshot/ChunkSnapshotIntegrationTest.java @@ -1,17 +1,18 @@ package net.minestom.server.snapshot; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.instance.block.Block; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest -public class ChunkSnapshotIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class ChunkSnapshotIntegrationTest { @Test - public void blocks(Env env) { + void blocks(Env env) { var instance = env.createFlatInstance(); instance.setBlock(0, 0, 0, Block.STONE); var snapshot = ServerSnapshot.update(); diff --git a/src/test/java/net/minestom/server/snapshot/EntitySnapshotIntegrationTest.java b/src/test/java/net/minestom/server/snapshot/EntitySnapshotIntegrationTest.java index 734b3c88892..a0e0d67920c 100644 --- a/src/test/java/net/minestom/server/snapshot/EntitySnapshotIntegrationTest.java +++ b/src/test/java/net/minestom/server/snapshot/EntitySnapshotIntegrationTest.java @@ -1,19 +1,20 @@ package net.minestom.server.snapshot; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.entity.Entity; import net.minestom.server.entity.EntityType; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -@EnvTest -public class EntitySnapshotIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class EntitySnapshotIntegrationTest { @Test - public void basic(Env env) { + void basic(Env env) { var instance = env.createFlatInstance(); var ent = new Entity(EntityType.ZOMBIE); ent.setInstance(instance).join(); diff --git a/src/test/java/net/minestom/server/snapshot/InstanceSnapshotIntegrationTest.java b/src/test/java/net/minestom/server/snapshot/InstanceSnapshotIntegrationTest.java index 7863e30ea16..3939ec7a9a6 100644 --- a/src/test/java/net/minestom/server/snapshot/InstanceSnapshotIntegrationTest.java +++ b/src/test/java/net/minestom/server/snapshot/InstanceSnapshotIntegrationTest.java @@ -1,16 +1,17 @@ package net.minestom.server.snapshot; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertEquals; -@EnvTest -public class InstanceSnapshotIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class InstanceSnapshotIntegrationTest { @Test - public void basic(Env env) { + void basic(Env env) { env.createFlatInstance(); var snapshot = ServerSnapshot.update(); diff --git a/src/test/java/net/minestom/server/tag/TagComponentTest.java b/src/test/java/net/minestom/server/tag/TagComponentTest.java index 44c126e1795..55a37fd275d 100644 --- a/src/test/java/net/minestom/server/tag/TagComponentTest.java +++ b/src/test/java/net/minestom/server/tag/TagComponentTest.java @@ -6,10 +6,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -public class TagComponentTest { +class TagComponentTest { @Test - public void get() { + void get() { var component = Component.text("Hey"); var tag = Tag.Component("component"); var handler = TagHandler.newHandler(); @@ -18,14 +18,14 @@ public void get() { } @Test - public void empty() { + void empty() { var tag = Tag.Component("component"); var handler = TagHandler.newHandler(); assertNull(handler.getTag(tag)); } @Test - public void invalidTag() { + void invalidTag() { var tag = Tag.Component("entry"); var handler = TagHandler.newHandler(); handler.setTag(Tag.Integer("entry"), 1); @@ -33,7 +33,7 @@ public void invalidTag() { } @Test - public void nbtFallback() { + void nbtFallback() { var component = Component.text("Hey"); var tag = Tag.Component("component"); var handler = TagHandler.newHandler(); diff --git a/src/test/java/net/minestom/server/tag/TagEqualityTest.java b/src/test/java/net/minestom/server/tag/TagEqualityTest.java index 79905d4ee8e..5bba1cbbbc7 100644 --- a/src/test/java/net/minestom/server/tag/TagEqualityTest.java +++ b/src/test/java/net/minestom/server/tag/TagEqualityTest.java @@ -5,10 +5,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; -public class TagEqualityTest { +class TagEqualityTest { @Test - public void sameType() { + void sameType() { var tag1 = Tag.Integer("key"); var tag2 = Tag.Integer("key"); assertEquals(tag1, tag1); @@ -17,49 +17,49 @@ public void sameType() { } @Test - public void differentKey() { + void differentKey() { var tag1 = Tag.Integer("key1"); var tag2 = Tag.Integer("key2"); assertNotEquals(tag1, tag2); } @Test - public void sameList() { + void sameList() { var tag1 = Tag.Integer("key").list(); var tag2 = Tag.Integer("key").list(); assertEquals(tag1, tag2); } @Test - public void differentList() { + void differentList() { var tag1 = Tag.Integer("key").list(); var tag2 = Tag.Integer("key"); assertNotEquals(tag1, tag2); } @Test - public void unmatchedList() { + void unmatchedList() { var tag1 = Tag.Integer("key").list().list(); var tag2 = Tag.Integer("key").list(); assertNotEquals(tag1, tag2); } @Test - public void samePath() { + void samePath() { var tag1 = Tag.Integer("key").path("path"); var tag2 = Tag.Integer("key").path("path"); assertEquals(tag1, tag2); } @Test - public void differentPath() { + void differentPath() { var tag1 = Tag.Integer("key").path("path"); var tag2 = Tag.Integer("key").path("path2"); assertNotEquals(tag1, tag2); } @Test - public void unmatchedPath() { + void unmatchedPath() { var tag1 = Tag.Integer("key").path("path", "path2"); var tag2 = Tag.Integer("key").path("path"); assertNotEquals(tag1, tag2); diff --git a/src/test/java/net/minestom/server/tag/TagHandlerCopyTest.java b/src/test/java/net/minestom/server/tag/TagHandlerCopyTest.java index 11b8660c350..aca9523ad96 100644 --- a/src/test/java/net/minestom/server/tag/TagHandlerCopyTest.java +++ b/src/test/java/net/minestom/server/tag/TagHandlerCopyTest.java @@ -6,10 +6,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -public class TagHandlerCopyTest { +class TagHandlerCopyTest { @Test - public void copy() { + void copy() { var handler = TagHandler.newHandler(); handler.setTag(Tag.String("key"), "test"); @@ -18,7 +18,7 @@ public void copy() { } @Test - public void copyCachePath() { + void copyCachePath() { var tag = Tag.String("key").path("path"); var handler = TagHandler.newHandler(); handler.setTag(tag, "test"); @@ -43,7 +43,7 @@ public void copyCachePath() { } @Test - public void copyCache() { + void copyCache() { var tag = Tag.String("key"); var handler = TagHandler.newHandler(); handler.setTag(tag, "test"); @@ -71,7 +71,7 @@ public void copyCache() { } @Test - public void copyRehashing() { + void copyRehashing() { var handler = TagHandler.newHandler(); TagHandler handlerCopy; for (int i = 0; i < 1000; i++) { diff --git a/src/test/java/net/minestom/server/tag/TagHandlerReadableCopyTest.java b/src/test/java/net/minestom/server/tag/TagHandlerReadableCopyTest.java index 90d4a646654..82774de7c00 100644 --- a/src/test/java/net/minestom/server/tag/TagHandlerReadableCopyTest.java +++ b/src/test/java/net/minestom/server/tag/TagHandlerReadableCopyTest.java @@ -6,10 +6,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertSame; -public class TagHandlerReadableCopyTest { +class TagHandlerReadableCopyTest { @Test - public void copyCache() { + void copyCache() { var tag = Tag.String("key"); var handler = TagHandler.newHandler(); handler.setTag(tag, "test"); @@ -23,7 +23,7 @@ public void copyCache() { } @Test - public void copyCachePath() { + void copyCachePath() { var tag = Tag.String("key").path("path"); var handler = TagHandler.newHandler(); handler.setTag(tag, "test"); @@ -38,14 +38,14 @@ public void copyCachePath() { } @Test - public void copyCacheReuse() { + void copyCacheReuse() { var handler = TagHandler.newHandler(); handler.setTag(Tag.String("key"), "test"); assertSame(handler.readableCopy(), handler.readableCopy()); } @Test - public void copyRehashing() { + void copyRehashing() { var tag = Tag.String("key"); var handler = TagHandler.newHandler(); handler.setTag(tag, "test"); diff --git a/src/test/java/net/minestom/server/tag/TagItemTest.java b/src/test/java/net/minestom/server/tag/TagItemTest.java index 688a271ef02..9925d94ce67 100644 --- a/src/test/java/net/minestom/server/tag/TagItemTest.java +++ b/src/test/java/net/minestom/server/tag/TagItemTest.java @@ -11,10 +11,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -public class TagItemTest { +class TagItemTest { @Test - public void get() { + void get() { var item = ItemStack.of(Material.DIAMOND); var tag = Tag.ItemStack("item"); var handler = TagHandler.newHandler(); @@ -24,7 +24,7 @@ public void get() { } @Test - public void getDifferentObject() { + void getDifferentObject() { var item = ItemStack.of(Material.DIAMOND); var handler = TagHandler.newHandler(); handler.setTag(Tag.ItemStack("item"), item); @@ -33,7 +33,7 @@ public void getDifferentObject() { } @Test - public void remove() { + void remove() { var item = ItemStack.of(Material.DIAMOND); var tag = Tag.ItemStack("item"); var handler = TagHandler.newHandler(); @@ -45,7 +45,7 @@ public void remove() { } @Test - public void gc() { + void gc() { var item = ItemStack.of(Material.DIAMOND); var tag = Tag.ItemStack("item"); var handler = TagHandler.newHandler(); @@ -60,7 +60,7 @@ public void gc() { } @Test - public void invalidation() { + void invalidation() { var item = ItemStack.of(Material.DIAMOND); var item2 = ItemStack.of(Material.DIAMOND, 2); var handler = TagHandler.newHandler(); @@ -73,7 +73,7 @@ public void invalidation() { } @Test - public void differentTagInvalidation() { + void differentTagInvalidation() { var item = ItemStack.of(Material.DIAMOND); var item2 = ItemStack.of(Material.DIAMOND, 2); var handler = TagHandler.newHandler(); @@ -95,7 +95,7 @@ public void differentTagInvalidation() { } @Test - public void snbt() { + void snbt() { var handler = TagHandler.newHandler(); var tag = Tag.ItemStack("item"); handler.setTag(tag, ItemStack.of(Material.DIAMOND)); diff --git a/src/test/java/net/minestom/server/tag/TagListTest.java b/src/test/java/net/minestom/server/tag/TagListTest.java index 28ba07d2c86..ae025e28379 100644 --- a/src/test/java/net/minestom/server/tag/TagListTest.java +++ b/src/test/java/net/minestom/server/tag/TagListTest.java @@ -9,10 +9,10 @@ import static net.minestom.testing.TestUtils.assertEqualsSNBT; import static org.junit.jupiter.api.Assertions.*; -public class TagListTest { +class TagListTest { @Test - public void basic() { + void basic() { var handler = TagHandler.newHandler(); Tag tag = Tag.Integer("number"); Tag> list = tag.list(); @@ -27,7 +27,7 @@ public void basic() { } @Test - public void cache() { + void cache() { var handler = TagHandler.newHandler(); var tag = Tag.Integer("number").list(); var val = List.of(1, 2, 3); @@ -37,7 +37,7 @@ public void cache() { } @Test - public void recursiveCache() { + void recursiveCache() { var handler = TagHandler.newHandler(); var tag = Tag.Integer("number").list().list(); var val = List.of(List.of(1, 2, 3), List.of(4, 5, 6)); @@ -49,7 +49,7 @@ public void recursiveCache() { } @Test - public void recursiveCacheIncorrect() { + void recursiveCacheIncorrect() { var handler = TagHandler.newHandler(); var tag = Tag.Integer("number").list().list(); var val = List.of(List.of(1, 2, 3), new ArrayList<>(Arrays.asList(4, 5, 6))); @@ -62,7 +62,7 @@ public void recursiveCacheIncorrect() { } @Test - public void snbt() { + void snbt() { var handler = TagHandler.newHandler(); Tag> tag = Tag.Integer("numbers").list(); @@ -75,7 +75,7 @@ public void snbt() { } @Test - public void empty() { + void empty() { var handler = TagHandler.newHandler(); Tag> tag = Tag.Integer("numbers").list(); handler.setTag(tag, List.of()); @@ -83,7 +83,7 @@ public void empty() { } @Test - public void emptySnbt() { + void emptySnbt() { var handler = TagHandler.newHandler(); Tag> tag = Tag.Integer("numbers").list(); handler.setTag(tag, List.of()); @@ -95,7 +95,7 @@ public void emptySnbt() { } @Test - public void removal() { + void removal() { var handler = TagHandler.newHandler(); Tag> tag = Tag.Integer("numbers").list(); handler.setTag(tag, List.of(1)); @@ -105,7 +105,7 @@ public void removal() { } @Test - public void removalSnbt() { + void removalSnbt() { var handler = TagHandler.newHandler(); Tag> tag = Tag.Integer("numbers").list(); handler.setTag(tag, List.of(1)); @@ -119,7 +119,7 @@ public void removalSnbt() { } @Test - public void chaining() { + void chaining() { var handler = TagHandler.newHandler(); Tag>> tag = Tag.Integer("numbers").list().list(); var integers = List.of(List.of(1, 2, 3), List.of(4, 5, 6)); @@ -130,7 +130,7 @@ public void chaining() { } @Test - public void chainingSnbt() { + void chainingSnbt() { var handler = TagHandler.newHandler(); Tag>> tag = Tag.Integer("numbers").list().list(); var integers = List.of(List.of(1, 2, 3), List.of(4, 5, 6)); @@ -148,7 +148,7 @@ public void chainingSnbt() { } @Test - public void defaultValue() { + void defaultValue() { var handler = TagHandler.newHandler(); var val = List.of(1, 2, 3); var tag = Tag.Integer("number").list().defaultValue(val); @@ -156,7 +156,7 @@ public void defaultValue() { } @Test - public void defaultValueReset() { + void defaultValueReset() { var handler = TagHandler.newHandler(); var tag = Tag.Integer("number").defaultValue(5); var list = tag.list(); @@ -165,7 +165,7 @@ public void defaultValueReset() { } @Test - public void immutability() { + void immutability() { var handler = TagHandler.newHandler(); var tag = Tag.Integer("number").list(); List val = new ArrayList<>(); @@ -181,7 +181,7 @@ public void immutability() { } @Test - public void chainingImmutability() { + void chainingImmutability() { var handler = TagHandler.newHandler(); Tag>> tag = Tag.Integer("numbers").list().list(); List> val = new ArrayList<>(); @@ -201,7 +201,7 @@ public void chainingImmutability() { } @Test - public void immutabilitySnbt() { + void immutabilitySnbt() { var handler = TagHandler.newHandler(); var tag = Tag.Integer("numbers").list(); List val = new ArrayList<>(); @@ -223,7 +223,7 @@ public void immutabilitySnbt() { } @Test - public void chainingImmutabilitySnbt() { + void chainingImmutabilitySnbt() { var handler = TagHandler.newHandler(); Tag>> tag = Tag.Integer("numbers").list().list(); List> val = new ArrayList<>(); diff --git a/src/test/java/net/minestom/server/tag/TagMapTest.java b/src/test/java/net/minestom/server/tag/TagMapTest.java index 08595008d38..c2ea9ead15f 100644 --- a/src/test/java/net/minestom/server/tag/TagMapTest.java +++ b/src/test/java/net/minestom/server/tag/TagMapTest.java @@ -5,13 +5,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -public class TagMapTest { +class TagMapTest { private record Entry(int value) { } @Test - public void map() { + void map() { var handler = TagHandler.newHandler(); var intTag = Tag.Integer("key"); var tag = intTag.map(Entry::new, Entry::value); @@ -22,7 +22,7 @@ public void map() { } @Test - public void mapDefault() { + void mapDefault() { var handler = TagHandler.newHandler(); var intTag = Tag.Integer("key"); var tag = intTag.map(Entry::new, Entry::value); @@ -35,7 +35,7 @@ public void mapDefault() { } @Test - public void mapDefaultAbsent() { + void mapDefaultAbsent() { var handler = TagHandler.newHandler(); var tag = Tag.Integer("key").map(Entry::new, Entry::value); assertNull(handler.getTag(tag)); diff --git a/src/test/java/net/minestom/server/tag/TagNbtSeparatorTest.java b/src/test/java/net/minestom/server/tag/TagNbtSeparatorTest.java index 17ff99ad5e6..42f36199e25 100644 --- a/src/test/java/net/minestom/server/tag/TagNbtSeparatorTest.java +++ b/src/test/java/net/minestom/server/tag/TagNbtSeparatorTest.java @@ -9,10 +9,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -public class TagNbtSeparatorTest { +class TagNbtSeparatorTest { @Test - public void primitives() { + void primitives() { assertSeparation(new TagNbtSeparator.Entry<>(Tag.Byte("key"), (byte) 1), "key", ByteBinaryTag.byteBinaryTag((byte) 1)); assertSeparation(new TagNbtSeparator.Entry<>(Tag.Short("key"), (short) 1), @@ -28,20 +28,20 @@ public void primitives() { } @Test - public void compound() { + void compound() { assertSeparation(new TagNbtSeparator.Entry<>(Tag.Byte("key").path("path"), (byte) 1), "path", CompoundBinaryTag.builder().putByte("key", (byte) 1).build()); } @Test - public void compoundMultiple() { + void compoundMultiple() { assertSeparation(Set.of(new TagNbtSeparator.Entry<>(Tag.Byte("key").path("path"), (byte) 1), new TagNbtSeparator.Entry<>(Tag.Integer("key2").path("path"), 2)), "path", CompoundBinaryTag.builder().putByte("key", (byte) 1).putInt("key2", 2).build()); } @Test - public void list() { + void list() { assertSeparation(new TagNbtSeparator.Entry<>(Tag.Integer("key").list(), List.of(1)), "key", ListBinaryTag.listBinaryTag(BinaryTagTypes.INT, List.of(IntBinaryTag.intBinaryTag(1)))); } diff --git a/src/test/java/net/minestom/server/tag/TagPathTest.java b/src/test/java/net/minestom/server/tag/TagPathTest.java index 67fcdcbcc3c..53d6ade4e24 100644 --- a/src/test/java/net/minestom/server/tag/TagPathTest.java +++ b/src/test/java/net/minestom/server/tag/TagPathTest.java @@ -7,10 +7,10 @@ import static net.minestom.testing.TestUtils.assertEqualsSNBT; import static org.junit.jupiter.api.Assertions.*; -public class TagPathTest { +class TagPathTest { @Test - public void basic() { + void basic() { var handler = TagHandler.newHandler(); var tag = Tag.Integer("number"); var path = tag.path("display"); @@ -28,13 +28,13 @@ public void basic() { } @Test - public void invalidPath() { + void invalidPath() { assertThrows(IllegalArgumentException.class, () -> Tag.Integer("number").path("")); assertThrows(IllegalArgumentException.class, () -> Tag.Integer("number").path("path", null)); } @Test - public void emptyRemoval() { + void emptyRemoval() { var handler = TagHandler.newHandler(); var tag = Tag.Integer("number").path("display"); handler.removeTag(tag); @@ -43,7 +43,7 @@ public void emptyRemoval() { } @Test - public void snbt() { + void snbt() { var handler = TagHandler.newHandler(); var tag = Tag.Integer("number").path("display"); handler.setTag(tag, 5); @@ -60,7 +60,7 @@ public void snbt() { } @Test - public void doubleSnbt() { + void doubleSnbt() { var handler = TagHandler.newHandler(); var tag = Tag.Integer("number").path("display"); var tag1 = Tag.String("string").path("display"); @@ -90,7 +90,7 @@ public void doubleSnbt() { } @Test - public void secondPathClearSnbt() { + void secondPathClearSnbt() { var handler = TagHandler.newHandler(); var numberTag = Tag.Integer("number").path("path1", "path2"); var stringTag = Tag.String("string").path("path1"); @@ -118,7 +118,7 @@ public void secondPathClearSnbt() { } @Test - public void differentPath() { + void differentPath() { var handler = TagHandler.newHandler(); var tag = Tag.Integer("number"); var path = tag.path("display"); @@ -150,7 +150,7 @@ public void differentPath() { } @Test - public void overrideSnbt() { + void overrideSnbt() { var handler = TagHandler.newHandler(); var tag = Tag.Integer("key"); var tag1 = Tag.Integer("value").path("key"); @@ -172,7 +172,7 @@ public void overrideSnbt() { } @Test - public void forgetPath() { + void forgetPath() { var handler = TagHandler.newHandler(); var tag = Tag.Integer("key"); var path = Tag.Integer("value").path("key"); @@ -181,7 +181,7 @@ public void forgetPath() { } @Test - public void pathInvalidClear() { + void pathInvalidClear() { var handler = TagHandler.newHandler(); var tag1 = Tag.Integer("pathInvalidClear1").path("key"); var tag2 = Tag.Integer("pathInvalidClear2").path("key"); @@ -190,7 +190,7 @@ public void pathInvalidClear() { } @Test - public void chaining() { + void chaining() { var handler = TagHandler.newHandler(); var tag = Tag.Integer("key"); var path = Tag.Integer("key").path("first", "second"); @@ -213,7 +213,7 @@ public void chaining() { } @Test - public void chainingDouble() { + void chainingDouble() { var handler = TagHandler.newHandler(); var path = Tag.Integer("key").path("first", "second"); var path1 = Tag.Integer("key").path("first"); @@ -257,7 +257,7 @@ public void chainingDouble() { } @Test - public void structureObstruction() { + void structureObstruction() { record Entry(int value) { } @@ -311,7 +311,7 @@ public void write(@NotNull TagWritable writer, @NotNull Entry value) { } @Test - public void tagObstruction() { + void tagObstruction() { var handler = TagHandler.newHandler(); var tag = Tag.Integer("key"); var path = Tag.Integer("value").path("key", "second"); diff --git a/src/test/java/net/minestom/server/tag/TagStructureTest.java b/src/test/java/net/minestom/server/tag/TagStructureTest.java index 303d0c3649e..9c8381c5aea 100644 --- a/src/test/java/net/minestom/server/tag/TagStructureTest.java +++ b/src/test/java/net/minestom/server/tag/TagStructureTest.java @@ -10,7 +10,7 @@ import static net.minestom.testing.TestUtils.assertEqualsSNBT; import static org.junit.jupiter.api.Assertions.*; -public class TagStructureTest { +class TagStructureTest { private static final Tag STRUCTURE_TAG = Tag.Structure("entry", new TagSerializer<>() { private static final Tag VALUE_TAG = Tag.String("value"); @@ -46,7 +46,7 @@ private record Entry(String value) { } @Test - public void basic() { + void basic() { var handler = TagHandler.newHandler(); assertNull(handler.getTag(STRUCTURE_TAG)); assertFalse(handler.hasTag(STRUCTURE_TAG)); @@ -62,7 +62,7 @@ public void basic() { } @Test - public void snbt() { + void snbt() { var handler = TagHandler.newHandler(); var entry = new Entry("hello"); handler.setTag(STRUCTURE_TAG, entry); @@ -79,7 +79,7 @@ public void snbt() { } @Test - public void overrideBasic() { + void overrideBasic() { var handler = TagHandler.newHandler(); assertNull(handler.getTag(STRUCTURE_TAG)); assertFalse(handler.hasTag(STRUCTURE_TAG)); @@ -105,7 +105,7 @@ public void overrideBasic() { } @Test - public void overrideNbt() { + void overrideNbt() { var handler = TagHandler.newHandler(); var entry1 = new Entry("hello"); var entry2 = new Entry("hello2"); @@ -134,7 +134,7 @@ public void overrideNbt() { } @Test - public void pathOverride() { + void pathOverride() { var handler = TagHandler.newHandler(); Tag uuidTag = Tag.UUID("Id").path("SkullOwner"); Tag skinTag = Tag.Structure("Properties", new TagSerializer() { diff --git a/src/test/java/net/minestom/server/tag/TagTransientTest.java b/src/test/java/net/minestom/server/tag/TagTransientTest.java index 1dce03d1305..e8fc926f3e3 100644 --- a/src/test/java/net/minestom/server/tag/TagTransientTest.java +++ b/src/test/java/net/minestom/server/tag/TagTransientTest.java @@ -5,10 +5,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; -public class TagTransientTest { +class TagTransientTest { @Test - public void twoTransientTags() { + void twoTransientTags() { var tagHandler = TagHandler.newHandler(); Tag tag1 = Tag.Transient("a"); Tag tag2 = Tag.Transient("b"); @@ -19,7 +19,7 @@ public void twoTransientTags() { } @Test - public void twoTransientTagsEqual() { + void twoTransientTagsEqual() { var tagHandler = TagHandler.newHandler(); Tag tag1 = Tag.Transient("a"); Tag tag2 = Tag.Transient("a"); @@ -30,7 +30,7 @@ public void twoTransientTagsEqual() { } @Test - public void tagHandlerCopyPreservesTransient() { + void tagHandlerCopyPreservesTransient() { var tagHandler = TagHandler.newHandler(); Tag tag = Tag.Transient("a"); tagHandler.setTag(tag, "abcdef"); @@ -41,7 +41,7 @@ public void tagHandlerCopyPreservesTransient() { } @Test - public void asCompoundDoesNotPreserveTransient() { + void asCompoundDoesNotPreserveTransient() { var tagHandler = TagHandler.newHandler(); Tag tag = Tag.Transient("a"); tagHandler.setTag(tag, "abcdef"); diff --git a/src/test/java/net/minestom/server/tag/TagUpdateTest.java b/src/test/java/net/minestom/server/tag/TagUpdateTest.java index 222b875de23..59a64d77c7c 100644 --- a/src/test/java/net/minestom/server/tag/TagUpdateTest.java +++ b/src/test/java/net/minestom/server/tag/TagUpdateTest.java @@ -6,10 +6,10 @@ import static net.minestom.testing.TestUtils.assertEqualsSNBT; import static org.junit.jupiter.api.Assertions.*; -public class TagUpdateTest { +class TagUpdateTest { @Test - public void update() { + void update() { var tag = Tag.Integer("coin"); var handler = TagHandler.newHandler(); handler.updateTag(tag, integer -> { @@ -25,7 +25,7 @@ public void update() { } @Test - public void updateDefault() { + void updateDefault() { var tag = Tag.Integer("coin").defaultValue(25); var handler = TagHandler.newHandler(); handler.updateTag(tag, integer -> { @@ -41,7 +41,7 @@ public void updateDefault() { } @Test - public void updateRemoval() { + void updateRemoval() { var tag = Tag.Integer("coin"); var handler = TagHandler.newHandler(); handler.setTag(tag, 5); @@ -54,7 +54,7 @@ public void updateRemoval() { } @Test - public void updateRemovalPath() { + void updateRemovalPath() { var tag = Tag.Integer("coin").path("path"); var handler = TagHandler.newHandler(); handler.setTag(tag, 5); @@ -67,7 +67,7 @@ public void updateRemovalPath() { } @Test - public void updateAndGet() { + void updateAndGet() { var tag = Tag.Integer("coin"); var handler = TagHandler.newHandler(); var result = handler.updateAndGetTag(tag, integer -> { @@ -83,7 +83,7 @@ public void updateAndGet() { } @Test - public void getAndUpdate() { + void getAndUpdate() { var tag = Tag.Integer("coin"); var handler = TagHandler.newHandler(); var result = handler.getAndUpdateTag(tag, integer -> { @@ -99,7 +99,7 @@ public void getAndUpdate() { } @Test - public void updateHiddenSimilarity() { + void updateHiddenSimilarity() { var tag1 = Tag.Integer("coin"); var tag2 = Tag.Integer("coin").map(i -> i + 1, i -> i - 1); var handler = TagHandler.newHandler(); @@ -110,7 +110,7 @@ public void updateHiddenSimilarity() { } @Test - public void updateStructureConversion() { + void updateStructureConversion() { record Test(int coin) { } @@ -131,7 +131,7 @@ record Test(int coin) { } @Test - public void updateStructureConversionPath() { + void updateStructureConversionPath() { record Test(int coin) { } @@ -152,7 +152,7 @@ record Test(int coin) { } @Test - public void updateStructureConversionPathDouble() { + void updateStructureConversionPathDouble() { record Test(int coin) { } record Structure(Test test) { @@ -176,7 +176,7 @@ record Structure(Test test) { } @Test - public void updateViewConversion() { + void updateViewConversion() { record Test(int coin) { } @@ -194,7 +194,7 @@ record Test(int coin) { } @Test - public void updateIncompatible() { + void updateIncompatible() { var tagI = Tag.Integer("coin"); var tagD = Tag.Double("coin"); var handler = TagHandler.newHandler(); @@ -203,7 +203,7 @@ public void updateIncompatible() { } @Test - public void updateInner() { + void updateInner() { var tag = Tag.Structure("vec", Vec.class); var tagX = Tag.Double("x").path("vec"); var handler = TagHandler.newHandler(); diff --git a/src/test/java/net/minestom/server/tag/TagUuidTest.java b/src/test/java/net/minestom/server/tag/TagUuidTest.java index 0e8d1acde9a..c6793a2b38c 100644 --- a/src/test/java/net/minestom/server/tag/TagUuidTest.java +++ b/src/test/java/net/minestom/server/tag/TagUuidTest.java @@ -7,10 +7,10 @@ import static org.junit.jupiter.api.Assertions.*; -public class TagUuidTest { +class TagUuidTest { @Test - public void get() { + void get() { var uuid = UUID.randomUUID(); var tag = Tag.UUID("uuid"); var handler = TagHandler.newHandler(); @@ -19,14 +19,14 @@ public void get() { } @Test - public void empty() { + void empty() { var tag = Tag.UUID("uuid"); var handler = TagHandler.newHandler(); assertNull(handler.getTag(tag)); } @Test - public void invalidTag() { + void invalidTag() { var tag = Tag.UUID("entry"); var handler = TagHandler.newHandler(); handler.setTag(Tag.Integer("entry"), 1); @@ -34,7 +34,7 @@ public void invalidTag() { } @Test - public void toNbt() { + void toNbt() { var tag = Tag.UUID("uuid"); var handler = TagHandler.newHandler(); handler.setTag(tag, UUID.fromString("9ab8ca63-3d7b-43ba-b805-a20a352dae9c")); @@ -44,7 +44,7 @@ public void toNbt() { } @Test - public void fromNbt() { + void fromNbt() { var tag = Tag.UUID("uuid"); var handler = TagHandler.newHandler(); handler.setTag(Tag.NBT("uuid"), IntArrayBinaryTag.intArrayBinaryTag(-1699165597, 1031488442, -1207590390, 892186268)); diff --git a/src/test/java/net/minestom/server/tag/TagValueShareTest.java b/src/test/java/net/minestom/server/tag/TagValueShareTest.java index bbed3b075d0..b375a45d41a 100644 --- a/src/test/java/net/minestom/server/tag/TagValueShareTest.java +++ b/src/test/java/net/minestom/server/tag/TagValueShareTest.java @@ -11,40 +11,40 @@ /** * Test tags that can share cached values. */ -public class TagValueShareTest { +class TagValueShareTest { record Entry(int value) { } @Test - public void same() { + void same() { var tag = Tag.String("test"); assertTrue(tag.shareValue(tag)); } @Test - public void similar() { + void similar() { var tag = Tag.String("test"); var tag2 = Tag.String("test"); assertTrue(tag.shareValue(tag2)); } @Test - public void differentDefault() { + void differentDefault() { var tag = Tag.String("test").defaultValue("test2"); var tag2 = Tag.String("test").defaultValue("test3"); assertTrue(tag.shareValue(tag2)); } @Test - public void differentType() { + void differentType() { var tag = Tag.String("test"); var tag2 = Tag.Integer("test"); assertFalse(tag.shareValue(tag2)); } @Test - public void mapSame() { + void mapSame() { // Force identical functions Function t1 = Entry::new; Function t2 = Entry::value; @@ -56,26 +56,26 @@ public void mapSame() { } @Test - public void mapChild() { + void mapChild() { var intTag = Tag.Integer("key"); var tag = intTag.map(Entry::new, Entry::value); assertFalse(intTag.shareValue(tag)); } @Test - public void list() { + void list() { var tag = Tag.String("test").list(); assertTrue(tag.shareValue(tag)); } @Test - public void listScope() { + void listScope() { var tag = Tag.String("test"); assertFalse(tag.shareValue(tag.list())); } @Test - public void similarList() { + void similarList() { var tag = Tag.String("test").list(); var tag2 = Tag.String("test").list(); assertTrue(tag.shareValue(tag2)); @@ -83,7 +83,7 @@ public void similarList() { } @Test - public void differentList() { + void differentList() { var tag = Tag.String("test").list(); var tag2 = Tag.String("test").list(); assertFalse(tag.shareValue(tag2.list())); @@ -91,7 +91,7 @@ public void differentList() { } @Test - public void differentListType() { + void differentListType() { var tag = Tag.String("test").list(); var tag2 = Tag.Integer("test").list(); assertFalse(tag.shareValue(tag2)); @@ -99,14 +99,14 @@ public void differentListType() { } @Test - public void recordStructure() { + void recordStructure() { var tag = Tag.Structure("test", Vec.class); var tag2 = Tag.Structure("test", Vec.class); assertTrue(tag.shareValue(tag2)); } @Test - public void recordStructureList() { + void recordStructureList() { var tag = Tag.Structure("test", Vec.class).list(); var tag2 = Tag.Structure("test", Vec.class).list(); assertTrue(tag.shareValue(tag2)); diff --git a/src/test/java/net/minestom/server/tag/TagViewTest.java b/src/test/java/net/minestom/server/tag/TagViewTest.java index 9e532187700..4aff1257e08 100644 --- a/src/test/java/net/minestom/server/tag/TagViewTest.java +++ b/src/test/java/net/minestom/server/tag/TagViewTest.java @@ -8,7 +8,7 @@ import static net.minestom.testing.TestUtils.assertEqualsSNBT; import static org.junit.jupiter.api.Assertions.*; -public class TagViewTest { +class TagViewTest { private static final Tag VIEW_TAG = Tag.View(new TagSerializer<>() { private static final Tag VALUE_TAG = Tag.String("value"); @@ -29,7 +29,7 @@ private record Entry(String value) { } @Test - public void basic() { + void basic() { var handler = TagHandler.newHandler(); assertNull(handler.getTag(VIEW_TAG)); assertFalse(handler.hasTag(VIEW_TAG)); @@ -45,7 +45,7 @@ public void basic() { } @Test - public void snbt() { + void snbt() { var handler = TagHandler.newHandler(); var entry = new Entry("hello"); handler.setTag(VIEW_TAG, entry); @@ -60,7 +60,7 @@ public void snbt() { } @Test - public void snbtOverride() { + void snbtOverride() { var handler = TagHandler.newHandler(); var entry = new Entry("hello"); handler.setTag(VIEW_TAG, entry); @@ -79,7 +79,7 @@ public void snbtOverride() { } @Test - public void empty() { + void empty() { var handler = TagHandler.newHandler(); var tag = Tag.View(new TagSerializer() { @Override @@ -109,7 +109,7 @@ public void write(@NotNull TagWritable writer, @NotNull Entry value) { } @Test - public void path() { + void path() { var handler = TagHandler.newHandler(); var tag = VIEW_TAG.path("path"); assertNull(handler.getTag(tag)); @@ -126,7 +126,7 @@ public void path() { } @Test - public void pathSnbt() { + void pathSnbt() { var handler = TagHandler.newHandler(); var tag = VIEW_TAG.path("path"); var entry = new Entry("hello"); @@ -144,7 +144,7 @@ public void pathSnbt() { } @Test - public void compoundSerializer() { + void compoundSerializer() { var tag = Tag.View(TagSerializer.COMPOUND); var handler = TagHandler.newHandler(); handler.setTag(tag, CompoundBinaryTag.builder().putString("value", "hello").build()); diff --git a/src/test/java/net/minestom/server/thread/AcquirableTest.java b/src/test/java/net/minestom/server/thread/AcquirableTest.java index 4ad821cc2ab..6129c929cec 100644 --- a/src/test/java/net/minestom/server/thread/AcquirableTest.java +++ b/src/test/java/net/minestom/server/thread/AcquirableTest.java @@ -9,10 +9,10 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -public class AcquirableTest { +class AcquirableTest { @Test - public void assignation() { + void assignation() { AtomicReference tickThread = new AtomicReference<>(); Entity entity = new Entity(EntityType.ZOMBIE) { @Override diff --git a/src/test/java/net/minestom/server/thread/ThreadDispatcherTest.java b/src/test/java/net/minestom/server/thread/ThreadDispatcherTest.java index 00f7b48addb..d9de83b15b8 100644 --- a/src/test/java/net/minestom/server/thread/ThreadDispatcherTest.java +++ b/src/test/java/net/minestom/server/thread/ThreadDispatcherTest.java @@ -14,10 +14,10 @@ import static org.junit.jupiter.api.Assertions.*; -public class ThreadDispatcherTest { +class ThreadDispatcherTest { @Test - public void elementTick() { + void elementTick() { final AtomicInteger counter = new AtomicInteger(); ThreadDispatcher dispatcher = ThreadDispatcher.singleThread(); assertEquals(1, dispatcher.threads().size()); @@ -45,7 +45,7 @@ public void elementTick() { } @Test - public void partitionTick() { + void partitionTick() { // Partitions implementing Tickable should be ticked same as elements final AtomicInteger counter1 = new AtomicInteger(); final AtomicInteger counter2 = new AtomicInteger(); @@ -74,7 +74,7 @@ public void partitionTick() { } @Test - public void uniqueThread() { + void uniqueThread() { // Ensure that partitions are properly dispatched across threads final int threadCount = 10; ThreadDispatcher dispatcher = ThreadDispatcher.of(ThreadProvider.counter(), threadCount); @@ -103,7 +103,7 @@ public void uniqueThread() { } @Test - public void threadUpdate() { + void threadUpdate() { // Ensure that partitions threads are properly updated every tick // when RefreshType.ALWAYS is used interface Updater extends Tickable { diff --git a/src/test/java/net/minestom/server/utils/ChunkUtilsTest.java b/src/test/java/net/minestom/server/utils/ChunkUtilsTest.java index 5327ad0533a..c6d314ab4f1 100644 --- a/src/test/java/net/minestom/server/utils/ChunkUtilsTest.java +++ b/src/test/java/net/minestom/server/utils/ChunkUtilsTest.java @@ -9,11 +9,11 @@ import java.util.*; import java.util.stream.Stream; -public class ChunkUtilsTest { +class ChunkUtilsTest { @ParameterizedTest @MethodSource("testForDifferingChunksInRangeParams") - public void testForDifferingChunksInRange(int nx, int nz, int ox, int oz, int r) { + void testForDifferingChunksInRange(int nx, int nz, int ox, int oz, int r) { final Set n = new HashSet<>(); final Set o = new HashSet<>(); ChunkUtils.forChunksInRange(nx, nz, r, (x, z) -> n.add(new ChunkCoordinate(x, z))); diff --git a/src/test/java/net/minestom/server/utils/NamespaceIDTest.java b/src/test/java/net/minestom/server/utils/NamespaceIDTest.java index 01783c5089c..6ed987c3947 100644 --- a/src/test/java/net/minestom/server/utils/NamespaceIDTest.java +++ b/src/test/java/net/minestom/server/utils/NamespaceIDTest.java @@ -5,10 +5,10 @@ import static org.junit.jupiter.api.Assertions.*; -public class NamespaceIDTest { +class NamespaceIDTest { @Test - public void init() { + void init() { var namespace = NamespaceID.from("minecraft:any"); assertEquals("minecraft", namespace.domain()); assertEquals("any", namespace.path()); @@ -21,7 +21,7 @@ public void init() { } @Test - public void equals() { + void equals() { var namespace = NamespaceID.from("minecraft:any"); assertEquals(namespace, NamespaceID.from("minecraft:any")); assertNotEquals(namespace, NamespaceID.from("minecraft:any2")); @@ -29,7 +29,7 @@ public void equals() { } @Test - public void hashCodeConsistentWithEquals() { + void hashCodeConsistentWithEquals() { var namespace = NamespaceID.from("minecraft:any"); var key = Key.key("minecraft:any"); @@ -38,50 +38,50 @@ public void hashCodeConsistentWithEquals() { } @Test - public void atMostOneColon() { + void atMostOneColon() { assertThrows(AssertionError.class, () -> NamespaceID.from("minecraft:block:wool")); } @Test - public void noSlashInDomain() { + void noSlashInDomain() { assertThrows(AssertionError.class, () -> NamespaceID.from("minecraft/java_edition:any")); } @Test - public void noDotInDomain() { + void noDotInDomain() { assertThrows(AssertionError.class, () -> NamespaceID.from("minecraft.java:game")); } @Test - public void noUppercase() { + void noUppercase() { assertThrows(AssertionError.class, () -> NamespaceID.from("Minecraft:any")); assertThrows(AssertionError.class, () -> NamespaceID.from("minecraft:Any")); } @Test - public void noSpace() { + void noSpace() { assertThrows(AssertionError.class, () -> NamespaceID.from("minecraft:a n y")); } @Test - public void onlyLatinLowercase() { + void onlyLatinLowercase() { assertThrows(AssertionError.class, () -> NamespaceID.from("Minecraft:voilà")); assertThrows(AssertionError.class, () -> NamespaceID.from("minecraft:où_ça")); assertThrows(AssertionError.class, () -> NamespaceID.from("minecraft:schrödingers_var")); } @Test - public void numbersAllowed() { + void numbersAllowed() { NamespaceID.from("0xc1:468786471"); } @Test - public void dotAllowedInPath() { + void dotAllowedInPath() { NamespaceID.from("minecraft:ambient.cave"); } @Test - public void slashAllowedInPath() { + void slashAllowedInPath() { NamespaceID.from("minecraft:textures/blocks/dirt.png"); } } diff --git a/src/test/java/net/minestom/server/utils/ObjectPoolTest.java b/src/test/java/net/minestom/server/utils/ObjectPoolTest.java index 42c8557addf..d3dc473514d 100644 --- a/src/test/java/net/minestom/server/utils/ObjectPoolTest.java +++ b/src/test/java/net/minestom/server/utils/ObjectPoolTest.java @@ -8,10 +8,10 @@ import static org.junit.jupiter.api.Assertions.*; -public class ObjectPoolTest { +class ObjectPoolTest { @Test - public void pool() { + void pool() { var pool = ObjectPool.BUFFER_POOL; Set pooledBuffers = new HashSet<>(); pool.clear(); @@ -31,7 +31,7 @@ public void pool() { } @Test - public void autoClose() { + void autoClose() { var pool = ObjectPool.BUFFER_POOL; assertEquals(0, pool.count()); try (var ignored = pool.hold()) { diff --git a/src/test/java/net/minestom/server/utils/PositionUtilsTest.java b/src/test/java/net/minestom/server/utils/PositionUtilsTest.java index 888bee67eda..aeba8005db9 100644 --- a/src/test/java/net/minestom/server/utils/PositionUtilsTest.java +++ b/src/test/java/net/minestom/server/utils/PositionUtilsTest.java @@ -5,10 +5,10 @@ import static org.junit.jupiter.api.Assertions.*; -public class PositionUtilsTest { +class PositionUtilsTest { @Test - public void yaw() { + void yaw() { float plusX = PositionUtils.getLookYaw(10, 0); assertEquals(-90, plusX, 1E-5); @@ -34,7 +34,7 @@ public void yaw() { } @Test - public void highPitch() { + void highPitch() { float high = PositionUtils.getLookPitch(0, 999999, 0); assertEquals(-90, high, 1E-5); diff --git a/src/test/java/net/minestom/server/utils/TranslationIntegrationTest.java b/src/test/java/net/minestom/server/utils/TranslationIntegrationTest.java index 5a4dc13b7e4..45c6689e03c 100644 --- a/src/test/java/net/minestom/server/utils/TranslationIntegrationTest.java +++ b/src/test/java/net/minestom/server/utils/TranslationIntegrationTest.java @@ -10,11 +10,12 @@ import net.minestom.server.item.Material; import net.minestom.server.network.packet.server.play.SetSlotPacket; import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; import net.minestom.server.coordinate.Pos; import net.minestom.server.network.packet.server.play.SystemChatPacket; +import net.minestom.testing.extension.MicrotusExtension; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import java.text.MessageFormat; import java.util.List; @@ -22,8 +23,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; -@EnvTest -public class TranslationIntegrationTest { +@ExtendWith(MicrotusExtension.class) +class TranslationIntegrationTest { @BeforeAll static void translator() { @@ -34,7 +35,7 @@ static void translator() { } @Test - public void testTranslationEnabled(final Env env) { + void testTranslationEnabled(final Env env) { final var instance = env.createFlatInstance(); final var connection = env.createConnection(); final var player = connection.connect(instance, new Pos(0, 40, 0)).join(); @@ -53,7 +54,7 @@ public void testTranslationEnabled(final Env env) { } @Test - public void testTranslationDisabled(final Env env) { + void testTranslationDisabled(final Env env) { final var instance = env.createFlatInstance(); final var connection = env.createConnection(); final var player = connection.connect(instance, new Pos(0, 40, 0)).join(); diff --git a/src/test/java/net/minestom/server/utils/UniqueIdUtilsTest.java b/src/test/java/net/minestom/server/utils/UniqueIdUtilsTest.java new file mode 100644 index 00000000000..a12b906b9a7 --- /dev/null +++ b/src/test/java/net/minestom/server/utils/UniqueIdUtilsTest.java @@ -0,0 +1,17 @@ +package net.minestom.server.utils; + +import org.junit.jupiter.api.Test; + +import java.util.UUID; + +import static net.minestom.server.utils.UniqueIdUtils.*; +import static org.junit.jupiter.api.Assertions.*; + +class UniqueIdUtilsTest { + + @Test + void testUniqueIDCheck() { + assertFalse(isUniqueId("")); + assertTrue(isUniqueId(UUID.randomUUID().toString())); + } +} diff --git a/src/test/java/net/minestom/server/utils/block/BlockIteratorTest.java b/src/test/java/net/minestom/server/utils/block/BlockIteratorTest.java index 56503dbdf90..d8381807460 100644 --- a/src/test/java/net/minestom/server/utils/block/BlockIteratorTest.java +++ b/src/test/java/net/minestom/server/utils/block/BlockIteratorTest.java @@ -9,14 +9,14 @@ import static org.junit.jupiter.api.Assertions.*; -public class BlockIteratorTest { +class BlockIteratorTest { private void assertContains(List points, Point point) { assertTrue(points.contains(point), "Expected " + points + " to contain " + point); } @Test - public void test2dOffsetppp() { - Vec s = new Vec(0, 0.1, 0); + void test2dOffsetppp() { + Vec s = new Vec(0, 0.1, 0); Vec e = new Vec(2, 1, 0); BlockIterator iterator = new BlockIterator(s, e, 0, 4); @@ -29,8 +29,8 @@ public void test2dOffsetppp() { } @Test - public void test2dOffsetppn() { - Vec s = new Vec(0, 0.1, 0); + void test2dOffsetppn() { + Vec s = new Vec(0, 0.1, 0); Vec e = new Vec(-2, 1, 0); BlockIterator iterator = new BlockIterator(s, e, 0, 4); @@ -44,8 +44,8 @@ public void test2dOffsetppn() { } @Test - public void test2dOffsetnpp() { - Vec s = new Vec(0, -0.1, 0); + void test2dOffsetnpp() { + Vec s = new Vec(0, -0.1, 0); Vec e = new Vec(2, 1, 0); BlockIterator iterator = new BlockIterator(s, e, 0, 4); @@ -59,8 +59,8 @@ public void test2dOffsetnpp() { } @Test - public void test2dOffsetnnp() { - Vec s = new Vec(0, -0.1, 0); + void test2dOffsetnnp() { + Vec s = new Vec(0, -0.1, 0); Vec e = new Vec(-2, 1, 0); BlockIterator iterator = new BlockIterator(s, e, 0, 4); @@ -75,15 +75,15 @@ public void test2dOffsetnnp() { } @Test - public void testZeroVelocity() { - Vec s = new Vec(0, 0, 0); + void testZeroVelocity() { + Vec s = new Vec(0, 0, 0); Vec e = new Vec(0, 0, 0); BlockIterator iterator = new BlockIterator(s, e, 0, 4); assertFalse(iterator.hasNext()); } @Test - public void testLongDistance() { + void testLongDistance() { Vec s = new Vec(42.5, 0, 51.5); Vec e = new Vec(-12, 0, -36); BlockIterator iterator = new BlockIterator(s, e, 0, 37); @@ -163,7 +163,7 @@ public void testLongDistance() { } @Test - public void testSkipping() { + void testSkipping() { Vec s = new Vec(0.5, 40, 0.5); Vec e = new Vec(27, 0, 21); BlockIterator iterator = new BlockIterator(s, e, 0, 34); @@ -235,8 +235,8 @@ public void testSkipping() { } @Test - public void testExactEnd() { - Vec s = new Vec(0.5, 0, 0.5); + void testExactEnd() { + Vec s = new Vec(0.5, 0, 0.5); Vec e = new Vec(0, 1, 0); BlockIterator iterator = new BlockIterator(s, e, 0, 1); assertEquals(new Vec(0, 0, 0), iterator.next()); @@ -245,8 +245,8 @@ public void testExactEnd() { } @Test - public void testSameEnd() { - Vec s = new Vec(0.5, 0, 0.5); + void testSameEnd() { + Vec s = new Vec(0.5, 0, 0.5); Vec e = new Vec(0, 1, 0); BlockIterator iterator = new BlockIterator(s, e, 0, 0.5); assertEquals(new Vec(0, 0, 0), iterator.next()); @@ -254,8 +254,8 @@ public void testSameEnd() { } @Test - public void test3dExtraCollection() { - Vec s = new Vec(0.1, 0.1, 0.1); + void test3dExtraCollection() { + Vec s = new Vec(0.1, 0.1, 0.1); Vec e = new Vec(1, 1, 1); BlockIterator iterator = new BlockIterator(s, e, 0, 4); @@ -290,8 +290,8 @@ public void test3dExtraCollection() { } @Test - public void test2dpp() { - Vec s = new Vec(0, 0, 0); + void test2dpp() { + Vec s = new Vec(0, 0, 0); Vec e = new Vec(2, 1, 0); BlockIterator iterator = new BlockIterator(s, e, 0, 4); @@ -316,8 +316,8 @@ public void test2dpp() { } @Test - public void test2dpn() { - Vec s = new Vec(0, 0, 0); + void test2dpn() { + Vec s = new Vec(0, 0, 0); Vec e = new Vec(-2, 1, 0); BlockIterator iterator = new BlockIterator(s, e, 0, 4); @@ -343,8 +343,8 @@ public void test2dpn() { } @Test - public void test2dnn() { - Vec s = new Vec(0, 0, 0); + void test2dnn() { + Vec s = new Vec(0, 0, 0); Vec e = new Vec(-2, -1, 0); BlockIterator iterator = new BlockIterator(s, e, 0, 4); @@ -372,8 +372,8 @@ public void test2dnn() { } @Test - public void falling() { - Vec s = new Vec(0, 42, 0); + void falling() { + Vec s = new Vec(0, 42, 0); Vec e = new Vec(0, -10, 0); BlockIterator iterator = new BlockIterator(s, e, 0, 14.142135623730951); diff --git a/src/test/java/net/minestom/server/utils/collection/AutoIncrementMapTest.java b/src/test/java/net/minestom/server/utils/collection/AutoIncrementMapTest.java index b19454170b5..04946c4ab86 100644 --- a/src/test/java/net/minestom/server/utils/collection/AutoIncrementMapTest.java +++ b/src/test/java/net/minestom/server/utils/collection/AutoIncrementMapTest.java @@ -4,9 +4,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -public class AutoIncrementMapTest { +class AutoIncrementMapTest { @Test - public void test() { + void test() { AutoIncrementMap map = new AutoIncrementMap<>(); for (int i = 0; i < 1000; i++) { assertEquals(i, map.get("test" + i)); diff --git a/src/test/java/net/minestom/server/utils/collection/ObjectArrayTest.java b/src/test/java/net/minestom/server/utils/collection/ObjectArrayTest.java index ee2f9544050..cece245e052 100644 --- a/src/test/java/net/minestom/server/utils/collection/ObjectArrayTest.java +++ b/src/test/java/net/minestom/server/utils/collection/ObjectArrayTest.java @@ -5,11 +5,11 @@ import static org.junit.jupiter.api.Assertions.*; -public class ObjectArrayTest { +class ObjectArrayTest { @ParameterizedTest @ValueSource(booleans = {false, true}) - public void objectArray(boolean concurrent) { + void objectArray(boolean concurrent) { ObjectArray array = concurrent ? ObjectArray.concurrent() : ObjectArray.singleThread(); array.set(50, "Hey"); @@ -37,7 +37,7 @@ public void objectArray(boolean concurrent) { @ParameterizedTest @ValueSource(booleans = {false, true}) - public void arrayCopy(boolean concurrent) { + void arrayCopy(boolean concurrent) { ObjectArray array = concurrent ? ObjectArray.concurrent() : ObjectArray.singleThread(); array.set(1, "Hey"); diff --git a/testing/build.gradle.kts b/testing/build.gradle.kts index 8926b63c3c7..34c7ab94613 100644 --- a/testing/build.gradle.kts +++ b/testing/build.gradle.kts @@ -1,14 +1,23 @@ plugins { - `java-library` -// `maven-publish` + id("java-library") + id("net.kyori.indra") + id("net.kyori.indra.publishing") + signing } -group = "net.minestom.testing" -// version declared by root project +group = "net.onelitefeather.microtus.testing" -dependencies { - api(rootProject) +repositories { + maven("https://s01.oss.sonatype.org/content/repositories/snapshots") + mavenCentral() + maven(url = "https://jitpack.io") +} + +dependencies { + // Minestom API + api(project(mapOf("path" to ":"))) + // Junit Testing Framework api(libs.junit.api) api(libs.junit.params) api(libs.junit.suite.api) @@ -16,14 +25,36 @@ dependencies { runtimeOnly(libs.junit.suite.engine) } -//publishing { -// publications { -// create("maven") { -// groupId = "net.minestom.testing" -// artifactId = "testing" -// version = "1.0" -// -// from(components["java"]) -// } -// } -//} +tasks.getByName("test") { + useJUnitPlatform() +} + +indra { + javaVersions { + target(21) + testWith(21) + } + + github("OneLiteFeatherNET", "Microtus") { + ci(true) + publishing(false) + } + mitLicense() + signWithKeyFromPrefixedProperties("onelitefeather") + configurePublications { + pom { + developers { + developer { + id.set("themeinerlp") + name.set("Phillipp Glanz") + email.set("p.glanz@madfix.me") + } + developer { + id.set("theEvilReaper") + name.set("Steffen Wonning") + email.set("steffenwx@gmail.com") + } + } + } + } +} \ No newline at end of file diff --git a/testing/src/main/java/net/minestom/testing/Env.java b/testing/src/main/java/net/minestom/testing/Env.java index 23f26476783..7fee8ded4f2 100644 --- a/testing/src/main/java/net/minestom/testing/Env.java +++ b/testing/src/main/java/net/minestom/testing/Env.java @@ -8,25 +8,93 @@ import net.minestom.server.instance.IChunkLoader; import net.minestom.server.instance.Instance; import net.minestom.server.instance.block.Block; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.time.Duration; import java.util.function.BooleanSupplier; +/** + * The {@code Env} class facilitates the creation of tests (e.g., JUnit tests) that interact directly + * with the server. It provides a simple way to set up a test environment where server + * components like players, instances, and other entities can be created and manipulated. + * + *

This class is particularly useful for testing code that interacts with server components, which would + * otherwise require the use of a mocking framework. By using this class, developers can create more realistic + * tests that involve actual server behavior, without needing to mock every component. + * + *

The {@code Env} class provides utility methods to: + *

    + *
  • Create new object references for {@link net.minestom.server.entity.Player Player}
  • + *
  • Initialize and manipulate server {@link net.minestom.server.instance.Instance Instances}
  • + *
  • Simulate server events and other interactions
  • + *
+ * + *

This class is intended for use in unit tests, integration tests, and other testing scenarios where + * interaction with a live server environment is necessary. + * + * @version 1.0.1 + * @since 1.0.0 + */ public interface Env { + + /** + * Creates a new instance of {@link Env} with the given {@link ServerProcess}. + * + * @param process the process to use + * @return a new instance of {@link Env} + */ + @Contract(value = "_ -> new", pure = true) + static @NotNull Env createInstance(@NotNull ServerProcess process) { + return new EnvImpl(process); + } + + /** + * Gets the {@link ServerProcess} used by this environment. + * + * @return the server process + */ @NotNull ServerProcess process(); + /** + * Creates a new {@link TestConnection} which can be used in the test environment. + * + * @return the created connection + */ @NotNull TestConnection createConnection(); + /** + * Tracks a specific event type in the test environment. + * + * @param eventType the event type to track + * @param the event type + * @return the {@link Collector} instance to use + */ @NotNull Collector trackEvent(@NotNull Class eventType, @NotNull EventFilter filter, @NotNull H actor); + /** + * Listen for a specific event type in the test environment. + * + * @param eventType the event type to listen for + * @param the event type + * @return the {@link FlexibleListener} instance to use + */ @NotNull FlexibleListener listen(@NotNull Class eventType); + /** + * Ticks the {@link ServerProcess} which is involved into the env instance. + */ default void tick() { process().ticker().tick(System.nanoTime()); } - default boolean tickWhile(BooleanSupplier condition, Duration timeout) { + /** + * Ticks the {@link ServerProcess} until the given condition is met. + * + * @param condition the condition to check + */ + default boolean tickWhile(@NotNull BooleanSupplier condition, @Nullable Duration timeout) { var ticker = process().ticker(); final long start = System.nanoTime(); while (condition.getAsBoolean()) { @@ -39,21 +107,75 @@ default boolean tickWhile(BooleanSupplier condition, Duration timeout) { return true; } + /** + * Creates a new instance of an {@link Player} which can be used in the test environment. + * + * @param instance the instance to spawn the player in + * @param pos the position to spawn the player at + * @return the created player + */ default @NotNull Player createPlayer(@NotNull Instance instance, @NotNull Pos pos) { return createConnection().connect(instance, pos).join(); } + /** + * Creates a new instance of an {@link Player} which can be used in the test environment. + * + * @param instance the instance to spawn the player in + * @return the created player + */ + default @NotNull Player createPlayer(@NotNull Instance instance) { + return createPlayer(instance, Pos.ZERO); + } + + /** + * Creates a new {@link Instance} which contains only one layer of stone blocks. + * + * @return the created instance + */ default @NotNull Instance createFlatInstance() { return createFlatInstance(null); } - default @NotNull Instance createFlatInstance(IChunkLoader chunkLoader) { + /** + * Creates a new {@link Instance} which contains only one layer of stone blocks. + * + * @param chunkLoader the chunk loader to use for the instance + * @return the created instance + */ + default @NotNull Instance createFlatInstance(@Nullable IChunkLoader chunkLoader) { var instance = process().instance().createInstanceContainer(chunkLoader); instance.setGenerator(unit -> unit.modifier().fillHeight(0, 40, Block.STONE)); return instance; } - default void destroyInstance(Instance instance) { + /** + * Destroys the given {@link Instance} from the test environment. + * Note: This method does not remove players from the instance. + * + * @param instance the instance to destroy + */ + default void destroyInstance(@NotNull Instance instance) { + destroyInstance(instance, false); + } + + /** + * Destroys the given {@link Instance} from the test environment. + * + * @param instance the instance to destroy + * @param cleanUpPlayers whether to remove players from the instance + */ + default void destroyInstance(@NotNull Instance instance, boolean cleanUpPlayers) { + if (cleanUpPlayers && !instance.getPlayers().isEmpty()) { + instance.getPlayers().forEach(Player::remove); + } process().instance().unregisterInstance(instance); } + + /** + * Cleanup the test environment + * + * @since 1.4.1 + */ + void cleanup(); } diff --git a/testing/src/main/java/net/minestom/testing/EnvImpl.java b/testing/src/main/java/net/minestom/testing/EnvImpl.java index 89f1c9c7ad6..cb41fcc9264 100644 --- a/testing/src/main/java/net/minestom/testing/EnvImpl.java +++ b/testing/src/main/java/net/minestom/testing/EnvImpl.java @@ -48,7 +48,8 @@ public EnvImpl(ServerProcess process) { return flexible; } - void cleanup() { + @Override + public void cleanup() { this.listeners.forEach(FlexibleListenerImpl::check); this.process.stop(); } diff --git a/testing/src/main/java/net/minestom/testing/EnvTest.java b/testing/src/main/java/net/minestom/testing/EnvTest.java index ebaeea0e1fa..556d7b43200 100644 --- a/testing/src/main/java/net/minestom/testing/EnvTest.java +++ b/testing/src/main/java/net/minestom/testing/EnvTest.java @@ -1,6 +1,7 @@ package net.minestom.testing; import net.minestom.server.MinecraftServer; +import org.jetbrains.annotations.ApiStatus; import org.junit.jupiter.api.extension.*; import org.junit.jupiter.api.extension.support.TypeBasedParameterResolver; @@ -10,11 +11,18 @@ import java.lang.annotation.Target; import java.lang.reflect.Method; +/** + * @deprecated As of Microtus 1.4.2, because this version doesn't support Non Env tests and env tests at the same time. + * Use {@link net.minestom.testing.extension.MicrotusExtension MicrotusExtension} instead of the {@code @EnvTest} annotation: + * {@code @ExtendWith(MicrotusExtension.class)} + */ @ExtendWith(EnvTest.EnvParameterResolver.class) @ExtendWith(EnvTest.EnvBefore.class) @ExtendWith(EnvTest.EnvCleaner.class) @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) +@Deprecated(forRemoval = true, since = "1.4.2") +@ApiStatus.ScheduledForRemoval(inVersion = "1.6.0") public @interface EnvTest { final class EnvBefore implements BeforeEachCallback { diff --git a/testing/src/main/java/net/minestom/testing/TestConnection.java b/testing/src/main/java/net/minestom/testing/TestConnection.java index c25b74be0e6..a2c37dea7fa 100644 --- a/testing/src/main/java/net/minestom/testing/TestConnection.java +++ b/testing/src/main/java/net/minestom/testing/TestConnection.java @@ -3,16 +3,60 @@ import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.Player; import net.minestom.server.instance.Instance; +import net.minestom.server.network.PlayerProvider; import net.minestom.server.network.packet.server.ServerPacket; import org.jetbrains.annotations.NotNull; import java.util.concurrent.CompletableFuture; +/** + * Represents a connection to a test server. + */ public interface TestConnection { + + /** + * Sets the custom player provider for this test connection. + *
+ * For a successful test you need to override the sendChunk method in the player implementation. + * Example: + *

{@code
+     * public class CustomGamePlayerImpl extends Player {
+     *    public CustomGamePlayerImpl(UUID uuid, String username, PlayerConnection playerConnection) {
+     *      super(uuid, username, playerConnection);
+     *    }
+     *    @Override
+     *    public void sendChunk(Chunk chunk) {
+     *      sendPacket(chunk.getFullDataPacket());
+     *    }
+     * }
+     * }
+ * @param provider the custom player provider + */ + void setCustomPlayerProvider(@NotNull PlayerProvider provider); + + /** + * Connects a player to the server. + * + * @param instance the instance to spawn the player in + * @param pos the position to spawn the player at + * @return a future that completes when the player is connected + */ @NotNull CompletableFuture<@NotNull Player> connect(@NotNull Instance instance, @NotNull Pos pos); + /** + * Tracks incoming packets of a specific type. + * + * @param type the packet type to track + * @param the packet type + * @return a collector for the tracked packets + */ @NotNull Collector trackIncoming(@NotNull Class type); + /** + * Tracks all incoming packets. + * + * @return a collector for all incoming packets + */ default @NotNull Collector trackIncoming() { return trackIncoming(ServerPacket.class); } diff --git a/testing/src/main/java/net/minestom/testing/TestConnectionImpl.java b/testing/src/main/java/net/minestom/testing/TestConnectionImpl.java index f6d963728d5..588dc50145d 100644 --- a/testing/src/main/java/net/minestom/testing/TestConnectionImpl.java +++ b/testing/src/main/java/net/minestom/testing/TestConnectionImpl.java @@ -8,6 +8,7 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.minestom.server.instance.Instance; import net.minestom.server.network.ConnectionState; +import net.minestom.server.network.PlayerProvider; import net.minestom.server.network.packet.server.SendablePacket; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.configuration.SelectKnownPacksPacket; @@ -18,26 +19,31 @@ import java.net.SocketAddress; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CopyOnWriteArrayList; final class TestConnectionImpl implements TestConnection { - private final Env env; private final ServerProcess process; private final PlayerConnectionImpl playerConnection = new PlayerConnectionImpl(); + private volatile Optional playerProvider = Optional.of(TestPlayerImpl::new); private final List> incomingTrackers = new CopyOnWriteArrayList<>(); TestConnectionImpl(Env env) { - this.env = env; this.process = env.process(); } + @Override + public void setCustomPlayerProvider(@NotNull PlayerProvider provider) { + this.playerProvider = Optional.ofNullable(provider); + } + @Override public @NotNull CompletableFuture connect(@NotNull Instance instance, @NotNull Pos pos) { // Use player provider to disable queued chunk sending - process.connection().setPlayerProvider(TestPlayerImpl::new); + process.connection().setPlayerProvider(playerProvider.orElse(TestPlayerImpl::new)); playerConnection.setConnectionState(ConnectionState.LOGIN); var player = process.connection().createPlayer(playerConnection, UUID.randomUUID(), "RandName"); diff --git a/testing/src/main/java/net/minestom/testing/annotations/EnvironmentTest.java b/testing/src/main/java/net/minestom/testing/annotations/EnvironmentTest.java new file mode 100644 index 00000000000..5f6f83db3c6 --- /dev/null +++ b/testing/src/main/java/net/minestom/testing/annotations/EnvironmentTest.java @@ -0,0 +1,24 @@ +package net.minestom.testing.annotations; + +import net.minestom.testing.extension.MicrotusExtension; +import org.jetbrains.annotations.ApiStatus; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Creates a fake environment for Microtus + * @since 1.4.2 + * @deprecated As of Microtus 1.5.0, because better and deeper integration of JUnit5 testing use + * {@link net.minestom.testing.extension.MicrotusExtension} instead. + */ +@ExtendWith(MicrotusExtension.class) +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Deprecated(forRemoval = true, since = "1.5.0") +@ApiStatus.ScheduledForRemoval(inVersion = "1.6.0") +public @interface EnvironmentTest { +} diff --git a/testing/src/main/java/net/minestom/testing/environment/TestEnvironmentCleaner.java b/testing/src/main/java/net/minestom/testing/environment/TestEnvironmentCleaner.java new file mode 100644 index 00000000000..94f404ebcd4 --- /dev/null +++ b/testing/src/main/java/net/minestom/testing/environment/TestEnvironmentCleaner.java @@ -0,0 +1,28 @@ +package net.minestom.testing.environment; + +import net.minestom.testing.Env; +import org.jetbrains.annotations.ApiStatus; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.InvocationInterceptor; +import org.junit.jupiter.api.extension.ReflectiveInvocationContext; + +import java.lang.reflect.Method; +import java.util.List; + +/** + * Handles {@link Env} to clean the Test Environment after usage + * @since 1.4.2 + */ +@Deprecated(forRemoval = true, since = "1.5.0") +@ApiStatus.ScheduledForRemoval(inVersion = "1.6.0") +public final class TestEnvironmentCleaner implements InvocationInterceptor { + @Override + public void interceptTestMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { + invocation.proceed(); + List arguments = invocationContext.getArguments(); + arguments.stream().filter(Env.class::isInstance).findFirst().ifPresent(o -> { + Env env = (Env) o; + env.cleanup(); + }); + } +} diff --git a/testing/src/main/java/net/minestom/testing/environment/TestEnvironmentParameterResolver.java b/testing/src/main/java/net/minestom/testing/environment/TestEnvironmentParameterResolver.java new file mode 100644 index 00000000000..6980f22bc0d --- /dev/null +++ b/testing/src/main/java/net/minestom/testing/environment/TestEnvironmentParameterResolver.java @@ -0,0 +1,23 @@ +package net.minestom.testing.environment; + +import net.minestom.server.MinecraftServer; +import net.minestom.testing.Env; +import org.jetbrains.annotations.ApiStatus; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolutionException; +import org.junit.jupiter.api.extension.support.TypeBasedParameterResolver; + +/** + * Handles {@link Env} parameter for JUnit Tests to inject the TestEnvironment + * @since 1.4.1 + */ +@Deprecated(forRemoval = true, since = "1.5.0") +@ApiStatus.ScheduledForRemoval(inVersion = "1.6.0") +public final class TestEnvironmentParameterResolver extends TypeBasedParameterResolver { + @Override + public Env resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) + throws ParameterResolutionException { + return Env.createInstance(MinecraftServer.updateProcess()); + } +} diff --git a/testing/src/main/java/net/minestom/testing/extension/MicrotusExtension.java b/testing/src/main/java/net/minestom/testing/extension/MicrotusExtension.java new file mode 100644 index 00000000000..e19513fd34b --- /dev/null +++ b/testing/src/main/java/net/minestom/testing/extension/MicrotusExtension.java @@ -0,0 +1,50 @@ +package net.minestom.testing.extension; + +import net.minestom.server.MinecraftServer; +import net.minestom.testing.Env; +import org.junit.jupiter.api.extension.*; +import org.junit.jupiter.api.extension.support.TypeBasedParameterResolver; + +import java.lang.reflect.Method; +import java.util.List; + +/** + * The {@code MicrotusExtension} class extends {@link TypeBasedParameterResolver} and implements {@link InvocationInterceptor}. + * This extension is used to resolve parameters of type {@link Env} and to intercept test method invocations. + * + * @since 1.5.0 + */ +public class MicrotusExtension extends TypeBasedParameterResolver implements InvocationInterceptor { + + /** + * Resolves the parameter of type {@link Env}. + * + * @param parameterContext the context for the parameter for which an argument should be resolved; never {@code null} + * @param extensionContext the extension context for the {@code Executable} about to be invoked; never {@code null} + * @return an instance of {@link Env} + * @throws ParameterResolutionException if an error occurs during parameter resolution + */ + @Override + public Env resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) + throws ParameterResolutionException { + return Env.createInstance(MinecraftServer.updateProcess()); + } + + /** + * Intercepts the test method invocation to perform additional actions before or after the test method execution. + * + * @param invocation the invocation to be intercepted; never {@code null} + * @param invocationContext the context for the reflective invocation of the test method; never {@code null} + * @param extensionContext the context for the extension; never {@code null} + * @throws Throwable if an error occurs during the interception + */ + @Override + public void interceptTestMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { + invocation.proceed(); + List arguments = invocationContext.getArguments(); + arguments.stream().filter(Env.class::isInstance).findFirst().ifPresent(o -> { + Env env = (Env) o; + env.cleanup(); + }); + } +} diff --git a/testing/src/main/java/net/minestom/testing/extension/package-info.java b/testing/src/main/java/net/minestom/testing/extension/package-info.java new file mode 100644 index 00000000000..8a40149180b --- /dev/null +++ b/testing/src/main/java/net/minestom/testing/extension/package-info.java @@ -0,0 +1,21 @@ +/** + * This package contains extensions for parameter resolution and invocation interception in tests. + *

+ * The main class in this package is {@link net.minestom.testing.extension.MicrotusExtension}, which provides + * parameter resolution for {@link net.minestom.testing.Env} type parameters and intercepts test method invocations. + *

+ * + *

Usage Example:

+ *
+ * @ExtendWith(MicrotusExtension.class)
+ * public class MyTest {
+ *     @Test
+ *     public void testWithEnv(Env env) {
+ *         // test code using env
+ *     }
+ * }
+ * 
+ * + * @since 1.5.0 + */ +package net.minestom.testing.extension; \ No newline at end of file