From e66477b2fd9c21c510938567c0ed76d41a51960b Mon Sep 17 00:00:00 2001 From: Morlok8k Date: Fri, 4 Nov 2011 01:54:30 -0700 Subject: [PATCH] 1.6.0 (test8) --- .classpath | 6 +- .settings/org.eclipse.jdt.core.prefs | 364 ++++ .settings/org.eclipse.jdt.launching.prefs | 3 + .settings/org.eclipse.jdt.ui.prefs | 57 + .../org.eclipse.ltk.core.refactoring.prefs | 3 + MinecraftLandGenerator.conf | 27 + README | 114 +- bin/MLG-BuildID | 1 + bin/MinecraftLandGenerator.conf | 4 +- bin/MinecraftLandGenerator.jar | Bin 32480 -> 40795 bytes new_readme_file.sh | 15 +- .../minecraft/landgenerator/Main.java | 1509 ++++++++++++----- 12 files changed, 1679 insertions(+), 424 deletions(-) create mode 100644 .settings/org.eclipse.jdt.core.prefs create mode 100644 .settings/org.eclipse.jdt.launching.prefs create mode 100644 .settings/org.eclipse.jdt.ui.prefs create mode 100644 .settings/org.eclipse.ltk.core.refactoring.prefs create mode 100644 MinecraftLandGenerator.conf create mode 100644 bin/MLG-BuildID mode change 100644 => 100755 bin/MinecraftLandGenerator.jar diff --git a/.classpath b/.classpath index f236b9f..6a296a6 100644 --- a/.classpath +++ b/.classpath @@ -2,6 +2,10 @@ - + + + + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..f260150 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,364 @@ +#Thu Nov 03 02:14:00 PDT 2011 +eclipse.preferences.version=1 +org.eclipse.jdt.core.builder.cleanOutputFolder=clean +org.eclipse.jdt.core.builder.duplicateResourceTask=warning +org.eclipse.jdt.core.builder.invalidClasspath=abort +org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=enabled +org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch +org.eclipse.jdt.core.circularClasspath=error +org.eclipse.jdt.core.classpath.exclusionPatterns=enabled +org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_assignment=16 +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16 +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false +org.eclipse.jdt.core.formatter.comment.format_block_comments=true +org.eclipse.jdt.core.formatter.comment.format_header=true +org.eclipse.jdt.core.formatter.comment.format_html=true +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true +org.eclipse.jdt.core.formatter.comment.format_line_comments=false +org.eclipse.jdt.core.formatter.comment.format_source_code=true +org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true +org.eclipse.jdt.core.formatter.comment.indent_root_tags=true +org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert +org.eclipse.jdt.core.formatter.comment.line_length=200 +org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true +org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true +org.eclipse.jdt.core.formatter.compact_else_if=true +org.eclipse.jdt.core.formatter.continuation_indentation=2 +org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=true +org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_empty_lines=false +org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true +org.eclipse.jdt.core.formatter.indentation.size=4 +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +org.eclipse.jdt.core.formatter.join_lines_in_comments=true +org.eclipse.jdt.core.formatter.join_wrapped_lines=true +org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=true +org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=true +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +org.eclipse.jdt.core.formatter.lineSplit=100 +org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=false +org.eclipse.jdt.core.formatter.tabulation.char=tab +org.eclipse.jdt.core.formatter.tabulation.size=4 +org.eclipse.jdt.core.formatter.use_on_off_tags=true +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true +org.eclipse.jdt.core.incompatibleJDKLevel=ignore +org.eclipse.jdt.core.incompleteClasspath=error diff --git a/.settings/org.eclipse.jdt.launching.prefs b/.settings/org.eclipse.jdt.launching.prefs new file mode 100644 index 0000000..0a82b7d --- /dev/null +++ b/.settings/org.eclipse.jdt.launching.prefs @@ -0,0 +1,3 @@ +#Sat Oct 29 12:57:48 PDT 2011 +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 0000000..57a75ed --- /dev/null +++ b/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,57 @@ +#Wed Nov 02 01:36:56 PDT 2011 +eclipse.preferences.version=1 +editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true +formatter_profile=_Morlok8k +formatter_settings_version=12 +sp_cleanup.add_default_serial_version_id=true +sp_cleanup.add_generated_serial_version_id=false +sp_cleanup.add_missing_annotations=true +sp_cleanup.add_missing_deprecated_annotations=true +sp_cleanup.add_missing_methods=false +sp_cleanup.add_missing_nls_tags=false +sp_cleanup.add_missing_override_annotations=true +sp_cleanup.add_missing_override_annotations_interface_methods=true +sp_cleanup.add_serial_version_id=false +sp_cleanup.always_use_blocks=true +sp_cleanup.always_use_parentheses_in_expressions=false +sp_cleanup.always_use_this_for_non_static_field_access=false +sp_cleanup.always_use_this_for_non_static_method_access=false +sp_cleanup.convert_to_enhanced_for_loop=false +sp_cleanup.correct_indentation=false +sp_cleanup.format_source_code=true +sp_cleanup.format_source_code_changes_only=false +sp_cleanup.make_local_variable_final=false +sp_cleanup.make_parameters_final=false +sp_cleanup.make_private_fields_final=true +sp_cleanup.make_type_abstract_if_missing_method=false +sp_cleanup.make_variable_declarations_final=true +sp_cleanup.never_use_blocks=false +sp_cleanup.never_use_parentheses_in_expressions=true +sp_cleanup.on_save_use_additional_actions=false +sp_cleanup.organize_imports=true +sp_cleanup.qualify_static_field_accesses_with_declaring_class=false +sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true +sp_cleanup.qualify_static_member_accesses_with_declaring_class=false +sp_cleanup.qualify_static_method_accesses_with_declaring_class=false +sp_cleanup.remove_private_constructors=true +sp_cleanup.remove_trailing_whitespaces=false +sp_cleanup.remove_trailing_whitespaces_all=true +sp_cleanup.remove_trailing_whitespaces_ignore_empty=false +sp_cleanup.remove_unnecessary_casts=true +sp_cleanup.remove_unnecessary_nls_tags=false +sp_cleanup.remove_unused_imports=false +sp_cleanup.remove_unused_local_variables=false +sp_cleanup.remove_unused_private_fields=true +sp_cleanup.remove_unused_private_members=false +sp_cleanup.remove_unused_private_methods=true +sp_cleanup.remove_unused_private_types=true +sp_cleanup.sort_members=false +sp_cleanup.sort_members_all=false +sp_cleanup.use_blocks=false +sp_cleanup.use_blocks_only_for_return_and_throw=false +sp_cleanup.use_parentheses_in_expressions=false +sp_cleanup.use_this_for_non_static_field_access=false +sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true +sp_cleanup.use_this_for_non_static_method_access=false +sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/.settings/org.eclipse.ltk.core.refactoring.prefs b/.settings/org.eclipse.ltk.core.refactoring.prefs new file mode 100644 index 0000000..0d53358 --- /dev/null +++ b/.settings/org.eclipse.ltk.core.refactoring.prefs @@ -0,0 +1,3 @@ +#Sat Oct 29 13:00:14 PDT 2011 +eclipse.preferences.version=1 +org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false diff --git a/MinecraftLandGenerator.conf b/MinecraftLandGenerator.conf new file mode 100644 index 0000000..4096b2c --- /dev/null +++ b/MinecraftLandGenerator.conf @@ -0,0 +1,27 @@ +#Minecraft Land Generator Configuration File: Version: 1.5.1 +#Authors: Corrodias, Morlok8k, pr0f1x +#Auto-Generated: Monday, October 17, 2011 at 11:40 PM Pacific Daylight Time + +#Line to run server: +Java=java -Djava.awt.headless=true -Djline.terminal=jline.UnsupportedTerminal -Duser.language=en -Xms1024m -Xmx1024m -Xincgc -jar minecraft_server.jar nogui + +#Location of server. use "." for the same folder as MLG +ServerPath=. + +#Strings read from the server +Done_Text=[INFO] Done +Preparing_Text=[INFO] Preparing spawn area: +Preparing_Level=[INFO] Preparing start region for +Level-0=The Overworld +Level-1=The Nether +Level-2=The End +Level-3=Level 3 (Future Level) +Level-4=Level 4 (Future Level) +Level-5=Level 5 (Future Level) +Level-6=Level 6 (Future Level) +Level-7=Level 7 (Future Level) +Level-8=Level 8 (Future Level) +Level-9=Level 9 (Future Level) + +#Optional: Wait a few seconds after saving. +WaitSave=false diff --git a/README b/README index 8c99c64..85be2be 100644 --- a/README +++ b/README @@ -1,9 +1,110 @@ -Minecraft Land Generator version 1.5.1 -BuildID: (111017.233927-0700) -This version was last modified on Monday, October 17, 2011 at 11:39 PM Pacific Daylight Time +Minecraft Land Generator version 1.6.0 Testing 8 -Uses a Minecraft server to generate square land of a specified size. +Updated November 4, 2011 +Original Code by Corrodias November 2010 +Enhanced Code by Morlok8k Feb. 2011 to Now (or at least to the date listed above!) +Additional Code by pr0f1x October 2011 +Forum: http://www.minecraftforum.net/topic/187737-minecraft-land-generator/ +Source: https://github.com/Morlok8k/MinecraftLandGenerator + +----------------------------------------------- + +This program lets you generate an area of land with your Minecraft Beta SMP server (and is prossibly future-proof for newer versions). You set up your java command line and minecraft server paths in the MinecraftLandGenerator.conf file, set up the server's server.properties file with the name of the world you wish to use, and then run this program. +When a Minecraft server is launched, it automatically generates chunks within a square area of 20x20 chunks (320x320 blocks), centered on the current spawn point. When provided X and Y ranges as arguments, this program will launch the server repeatedly, editing the level.dat file between sessions, to generate large amounts of land without players having to explore them. The generated land will have about the X and Y ranges as requested by the arguments, though it will not be exact due to the spawn point typically not on the border of a chunk. (Because of this, MLG by default adds a slight overlap with each pass - 300x300) You can use the -x and -y switches to override the spawn offset and center the land generation on a different point. +The program makes a backup of level.dat as level_backup.dat before editing, and restores the backup at the end. In the event that a level_backup.dat file already exists, the program will refuse to proceed, leaving the user to determine why the level_backup.dat file exists and whether they would rather restore it or delete it, which must be done manually. + +This program is public domain, and the source code is included in the .jar file. (If accidently missing, like in 1.3.0 and 1.4.0, it is always available at Github.) +The JNLP library is included (inside the .jar) as jnbt-1.1.jar. It is not public domain. Its license is included within its .jar file, as LICENSE.TXT. +It is also available at: http://jnbt.sourceforge.net/ + +----------------------------------------------- + +Version History: +Morlok8k: + +1.6.0 +- TODO: add features +- Added the ability to download files from the internet (specifically for the BuildID file) +- Added the ability to check what version the .jar is. (Using MD5 hashes, timestamps, and the BuildID file) +- Minor Refactoring + +1.5.1 +- pr0f1x: Added the "save-all" command to be sent to the server before shutting it down. +- pr0f1x: Added a 40 second wait before shutting down. +- Morlok8k: Made 40 second wait optional. +- Morlok8k: Changed the Dimensions code. (I had assumed it would be DIM-1, DIM-2, etc. but it turned out to be DIM-1 and DIM1. Change reflects Server output of "Level n") +- Morlok8k: Config file is automatically updated to reflect these changes. +- Morlok8k: Cleaned up code. + +1.5.0 +- Supports Server Beta 1.6.4 (& hopefully future versions as well, while remaining backward compatible.) +- Added "-a","-alt" to use alternate method (a slightly simplier version of 1.3.0's code - pure verbose only) +- Added world specific output for 9 dimensions (DIM-1 is the Nether, DIM-2 through DIM-9 dont exist yet, but if and when they do, you can configure it's text). ("Level 0", the default world, is displayed as the worlds name) +- Updated Config File for these Dimensions. +- Reads and outputs the Seed to the output. (If you had used text for the Seed, Minecraft converts it into a number. This outputs the number.) +- Changed the default 300 blocks to 380. The server now makes a 400x400 square block terrain instead of 320x320. Thus it is faster because there are less loops. To use the old way, use "-i300" +- Added total Percentage done (technically, it displays the % done once the server finishes...) +- Added debugging output vars of conf file (disabled - need to re-compile source to activate) + + + (the goal is to have MLG be configureable, so it can work on any version of the server, past or present.) + +*** 1.4.5 (pre 1.5.0) *** +- sorry! I shouldn't release untested code... +************************* + +1.4.4 +- Added ablilty to ignore [WARNING] and [SEVERE] errors with "-w" + +1.4.3 +- Fixed "-ps","-printspawn" as I had forgot I had broken it in 1.4.0 - due to config file change. + +1.4.2 +- No New Features +- Changed non-verbose mode to display server progress on the same line, saving a lot of space. + - This couldn't wait for 1.5.0 ... I (Morlok8k) liked it too much. + +1.4.0 +- Future Proofing +- Configurble Server Message reading. (If server updates and breaks MLG, you can add the new text!) +- Updated config file, and auto updating from old format. +- Added % of spawn area to non-verbose output. +- Removed datetime stamps from server output in verbose mode +- Other Misc fixes. + +1.3.0 +- Fixed Problems with Minecraft Beta 1.3 -- Morlok8k + +----------------------------------------------- + +Corrodias: +1.2.0 +- land generation now centers on the spawn point instead of [0, 0] +- the server is launched once before the spawn point is changed, to verify that it can run and to create a world if one doesn't exist +- added -printspawn [-ps] switch to print the current spawn coordinates to the console +- added -x and -y switches to override the X and Y offsets +- added -v switch, does the same as -verbose +- improved status message spacing to make things easier to read +- improved time estimation algorithm: it now averages the last 3 launches + +1.1.0 +- added MinecraftLandGenerator.conf file to hold the java command line and the server path +- added -conf solo switch to generate a .conf file +- added -verbose switch to output server output to the console (default is to ignore it) +- added -i switch to allow customizing the block increment size (default is 300) +- added instructions output in this version, i think +- improved status message output to include current iteration and total iterations + +1.0.0 +- initial release + +----------------------------------------------- + +Notes: +Due to changes in server beta 1.6, it now generates the nether as well as the world at the same time. +I recommend using MCE or MCEDIT to relight the map after you generate it. This will take a long time, but should fix all those incorrectly dark spots in your level. + +----------------------------------------------- Usage: java -jar MinecraftLandGenerator.jar x y [serverpath] [switches] @@ -30,6 +131,10 @@ Other options: java -jar MinecraftLandGenerator.jar -conf Generates a MinecraftLandGenerator.conf file. + java -jar MinecraftLandGenerator.jar -readme readme.txt + java -jar MinecraftLandGenerator.jar -readme + Generates a readme file using supplied name or the default MLG-Readme.txt + java -jar MinecraftLandGenerator.jar -version java -jar MinecraftLandGenerator.jar -help java -jar MinecraftLandGenerator.jar /? @@ -55,3 +160,4 @@ Preparing_Level : The output from the server that tells us the level it is worki Level-8 : Name of Level 8: (Future Level) Level-9 : Name of Level 9: (Future Level) WaitSave : Optional: Wait before saving. + diff --git a/bin/MLG-BuildID b/bin/MLG-BuildID new file mode 100644 index 0000000..3846aa9 --- /dev/null +++ b/bin/MLG-BuildID @@ -0,0 +1 @@ +919315DC465C9A821A857FCBE789C571=1320395554000#MLG v1.6.0 Testing 8 diff --git a/bin/MinecraftLandGenerator.conf b/bin/MinecraftLandGenerator.conf index 4096b2c..1fd7ae4 100644 --- a/bin/MinecraftLandGenerator.conf +++ b/bin/MinecraftLandGenerator.conf @@ -1,6 +1,6 @@ -#Minecraft Land Generator Configuration File: Version: 1.5.1 +#Minecraft Land Generator Configuration File: Version: 1.6.0 Testing 8 #Authors: Corrodias, Morlok8k, pr0f1x -#Auto-Generated: Monday, October 17, 2011 at 11:40 PM Pacific Daylight Time +#Auto-Generated: Friday, November 4, 2011 at 1:53 AM Pacific Daylight Time #Line to run server: Java=java -Djava.awt.headless=true -Djline.terminal=jline.UnsupportedTerminal -Duser.language=en -Xms1024m -Xmx1024m -Xincgc -jar minecraft_server.jar nogui diff --git a/bin/MinecraftLandGenerator.jar b/bin/MinecraftLandGenerator.jar old mode 100644 new mode 100755 index c8d38985f707e287301df37a1831012926c6d5e3..bea65996dae165f31f454e1e7fc7b3743e81cd77 GIT binary patch delta 22702 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 RH ./README +## MLG will display the readme with the "-readme" argument +cd ./bin/ +chmod a+x ./MinecraftLandGenerator.jar + +java -jar ./MinecraftLandGenerator.jar -conf + +cd .. +java -jar ./bin/MinecraftLandGenerator.jar -readme README + +rm ./MLG-BuildID diff --git a/src/corrodias/minecraft/landgenerator/Main.java b/src/corrodias/minecraft/landgenerator/Main.java index 3035416..942b3ec 100644 --- a/src/corrodias/minecraft/landgenerator/Main.java +++ b/src/corrodias/minecraft/landgenerator/Main.java @@ -1,9 +1,7 @@ -/* - * To change this template, choose Tools | Templates - * and open the template in the editor. - */ package corrodias.minecraft.landgenerator; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; @@ -16,55 +14,59 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; -//import java.io.OutputStreamWriter; -//import java.util.Date; +import java.math.BigInteger; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLDecoder; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Locale; -//import java.util.Locale; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; + import org.jnbt.CompoundTag; import org.jnbt.IntTag; import org.jnbt.LongTag; import org.jnbt.NBTInputStream; import org.jnbt.NBTOutputStream; import org.jnbt.Tag; -//import java.io.*; //if we want to import everything... -//import java.util.*; /** - * + * * @author Corrodias, Morlok8k, pr0f1x */ public class Main { - //Version Number! - private static final String VERSION = "1.5.1"; + // Version Number! + private static final String VERSION = "1.6.0 Testing 8"; private static final String AUTHORS = "Corrodias, Morlok8k, pr0f1x"; - - private static final String separator = System.getProperty("file.separator"); - //private static final String classpath = System.getProperty("java.class.path"); - //private static final String javaPath = System.getProperty("java.home") + separator + "bin" + separator + "java"; + + private static final String fileSeparator = System.getProperty("file.separator"); + private static final String newLine = System.getProperty("line.separator"); private int increment = 380; private ProcessBuilder minecraft = null; private String javaLine = null; - private static final String defaultJavaLine = "java -Djava.awt.headless=true -Djline.terminal=jline.UnsupportedTerminal -Duser.language=en -Xms1024m -Xmx1024m -Xincgc -jar minecraft_server.jar nogui"; + private static final String defaultJavaLine = + "java -Djava.awt.headless=true -Djline.terminal=jline.UnsupportedTerminal -Duser.language=en" + + " -Xms1024m -Xmx1024m -Xincgc -jar minecraft_server.jar nogui"; private String serverPath = null; private String worldPath = null; private static String worldName = null; private static String doneText = null; private static String preparingText = null; private static String preparingLevel = null; - private static String level_0 = null; //the world - private static String level_1 = null; //the nether - private static String level_2 = null; //future worlds - private static String level_3 = null; + private static String level_0 = null; // the world + private static String level_1 = null; // the nether + private static String level_2 = null; // the end + private static String level_3 = null; // future worlds private static String level_4 = null; private static String level_5 = null; private static String level_6 = null; @@ -80,112 +82,84 @@ public class Main { private static boolean waitSave = false; private static boolean ignoreWarnings = false; private static LongTag randomSeed = null; - + private static String MLG = "[MLG] "; - + private static DateFormat dateFormat = null; private static DateFormat dateFormatBuildID = null; + private static DateFormat dateFormat_MDY = null; private static Date date = null; private static Date MLG_Last_Modified_Date = null; - - + + private static final Class cls = Main.class; + private static String MLGFileName = null; + private static final String rsrcError = "rsrcERROR"; + private static String buildIDFile = "MLG-BuildID"; + private static boolean isCompiledAsJar = false; + private static String MLG_Current_Hash = null; + + @SuppressWarnings("unused") + private static final String MinecraftLandGeneratorConfURL = + "https://raw.github.com/Morlok8k/MinecraftLandGenerator/master/bin/MinecraftLandGenerator.conf"; + private static final String MinecraftLandGeneratorConf = "MinecraftLandGenerator.conf"; + private static final boolean testing = false; // a constant to display more output when debugging - + // REMINDER: because I always forget/mix up languages: // "static" in java means "global" // "final" means "constant" /** - * @param args the command line arguments + * @param args + * the command line arguments */ public static void main(String[] args) { - (new Main()).run(args); //Why? idk, but merging this with run() creates errors, and i'm lazy! + (new Main()).run(args); // Why? idk, but merging this with run() creates + // errors, and i'm lazy! } + /** + * Start MinecraftLandGenerator + * + * @author Corrodias, Morlok8k + * @param args + */ private void run(String[] args) { - - // Lets get a nice Date format for display, and a compact one for telling apart builds. - dateFormat = new SimpleDateFormat("EEEE, MMMM d, yyyy 'at' h:m a zzzz", Locale.ENGLISH); - dateFormatBuildID = new SimpleDateFormat("'BuildID:' (yyMMdd.HHmmssZ)", Locale.ENGLISH); - date = new Date(); - //dateFormat.format(date); - - //Here we attempt to get the last modified date of this compiled .class file from the filesystem! - try { - MLG_Last_Modified_Date = new Date(Main.class.getResource("Main.class").openConnection().getLastModified()); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - //The following displays no matter what happens, so we needed this date stuff to happen first. - + + // Lets get a nice Date format for display, and a compact one for + // telling apart builds. + dateFormat = new SimpleDateFormat("EEEE, MMMM d, yyyy 'at' h:mm a zzzz", Locale.ENGLISH); + dateFormatBuildID = new SimpleDateFormat("'BuildID:' (yyMMdd.HHmmss)", Locale.ENGLISH); + dateFormat_MDY = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH); + date = new Date(); + // dateFormat.format(date); + + readBuildID(); + + //readMe("test.txt"); + + // The following displays no matter what happens, so we needed this date + // stuff to happen first. + + // MLG_Last_Modified_Date = date; + System.out.println("Minecraft Land Generator version " + VERSION); System.out.println(dateFormatBuildID.format(MLG_Last_Modified_Date)); - System.out.println("This version was last modified on " + dateFormat.format(MLG_Last_Modified_Date)); + System.out.println("This version was last modified on " + + dateFormat.format(MLG_Last_Modified_Date)); System.out.println(""); System.out.println("Uses a Minecraft server to generate square land of a specified size."); System.out.println(""); System.out.println(""); - - - // ===================================================================== // INSTRUCTIONS // ===================================================================== - if (args.length == 0 || args[0].equals("-version") || args[0].equals("-help") || args[0].equals("/?")) { - System.out.println("Usage: java -jar MinecraftLandGenerator.jar x y [serverpath] [switches]"); - System.out.println(""); - System.out.println("Arguments:"); - System.out.println(" x : X range to generate"); - System.out.println(" y : Y range to generate"); - System.out.println(" serverpath : the path to the directory in which the server runs (takes precedence over the config file setting)"); - System.out.println(""); - System.out.println("Switches:"); - System.out.println(" -verbose : causes the application to output the server's messages to the console"); - System.out.println(" -v : same as -verbose"); - System.out.println(" -w : Ignore [WARNING] and [SEVERE] messages."); - System.out.println(" -alt : alternate server launch sequence"); - System.out.println(" -a : same as -alt"); - System.out.println(" -i# : override the iteration spawn offset increment (default 300) (example: -i100)"); - System.out.println(" -x# : set the X offset to generate land around (example: -x0)"); - System.out.println(" -y# : set the X offset to generate land around (example: -y0)"); - System.out.println(""); - System.out.println("Other options:"); - System.out.println(" java -jar MinecraftLandGenerator.jar -printspawn"); - System.out.println(" java -jar MinecraftLandGenerator.jar -ps"); - System.out.println(" Outputs the current world's spawn point coordinates."); - System.out.println(""); - System.out.println(" java -jar MinecraftLandGenerator.jar -conf"); - System.out.println(" Generates a MinecraftLandGenerator.conf file."); - System.out.println(""); - System.out.println(" java -jar MinecraftLandGenerator.jar -version"); - System.out.println(" java -jar MinecraftLandGenerator.jar -help"); - System.out.println(" java -jar MinecraftLandGenerator.jar /?"); - System.out.println(" Prints this message."); - System.out.println(""); - System.out.println("When launched with the -conf switch, this application creates a MinecraftLandGenerator.conf file that contains configuration options."); - System.out.println("If this file does not exist or does not contain all required properties, the application will not run."); - System.out.println(""); - System.out.println("MinecraftLandGenerator.conf properties:"); - System.out.println(" Java : The command line to use to launch the server"); - System.out.println(" ServerPath : The path to the directory in which the server runs (can be overridden by the serverpath argument)"); - System.out.println(" Done_Text : The output from the server that tells us that we are done"); - System.out.println(" Preparing_Text : The output from the server that tells us the percentage"); - System.out.println("Preparing_Level : The output from the server that tells us the level it is working on"); - System.out.println(" Level-0 : Name of Level 0: The Overworld"); - System.out.println(" Level-1 : Name of Level 1: The Nether"); - System.out.println(" Level-2 : Name of Level 2: The End"); - System.out.println(" Level-3 : Name of Level 3: (Future Level)"); - System.out.println(" Level-4 : Name of Level 4: (Future Level)"); - System.out.println(" Level-5 : Name of Level 5: (Future Level)"); - System.out.println(" Level-6 : Name of Level 6: (Future Level)"); - System.out.println(" Level-7 : Name of Level 7: (Future Level)"); - System.out.println(" Level-8 : Name of Level 8: (Future Level)"); - System.out.println(" Level-9 : Name of Level 9: (Future Level)"); - System.out.println(" WaitSave : Optional: Wait before saving."); + if (args.length == 0 || args[0].equals("-version") || args[0].equals("-help") + || args[0].equals("/?")) { + + showHelp(true); return; } @@ -194,11 +168,10 @@ public class Main { // STARTUP AND CONFIG // ===================================================================== - // the arguments are apparently okay so far. parse the conf file. if (args[0].equalsIgnoreCase("-conf")) { try { - File config = new File("MinecraftLandGenerator.conf"); + File config = new File(MinecraftLandGeneratorConf); BufferedWriter out = new BufferedWriter(new FileWriter(config)); out.write("#Minecraft Land Generator Configuration File: Version: " + VERSION); out.newLine(); @@ -209,7 +182,7 @@ public class Main { out.newLine(); out.write("#Line to run server:"); out.newLine(); - out.write("Java=" + defaultJavaLine); // reads the default from a constant, makes it easier! + out.write("Java=" + defaultJavaLine); // reads the default from a constant, makes it easier! out.newLine(); out.newLine(); out.write("#Location of server. use \".\" for the same folder as MLG"); @@ -251,33 +224,39 @@ public class Main { out.write("WaitSave=false"); out.newLine(); out.close(); - System.out.println( MLG + "MinecraftLandGenerator.conf file created."); + System.out.println(MLG + MinecraftLandGeneratorConf + " file created."); return; } catch (IOException ex) { - System.err.println( MLG + "Could not create MinecraftLandGenerator.conf."); + System.err.println(MLG + "Could not create " + MinecraftLandGeneratorConf + "."); return; } } else if (args[0].equalsIgnoreCase("-ps") || args[0].equalsIgnoreCase("-printspawn")) { // okay, sorry, this is an ugly hack, but it's just a last-minute feature. printSpawn(); return; + } else if (args[0].equalsIgnoreCase("-build")) { + buildID(); + return; + } else if (args[0].equalsIgnoreCase("-readme")) { + readMe(args[1]); + return; } else if (args.length == 1) { - System.out.println( MLG + "For help, use java -jar MinecraftLandGenerator.jar -help"); + System.out.println(MLG + "For help, use java -jar MinecraftLandGenerator.jar -help"); return; } try { - File config = new File("MinecraftLandGenerator.conf"); + File config = new File(MinecraftLandGeneratorConf); BufferedReader in = new BufferedReader(new FileReader(config)); String line; while ((line = in.readLine()) != null) { int pos = line.indexOf('='); - int end = line.lastIndexOf('#'); //comments, ignored lines - - if (end == -1){ // If we have no hash sign, then we read till the end of the line + int end = line.lastIndexOf('#'); // comments, ignored lines + + if (end == -1) { // If we have no hash sign, then we read till the end of the line end = line.length(); } - if (end <= pos){ // If hash is before the '=', we may have a issue... it should be fine, cause we check for issues next, but lets make sure. + if (end <= pos) { // If hash is before the '=', we may have an issue... it should be fine, cause we check for issues next, but lets make sure. end = line.length(); } @@ -292,24 +271,6 @@ public class Main { preparingText = line.substring(pos + 1, end); } else if (line.substring(0, pos).toLowerCase().equals("preparing_level")) { preparingLevel = line.substring(pos + 1, end); - } else if (line.substring(0, pos).toLowerCase().equals("dim-1")) { //old, but still works - level_1 = line.substring(pos + 1, end); - } else if (line.substring(0, pos).toLowerCase().equals("dim-2")) { //to be removed later! - level_2 = line.substring(pos + 1, end); - } else if (line.substring(0, pos).toLowerCase().equals("dim-3")) { - level_3 = line.substring(pos + 1, end); - } else if (line.substring(0, pos).toLowerCase().equals("dim-4")) { - level_4 = line.substring(pos + 1, end); - } else if (line.substring(0, pos).toLowerCase().equals("dim-5")) { - level_5 = line.substring(pos + 1, end); - } else if (line.substring(0, pos).toLowerCase().equals("dim-6")) { - level_6 = line.substring(pos + 1, end); - } else if (line.substring(0, pos).toLowerCase().equals("dim-7")) { - level_7 = line.substring(pos + 1, end); - } else if (line.substring(0, pos).toLowerCase().equals("dim-8")) { - level_8 = line.substring(pos + 1, end); - } else if (line.substring(0, pos).toLowerCase().equals("dim-9")) { //end of deprecated names - level_9 = line.substring(pos + 1, end); } else if (line.substring(0, pos).toLowerCase().equals("level-0")) { level_0 = line.substring(pos + 1, end); } else if (line.substring(0, pos).toLowerCase().equals("level-1")) { @@ -325,70 +286,74 @@ public class Main { } else if (line.substring(0, pos).toLowerCase().equals("level-6")) { level_6 = line.substring(pos + 1, end); } else if (line.substring(0, pos).toLowerCase().equals("level-7")) { - level_7 = line.substring(pos + 1, end); + level_7 = line.substring(pos + 1, end); } else if (line.substring(0, pos).toLowerCase().equals("level-8")) { level_8 = line.substring(pos + 1, end); } else if (line.substring(0, pos).toLowerCase().equals("level-9")) { level_9 = line.substring(pos + 1, end); } else if (line.substring(0, pos).toLowerCase().equals("waitsave")) { String wstmp = line.toLowerCase().substring(pos + 1, end); - if (wstmp.equals( "true" ) ){ - waitSave = true; - } else { - waitSave = false; - } + if (wstmp.equals("true")) { + waitSave = true; + } else { + waitSave = false; + } } } } in.close(); if (testing) { - System.out.println( MLG + "[TEST] Test Output: Reading of Config File "); - System.out.println( MLG + "[TEST] serverPath: " + serverPath); - System.out.println( MLG + "[TEST] javaLine: " + javaLine); - System.out.println( MLG + "[TEST] doneText: " + doneText); - System.out.println( MLG + "[TEST] preparingText: " + preparingText); - System.out.println( MLG + "[TEST] preparingLevel: " + preparingLevel); - System.out.println( MLG + "[TEST] level_0: " + level_0); - System.out.println( MLG + "[TEST] level_1: " + level_1); - System.out.println( MLG + "[TEST] level_2: " + level_2); - System.out.println( MLG + "[TEST] level_3: " + level_3); - System.out.println( MLG + "[TEST] level_4: " + level_4); - System.out.println( MLG + "[TEST] level_5: " + level_5); - System.out.println( MLG + "[TEST] level_6: " + level_6); - System.out.println( MLG + "[TEST] level_7: " + level_7); - System.out.println( MLG + "[TEST] level_8: " + level_8); - System.out.println( MLG + "[TEST] level_9: " + level_9); - System.out.println( MLG + "[TEST] waitSave: " + waitSave); + System.out.println(MLG + "[TEST] Test Output: Reading of Config File "); + System.out.println(MLG + "[TEST] serverPath: " + serverPath); + System.out.println(MLG + "[TEST] javaLine: " + javaLine); + System.out.println(MLG + "[TEST] doneText: " + doneText); + System.out.println(MLG + "[TEST] preparingText: " + preparingText); + System.out.println(MLG + "[TEST] preparingLevel: " + preparingLevel); + System.out.println(MLG + "[TEST] level_0: " + level_0); + System.out.println(MLG + "[TEST] level_1: " + level_1); + System.out.println(MLG + "[TEST] level_2: " + level_2); + System.out.println(MLG + "[TEST] level_3: " + level_3); + System.out.println(MLG + "[TEST] level_4: " + level_4); + System.out.println(MLG + "[TEST] level_5: " + level_5); + System.out.println(MLG + "[TEST] level_6: " + level_6); + System.out.println(MLG + "[TEST] level_7: " + level_7); + System.out.println(MLG + "[TEST] level_8: " + level_8); + System.out.println(MLG + "[TEST] level_9: " + level_9); + System.out.println(MLG + "[TEST] waitSave: " + waitSave); } - - boolean oldConf = false; //This next section checks to see if we have a old configuration file (or none!) - - if (serverPath == null || javaLine == null) { //MLG 1.2 Check for a valid .conf file. - System.err.println( MLG + "MinecraftLandGenerator.conf does not contain all required properties. Making New File!"); // Please recreate it by running this application with -conf. - //return; //We no longer quit. We generate a new one with defaults. + + boolean oldConf = false; // This next section checks to see if we have a old configuration file (or none!) + + if (serverPath == null || javaLine == null) { // MLG 1.2 Check for a valid .conf file. + System.err.println(MLG + MinecraftLandGeneratorConf + + " does not contain all required properties. Making New File!"); + // Please recreate it by running this application with -conf. + // return; + // We no longer quit. We generate a new one with defaults. + javaLine = defaultJavaLine; serverPath = "."; oldConf = true; } - - if (doneText == null) { //MLG 1.3 + + if (doneText == null) { // MLG 1.3 oldConf = true; - } else if ( preparingText == null) { //MLG 1.4? + } else if (preparingText == null) { // MLG 1.4? oldConf = true; - } else if (preparingLevel == null){ //MLG 1.4? + } else if (preparingLevel == null) { // MLG 1.4? oldConf = true; - } else if (level_1 == null) { //MLG 1.5.0? + } else if (level_1 == null) { // MLG 1.5.0? oldConf = true; - } else if (level_0 == null) { //MLG 1.5.1 + } else if (level_0 == null) { // MLG 1.5.1 oldConf = true; } - - + if (oldConf) { - System.err.println( MLG + "Old Version of MinecraftLandGenerator.conf found. Updating..."); + System.err.println(MLG + "Old Version of " + MinecraftLandGeneratorConf + + " found. Updating..."); try { - File configUpdate = new File("MinecraftLandGenerator.conf"); + File configUpdate = new File(MinecraftLandGeneratorConf); BufferedWriter out = new BufferedWriter(new FileWriter(configUpdate)); out.write("#Minecraft Land Generator Configuration File: Version: " + VERSION); out.newLine(); @@ -441,34 +406,39 @@ public class Main { out.write("WaitSave=false"); out.newLine(); out.close(); - System.out.println( MLG + "MinecraftLandGenerator.conf file created."); - + System.out.println(MLG + MinecraftLandGeneratorConf + " file created."); + System.out.println(""); int count = 0; while (count <= 100) { System.out.print(count + "% "); - + try { - Thread.sleep( 1000 ); - } catch ( InterruptedException e ) { - e.printStackTrace(); - } + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } count += 10; } System.out.println(""); return; - + } catch (IOException ex) { - System.err.println( MLG + "Could not create MinecraftLandGenerator.conf."); + System.err + .println(MLG + "Could not create " + MinecraftLandGeneratorConf + "."); return; } } - + } catch (FileNotFoundException ex) { - System.out.println( MLG + "Could not find MinecraftLandGenerator.conf. It is recommended that you run the application with the -conf option to create it."); + System.out + .println(MLG + + "Could not find " + + MinecraftLandGeneratorConf + + ". It is recommended that you run the application with the -conf option to create it."); return; } catch (IOException ex) { - System.err.println( MLG + "Could not read MinecraftLandGenerator.conf"); + System.err.println(MLG + "Could not read " + MinecraftLandGeneratorConf + "."); return; } @@ -477,13 +447,13 @@ public class Main { xRange = Integer.parseInt(args[0]); yRange = Integer.parseInt(args[1]); } catch (NumberFormatException ex) { - System.err.println( MLG + "Invalid X or Y argument."); + System.err.println(MLG + "Invalid X or Y argument."); return; } - - verbose = false; // Verifing that these vars are false - alternate = false; // before changing them... - + + verbose = false; // Verifing that these vars are false + alternate = false; // before changing them... + // This is embarrassing. Don't look. try { for (int i = 0; i < args.length - 2; i++) { @@ -495,7 +465,7 @@ public class Main { } else if (nextSwitch.startsWith("-w")) { ignoreWarnings = true; } else if (nextSwitch.equals("-alt") || nextSwitch.equals("-a")) { - System.out.println( MLG + "Using Alternate Launching..."); + System.out.println(MLG + "Using Alternate Launching..."); alternate = true; } else if (nextSwitch.startsWith("-x")) { xOffset = Integer.valueOf(args[i + 2].substring(2)); @@ -506,7 +476,7 @@ public class Main { } } } catch (NumberFormatException ex) { - System.err.println( MLG + "Invalid -i switch value."); + System.err.println(MLG + "Invalid -i switch value."); return; } @@ -514,28 +484,31 @@ public class Main { // verify that we ended up with a good server path, either from the file or from an argument. File file = new File(serverPath); if (!file.exists() || !file.isDirectory()) { - System.err.println( MLG + "The server directory is invalid: " + serverPath); + System.err.println(MLG + "The server directory is invalid: " + serverPath); return; } } try { // read the name of the current world from the server.properties file - BufferedReader props = new BufferedReader(new FileReader(new File(serverPath + separator + "server.properties"))); + BufferedReader props = + new BufferedReader(new FileReader(new File(serverPath + fileSeparator + + "server.properties"))); String line; while ((line = props.readLine()) != null) { int pos = line.indexOf('='); if (pos != -1) { if (line.substring(0, pos).toLowerCase().equals("level-name")) { - worldPath = serverPath + separator + line.substring(pos + 1); + worldPath = serverPath + fileSeparator + line.substring(pos + 1); worldName = line.substring(pos + 1); } - + } } } catch (FileNotFoundException ex) { - System.err.println( MLG + "Could not open " + serverPath + separator + "server.properties"); + System.err.println(MLG + "Could not open " + serverPath + fileSeparator + + "server.properties"); return; } catch (IOException ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); @@ -543,10 +516,12 @@ public class Main { } { - File backupLevel = new File(worldPath + separator + "level_backup.dat"); + File backupLevel = new File(worldPath + fileSeparator + "level_backup.dat"); if (backupLevel.exists()) { - System.err.println( MLG + "There is a level_backup.dat file left over from a previous attempt that failed. You should go determine whether to keep the current level.dat" - + " or restore the backup."); + System.err + .println(MLG + + "There is a level_backup.dat file left over from a previous attempt that failed. You should go determine whether to keep the current level.dat" + + " or restore the backup."); return; } } @@ -555,31 +530,33 @@ public class Main { // PROCESSING // ===================================================================== - System.out.println( MLG + "Processing world \"" + worldPath + "\", in " + increment + " block increments, with: " + javaLine); - //System.out.println( MLG + "Processing \"" + worldName + "\"..."); - + System.out.println(MLG + "Processing world \"" + worldPath + "\", in " + increment + + " block increments, with: " + javaLine); + // System.out.println( MLG + "Processing \"" + worldName + "\"..."); + System.out.println(""); // prepare our two ProcessBuilders - //minecraft = new ProcessBuilder(javaLine, "-Xms1024m", "-Xmx1024m", "-jar", jarFile, "nogui"); + // minecraft = new ProcessBuilder(javaLine, "-Xms1024m", "-Xmx1024m", + // "-jar", jarFile, "nogui"); minecraft = new ProcessBuilder(javaLine.split("\\s")); // is this always going to work? i don't know. minecraft.directory(new File(serverPath)); minecraft.redirectErrorStream(true); try { - System.out.println( MLG + "Launching server once to make sure there is a world."); + System.out.println(MLG + "Launching server once to make sure there is a world."); runMinecraft(minecraft, verbose, alternate, javaLine); System.out.println(""); - File serverLevel = new File(worldPath + separator + "level.dat"); - File backupLevel = new File(worldPath + separator + "level_backup.dat"); + File serverLevel = new File(worldPath + fileSeparator + "level.dat"); + File backupLevel = new File(worldPath + fileSeparator + "level_backup.dat"); - System.out.println( MLG + "Backing up level.dat to level_backup.dat."); + System.out.println(MLG + "Backing up level.dat to level_backup.dat."); copyFile(serverLevel, backupLevel); System.out.println(""); Integer[] spawn = getSpawn(serverLevel); - System.out.println( MLG + "Spawn point detected: [" + spawn[0] + ", " + spawn[2] + "]"); + System.out.println(MLG + "Spawn point detected: [" + spawn[0] + ", " + spawn[2] + "]"); { boolean overridden = false; if (xOffset == null) { @@ -593,7 +570,8 @@ public class Main { overridden = true; } if (overridden) { - System.out.println( MLG + "Centering land generation on [" + xOffset + ", " + yOffset + "] due to switches."); + System.out.println(MLG + "Centering land generation on [" + xOffset + ", " + + yOffset + "] due to switches."); } } System.out.println(""); @@ -602,35 +580,85 @@ public class Main { int currentIteration = 0; long differenceTime = System.currentTimeMillis(); - Long[] timeTracking = new Long[]{differenceTime, differenceTime, differenceTime, differenceTime}; + Long[] timeTracking = + new Long[] { differenceTime, differenceTime, differenceTime, differenceTime }; for (int currentX = 0 - xRange / 2; currentX <= xRange / 2; currentX += increment) { for (int currentY = 0 - yRange / 2; currentY <= yRange / 2; currentY += increment) { currentIteration++; - - - - System.out.println( MLG + "Setting spawn to [" + Integer.toString(currentX + xOffset) + ", " + Integer.toString(currentY + yOffset) + "] (" + currentIteration + "/" + totalIterations + ") " + Float.toString((Float.parseFloat(Integer.toString(currentIteration)) / Float.parseFloat(Integer.toString(totalIterations))) * 100) + "% Done" ); // Time Remaining estimate + + System.out + .println(MLG + + "Setting spawn to [" + + Integer.toString(currentX + xOffset) + + ", " + + Integer.toString(currentY + yOffset) + + "] (" + + currentIteration + + "/" + + totalIterations + + ") " + + Float.toString((Float.parseFloat(Integer + .toString(currentIteration)) / Float.parseFloat(Integer + .toString(totalIterations))) * 100) + "% Done"); // Time + // Remaining + // estimate timeTracking[0] = timeTracking[1]; timeTracking[1] = timeTracking[2]; timeTracking[2] = timeTracking[3]; timeTracking[3] = System.currentTimeMillis(); if (currentIteration >= 4) { - differenceTime = (timeTracking[3] - timeTracking[0]) / 3; // well, this is what it boils down to + differenceTime = (timeTracking[3] - timeTracking[0]) / 3; // well, + // this + // is + // what + // it + // boils + // down + // to differenceTime *= 1 + (totalIterations - currentIteration); - System.out.println( MLG + String.format("Estimated time remaining: %dh%dm%ds", - differenceTime / (1000 * 60 * 60), (differenceTime % (1000 * 60 * 60)) / (1000 * 60), ((differenceTime % (1000 * 60 * 60)) % (1000 * 60)) / 1000)); + System.out + .println(MLG + + String.format( + "Estimated time remaining: %dh%dm%ds", + differenceTime / (1000 * 60 * 60), + (differenceTime % (1000 * 60 * 60)) / (1000 * 60), + ((differenceTime % (1000 * 60 * 60)) % (1000 * 60)) / 1000)); } else if (currentIteration == 3) { - differenceTime = (timeTracking[3] - timeTracking[1]) / 2; // well, this is what it boils down to + differenceTime = (timeTracking[3] - timeTracking[1]) / 2; // well, + // this + // is + // what + // it + // boils + // down + // to differenceTime *= 1 + (totalIterations - currentIteration); - System.out.println( MLG + String.format("Estimated time remaining: %dh%dm%ds", - differenceTime / (1000 * 60 * 60), (differenceTime % (1000 * 60 * 60)) / (1000 * 60), ((differenceTime % (1000 * 60 * 60)) % (1000 * 60)) / 1000)); + System.out + .println(MLG + + String.format( + "Estimated time remaining: %dh%dm%ds", + differenceTime / (1000 * 60 * 60), + (differenceTime % (1000 * 60 * 60)) / (1000 * 60), + ((differenceTime % (1000 * 60 * 60)) % (1000 * 60)) / 1000)); } else if (currentIteration == 2) { - differenceTime = (timeTracking[3] - timeTracking[2]); // well, this is what it boils down to + differenceTime = (timeTracking[3] - timeTracking[2]); // well, + // this + // is + // what + // it + // boils + // down + // to differenceTime *= 1 + (totalIterations - currentIteration); - System.out.println( MLG + String.format("Estimated time remaining: %dh%dm%ds", - differenceTime / (1000 * 60 * 60), (differenceTime % (1000 * 60 * 60)) / (1000 * 60), ((differenceTime % (1000 * 60 * 60)) % (1000 * 60)) / 1000)); + System.out + .println(MLG + + String.format( + "Estimated time remaining: %dh%dm%ds", + differenceTime / (1000 * 60 * 60), + (differenceTime % (1000 * 60 * 60)) / (1000 * 60), + ((differenceTime % (1000 * 60 * 60)) % (1000 * 60)) / 1000)); } else if (currentIteration <= 1) { - System.out.println( MLG + "Estimated time remaining: Caculating..."); + System.out.println(MLG + "Estimated time remaining: Calculating..."); } // Set the spawn point @@ -642,10 +670,10 @@ public class Main { } } - System.out.println( MLG + "Finished generating chunks."); + System.out.println(MLG + "Finished generating chunks."); copyFile(backupLevel, serverLevel); backupLevel.delete(); - System.out.println( MLG + "Restored original level.dat."); + System.out.println(MLG + "Restored original level.dat."); } catch (IOException ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); } @@ -657,19 +685,28 @@ public class Main { CompoundTag originalTopLevelTag = (CompoundTag) input.readTag(); input.close(); - Map originalData = ((CompoundTag) originalTopLevelTag.getValue().get("Data")).getValue(); - // This is our map of data. It is an unmodifiable map, for some reason, so we have to make a copy. + Map originalData = + ((CompoundTag) originalTopLevelTag.getValue().get("Data")).getValue(); + // This is our map of data. It is an unmodifiable map, for some + // reason, so we have to make a copy. Map newData = new LinkedHashMap(originalData); - // .get() a couple of values, just to make sure we're dealing with a valid level file, here. Good for debugging, too. + // .get() a couple of values, just to make sure we're dealing with a + // valid level file, here. Good for debugging, too. IntTag spawnX = (IntTag) newData.get("SpawnX"); IntTag spawnY = (IntTag) newData.get("SpawnY"); IntTag spawnZ = (IntTag) newData.get("SpawnZ"); - + randomSeed = (LongTag) newData.get("RandomSeed"); - System.out.println( MLG + "Seed: " + randomSeed.getValue()); //lets output the seed, cause why not? - - - Integer[] ret = new Integer[]{spawnX.getValue(), spawnY.getValue(), spawnZ.getValue()}; + System.out.println(MLG + "Seed: " + randomSeed.getValue()); // lets + // output + // the + // seed, + // cause + // why + // not? + + Integer[] ret = + new Integer[] { spawnX.getValue(), spawnY.getValue(), spawnZ.getValue() }; return ret; } catch (ClassCastException ex) { throw new IOException("Invalid level format."); @@ -679,14 +716,18 @@ public class Main { } /** - * Changes the spawn point in the given Alpha/Beta level to the given coordinates. - * Note that, in Minecraft levels, the Y coordinate is height, while Z is - * what may normally be thought of as Y. - * @param level the level file to change the spawn point in - * @param x the new X value - * @param z the new Y value - * @param y the new Z value - * @throws IOException if there are any problems reading/writing the file + * Changes the spawn point in the given Alpha/Beta level to the given coordinates. Note that, in Minecraft levels, the Y coordinate is height, while Z is what may normally be thought of as Y. + * + * @param level + * the level file to change the spawn point in + * @param x + * the new X value + * @param z + * the new Y value + * @param y + * the new Z value + * @throws IOException + * if there are any problems reading/writing the file */ protected static void setSpawn(File level, Integer x, Integer y, Integer z) throws IOException { try { @@ -694,40 +735,64 @@ public class Main { CompoundTag originalTopLevelTag = (CompoundTag) input.readTag(); input.close(); -// -// Structure: -// -//TAG_Compound("Data"): World data. -// * TAG_Long("Time"): Stores the current "time of day" in ticks. There are 20 ticks per real-life second, and 24000 ticks per Minecraft day, making the day length 20 minutes. 0 appears to be sunrise, 12000 sunset and 24000 sunrise again. -// * TAG_Long("LastPlayed"): Stores the Unix time stamp (in milliseconds) when the player saved the game. -// * TAG_Compound("Player"): Player entity information. See Entity Format and Mob Entity Format for details. Has additional elements: -// o TAG_List("Inventory"): Each TAG_Compound in this list defines an item the player is carrying, holding, or wearing as armor. -// + TAG_Compound: Inventory item data -// # TAG_Short("id"): Item or Block ID. -// # TAG_Short("Damage"): The amount of wear each item has suffered. 0 means undamaged. When the Damage exceeds the item's durability, it breaks and disappears. Only tools and armor accumulate damage normally. -// # TAG_Byte("Count"): Number of items stacked in this inventory slot. Any item can be stacked, including tools, armor, and vehicles. Range is 1-255. Values above 127 are not displayed in-game. -// # TAG_Byte("Slot"): Indicates which inventory slot this item is in. -// o TAG_Int("Score"): Current score, doesn't appear to be implemented yet. Always 0. -// * TAG_Int("SpawnX"): X coordinate of the player's spawn position. Default is 0. -// * TAG_Int("SpawnY"): Y coordinate of the player's spawn position. Default is 64. -// * TAG_Int("SpawnZ"): Z coordinate of the player's spawn position. Default is 0. -// * TAG_Byte("SnowCovered"): 1 enables, 0 disables, see Winter Mode //Old! -// * TAG_Long("SizeOnDisk"): Estimated size of the entire world in bytes. -// * TAG_Long("RandomSeed"): Random number providing the Random Seed for the terrain. -// + // + // Structure: + // + // TAG_Compound("Data"): World data. + // * TAG_Long("Time"): Stores the current "time of day" in ticks. + // There are 20 ticks per real-life second, and 24000 ticks per + // Minecraft day, making the day length 20 minutes. 0 appears to be + // sunrise, 12000 sunset and 24000 sunrise again. + // * TAG_Long("LastPlayed"): Stores the Unix time stamp (in + // milliseconds) when the player saved the game. + // * TAG_Compound("Player"): Player entity information. See Entity + // Format and Mob Entity Format for details. Has additional + // elements: + // o TAG_List("Inventory"): Each TAG_Compound in this list defines + // an item the player is carrying, holding, or wearing as armor. + // + TAG_Compound: Inventory item data + // # TAG_Short("id"): Item or Block ID. + // # TAG_Short("Damage"): The amount of wear each item has suffered. + // 0 means undamaged. When the Damage exceeds the item's durability, + // it breaks and disappears. Only tools and armor accumulate damage + // normally. + // # TAG_Byte("Count"): Number of items stacked in this inventory + // slot. Any item can be stacked, including tools, armor, and + // vehicles. Range is 1-255. Values above 127 are not displayed + // in-game. + // # TAG_Byte("Slot"): Indicates which inventory slot this item is + // in. + // o TAG_Int("Score"): Current score, doesn't appear to be + // implemented yet. Always 0. + // * TAG_Int("SpawnX"): X coordinate of the player's spawn position. + // Default is 0. + // * TAG_Int("SpawnY"): Y coordinate of the player's spawn position. + // Default is 64. + // * TAG_Int("SpawnZ"): Z coordinate of the player's spawn position. + // Default is 0. + // * TAG_Byte("SnowCovered"): 1 enables, 0 disables, see Winter Mode + // //Old! + // * TAG_Long("SizeOnDisk"): Estimated size of the entire world in + // bytes. + // * TAG_Long("RandomSeed"): Random number providing the Random Seed + // for the terrain. + // - Map originalData = ((CompoundTag) originalTopLevelTag.getValue().get("Data")).getValue(); - // This is our map of data. It is an unmodifiable map, for some reason, so we have to make a copy. + Map originalData = + ((CompoundTag) originalTopLevelTag.getValue().get("Data")).getValue(); + // This is our map of data. It is an unmodifiable map, for some + // reason, so we have to make a copy. Map newData = new LinkedHashMap(originalData); - // .get() a couple of values, just to make sure we're dealing with a valid level file, here. Good for debugging, too. + // .get() a couple of values, just to make sure we're dealing with a + // valid level file, here. Good for debugging, too. @SuppressWarnings("unused") - IntTag spawnX = (IntTag) newData.get("SpawnX"); // we never use these... Its only here for potential debugging. + IntTag spawnX = (IntTag) newData.get("SpawnX"); // we never use these... Its only here for potential debugging. @SuppressWarnings("unused") - IntTag spawnY = (IntTag) newData.get("SpawnY"); // but whatever... so I (Morlok8k) suppressed these warnings. + IntTag spawnY = (IntTag) newData.get("SpawnY"); // but whatever... so I (Morlok8k) suppressed these warnings. @SuppressWarnings("unused") - IntTag spawnZ = (IntTag) newData.get("SpawnZ"); // I don't want to remove existing code, either by myself (Morlok8k) or Corrodias - + IntTag spawnZ = (IntTag) newData.get("SpawnZ"); // I don't want to remove existing code, either by myself (Morlok8k) or Corrodias + newData.put("SpawnX", new IntTag("SpawnX", x)); newData.put("SpawnY", new IntTag("SpawnY", y)); newData.put("SpawnZ", new IntTag("SpawnZ", z)); @@ -749,78 +814,80 @@ public class Main { } /** - * Starts the process in the given ProcessBuilder, monitors its output for a - * "[INFO] Done!" message, and sends it a "stop\r\n" message. One message is printed - * to the console before launching and one is printed to the console when the - * Done! message is detected. If "verbose" is true, the process's output will - * also be printed to the console. + * Starts the process in the given ProcessBuilder, monitors its output for a "[INFO] Done!" message, and sends it a "stop\r\n" message. One message is printed to the console before launching and + * one is printed to the console when the Done! message is detected. If "verbose" is true, the process's output will also be printed to the console. + * * @param minecraft * @param verbose * @throws IOException */ - protected static void runMinecraft(ProcessBuilder minecraft, boolean verbose, boolean alternate, String javaLine) throws IOException { - System.out.println( MLG + "Starting server."); - + protected static void runMinecraft(ProcessBuilder minecraft, boolean verbose, + boolean alternate, String javaLine) throws IOException { + System.out.println(MLG + "Starting server."); + boolean warning = false; - + // monitor output and print to console where required. // STOP the server when it's done. - - // Damn it Java! I hate you so much! + + // Damn it Java! I hate you so much! // I can't reuse code the way I want to, like in other langauges. // So, here is a bunch of duplicate code... // Stupid compile errors... - - if (alternate) { //Alternate - a replication (slightly stripped down) of MLG 1.3.0's code. simplest code possible. - System.out.println( MLG + "Alternate Launch"); + + if (alternate) { // Alternate - a replication (slightly stripped down) + // of MLG 1.3.0's code. simplest code possible. + System.out.println(MLG + "Alternate Launch"); Process process = minecraft.start(); // monitor output and print to console where required. // STOP the server when it's done. - BufferedReader pOut = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader pOut = + new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = pOut.readLine()) != null) { System.out.println(line); - if (line.contains(doneText)) { //EDITED By Morlok8k for Minecraft 1.3+ Beta + if (line.contains(doneText)) { // EDITED By Morlok8k for + // Minecraft 1.3+ Beta OutputStream outputStream = process.getOutputStream(); if (waitSave) { - System.out.println( MLG + "Waiting 30 seconds to save."); - - int count = 1; + System.out.println(MLG + "Waiting 30 seconds to save."); + + int count = 1; while (count <= 30) { System.out.print("."); - + try { - Thread.sleep( 1000 ); - } catch ( InterruptedException e ) { - e.printStackTrace(); - } + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } count += 1; } System.out.println(""); } - - System.out.println( MLG + "Saving server data..."); - byte[] saveall = {'s', 'a', 'v', 'e', '-', 'a', 'l', 'l', '\r', '\n'}; + + System.out.println(MLG + "Saving server data..."); + byte[] saveall = { 's', 'a', 'v', 'e', '-', 'a', 'l', 'l', '\r', '\n' }; outputStream.write(saveall); outputStream.flush(); - byte[] stop = {'s', 't', 'o', 'p', '\r', '\n'}; - - System.out.println( MLG + "Stopping server..." ); - + byte[] stop = { 's', 't', 'o', 'p', '\r', '\n' }; + + System.out.println(MLG + "Stopping server..."); + outputStream.write(stop); outputStream.flush(); if (waitSave) { - System.out.println( MLG + "Waiting 10 seconds to save."); - int count = 1; + System.out.println(MLG + "Waiting 10 seconds to save."); + int count = 1; while (count <= 10) { System.out.print("."); - + try { - Thread.sleep( 1000 ); - } catch ( InterruptedException e ) { - e.printStackTrace(); - } + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } count += 1; } System.out.println(""); @@ -828,166 +895,192 @@ public class Main { } } // readLine() returns null when the process exits - - } else { //start minecraft server normally! + + } else { // start minecraft server normally! Process process = minecraft.start(); if (verbose) { - System.out.println( MLG + "Started Server."); + System.out.println(MLG + "Started Server."); } - BufferedReader pOut = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedReader pOut = + new BufferedReader(new InputStreamReader(process.getInputStream())); if (verbose) { - System.out.println( MLG + "Accessing Server Output..."); + System.out.println(MLG + "Accessing Server Output..."); } - + String line = null; - - byte[] stop = {'s', 't', 'o', 'p', '\r', '\n'}; //Moved here, so this code wont run every loop, thus Faster! - //and no, i can't use a string here! - - byte[] saveAll = {'s', 'a', 'v', 'e', '-', 'a', 'l', 'l', '\r', '\n'}; - - OutputStream outputStream = process.getOutputStream(); //moved here to remove some redundancy - + + byte[] stop = { 's', 't', 'o', 'p', '\r', '\n' }; // Moved here, so + // this code + // wont run + // every loop, + // thus Faster! + // and no, i can't use a string here! + + byte[] saveAll = { 's', 'a', 'v', 'e', '-', 'a', 'l', 'l', '\r', '\n' }; + + OutputStream outputStream = process.getOutputStream(); // moved here + // to remove + // some + // redundancy while ((line = pOut.readLine()) != null) { if (verbose) { - if (line.contains("[INFO]")){ + if (line.contains("[INFO]")) { System.out.println(line.substring(line.lastIndexOf("]") + 2)); } else { System.out.println(line); } - } else if (line.contains(preparingText)){ + } else if (line.contains(preparingText)) { System.out.print(line.substring(line.length() - 3, line.length()) + "... "); - } else if (line.contains(preparingLevel)){ - if (line.contains("level 0")) { //"Preparing start region for level 0" - System.out.println("\r\n" + worldName + ": " + level_0 + ":"); - } else if (line.contains("level 1")) { //"Preparing start region for level 1" - System.out.println("\r\n" + worldName + ": " + level_1 + ":"); - } else if (line.contains("level 2")) { //"Preparing start region for level 2" - System.out.println("\r\n" + worldName + ": " + level_2 + ":"); - } else if (line.contains("level 3")) { //"Preparing start region for level 3" - System.out.println("\r\n" + worldName + ": " + level_3 + ":"); - } else if (line.contains("level 4")) { //"Preparing start region for level 4" - System.out.println("\r\n" + worldName + ": " + level_4 + ":"); - } else if (line.contains("level 5")) { //"Preparing start region for level 5" - System.out.println("\r\n" + worldName + ": " + level_5 + ":"); - } else if (line.contains("level 6")) { //"Preparing start region for level 6" - System.out.println("\r\n" + worldName + ": " + level_6 + ":"); - } else if (line.contains("level 7")) { //"Preparing start region for level 7" - System.out.println("\r\n" + worldName + ": " + level_7 + ":"); - } else if (line.contains("level 8")) { //"Preparing start region for level 8" - System.out.println("\r\n" + worldName + ": " + level_8 + ":"); - } else if (line.contains("level 9")) { //"Preparing start region for level 9" - System.out.println("\r\n" + worldName + ": " + level_9 + ":"); + } else if (line.contains(preparingLevel)) { + if (line.contains("level 0")) { // "Preparing start region for level 0" + System.out.println("\r\n" + MLG + worldName + ": " + level_0 + ":"); + } else if (line.contains("level 1")) { // "Preparing start region for level 1" + System.out.println("\r\n" + MLG + worldName + ": " + level_1 + ":"); + } else if (line.contains("level 2")) { // "Preparing start region for level 2" + System.out.println("\r\n" + MLG + worldName + ": " + level_2 + ":"); + } else if (line.contains("level 3")) { // "Preparing start region for level 3" + System.out.println("\r\n" + MLG + worldName + ": " + level_3 + ":"); + } else if (line.contains("level 4")) { // "Preparing start region for level 4" + System.out.println("\r\n" + MLG + worldName + ": " + level_4 + ":"); + } else if (line.contains("level 5")) { // "Preparing start region for level 5" + System.out.println("\r\n" + MLG + worldName + ": " + level_5 + ":"); + } else if (line.contains("level 6")) { // "Preparing start region for level 6" + System.out.println("\r\n" + MLG + worldName + ": " + level_6 + ":"); + } else if (line.contains("level 7")) { // "Preparing start region for level 7" + System.out.println("\r\n" + MLG + worldName + ": " + level_7 + ":"); + } else if (line.contains("level 8")) { // "Preparing start region for level 8" + System.out.println("\r\n" + MLG + worldName + ": " + level_8 + ":"); + } else if (line.contains("level 9")) { // "Preparing start region for level 9" + System.out.println("\r\n" + MLG + worldName + ": " + level_9 + ":"); } else { System.out.println(line.substring(line.lastIndexOf("]") + 2)); } } - - if (line.contains(doneText)) { // now this is configurable! + + if (line.contains(doneText)) { // now this is configurable! System.out.println(""); - if ( waitSave ) { - System.out.println( MLG + "Waiting 30 seconds to save." ); + if (waitSave) { + System.out.println(MLG + "Waiting 30 seconds to save."); int count = 1; while (count <= 30) { System.out.print("."); - + try { - Thread.sleep( 1000 ); - } catch ( InterruptedException e ) { - e.printStackTrace(); - } + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } count += 1; } System.out.println(""); } - System.out.println( MLG + "Saving server data."); + System.out.println(MLG + "Saving server data."); outputStream.write(saveAll); outputStream.flush(); - - System.out.println( MLG + "Stopping server."); - //OutputStream outputStream = process.getOutputStream(); + + System.out.println(MLG + "Stopping server."); + // OutputStream outputStream = process.getOutputStream(); outputStream.write(stop); outputStream.flush(); - //outputStream.close(); + // outputStream.close(); - if ( waitSave ) { - System.out.println( MLG + "Waiting 10 seconds to save." ); + if (waitSave) { + System.out.println(MLG + "Waiting 10 seconds to save."); int count = 1; while (count <= 10) { System.out.print("."); - + try { - Thread.sleep( 1000 ); - } catch ( InterruptedException e ) { - e.printStackTrace(); - } + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } count += 1; } System.out.println(""); } } if (ignoreWarnings == false) { - if (line.contains("[WARNING]")) { //If we have a warning, stop... + if (line.contains("[WARNING]")) { // If we have a warning, + // stop... System.out.println(""); - System.out.println( MLG + "Warning found: Stopping Minecraft Land Generator"); - if (verbose == false) { //If verbose is true, we already displayed it. + System.out + .println(MLG + "Warning found: Stopping Minecraft Land Generator"); + if (verbose == false) { // If verbose is true, we + // already displayed it. System.out.println(line); } System.out.println(""); - System.out.println( MLG + "Forcing Save..."); - outputStream.write(saveAll); - outputStream.flush(); - //OutputStream outputStream = process.getOutputStream(); - outputStream.write(stop); //if the warning was a fail to bind to port, we may need to write stop twice! + System.out.println(MLG + "Forcing Save..."); + outputStream.write(saveAll); + outputStream.flush(); + // OutputStream outputStream = + // process.getOutputStream(); + outputStream.write(stop); // if the warning was a fail + // to bind to port, we may + // need to write stop twice! outputStream.flush(); outputStream.write(stop); outputStream.flush(); - //outputStream.close(); + // outputStream.close(); warning = true; - //System.exit(1); + // System.exit(1); } - if (line.contains("[SEVERE]")) { //If we have a severe error, stop... + if (line.contains("[SEVERE]")) { // If we have a severe + // error, stop... System.out.println(""); - System.out.println( MLG + "Severe error found: Stopping server."); - if (verbose == false) { //If verbose is true, we already displayed it. + System.out.println(MLG + "Severe error found: Stopping server."); + if (verbose == false) { // If verbose is true, we + // already displayed it. System.out.println(line); } System.out.println(""); - System.out.println( MLG + "Forcing Save..."); - outputStream.write(saveAll); - outputStream.flush(); - //OutputStream outputStream = process.getOutputStream(); + System.out.println(MLG + "Forcing Save..."); + outputStream.write(saveAll); + outputStream.flush(); + // OutputStream outputStream = + // process.getOutputStream(); outputStream.write(stop); outputStream.flush(); - outputStream.write(stop); //sometimes we need to do stop twice... + outputStream.write(stop); // sometimes we need to do + // stop twice... outputStream.flush(); - //outputStream.close(); + // outputStream.close(); warning = true; - //System.exit(1); - //Quit! + // System.exit(1); + // Quit! } } } - - if (warning == true){ //in 1.4.4 we had a issue. tried to write stop twice, but we had closed the stream already. this, and other lines should fix this. + + if (warning == true) { // in 1.4.4 we had a issue. tried to write + // stop twice, but we had closed the stream + // already. this, and other lines should fix + // this. outputStream.flush(); outputStream.close(); System.exit(1); } - + outputStream.close(); } - + // readLine() returns null when the process exits } - - // Corrodias: - // I'd love to use nio, but it requires Java 7. - // I could use Apache Commons, but i don't want to include a library for one little thing. - // Copies src file to dst file. - // If the dst file does not exist, it is created + + /** + * I'd love to use nio, but it requires Java 7.
+ * I could use Apache Commons, but i don't want to include a library for one little thing.
+ * Copies src file to dst file.
+ * If the dst file does not exist, it is created
+ * + * @author Corrodias + * @param src + * @param dst + * @throws IOException + */ public static void copyFile(File src, File dst) throws IOException { InputStream in = new FileInputStream(src); OutputStream out = new FileOutputStream(dst); @@ -1010,22 +1103,21 @@ public class Main { // this is a lot of duplicated code. try { - File config = new File("MinecraftLandGenerator.conf"); + File config = new File(MinecraftLandGeneratorConf); BufferedReader in = new BufferedReader(new FileReader(config)); String line; while ((line = in.readLine()) != null) { int pos = line.indexOf('='); - int end = line.lastIndexOf('#'); //comments, ignored lines - - - if (end == -1){ // If we have no hash sign, then we read till the end of the line + int end = line.lastIndexOf('#'); // comments, ignored lines + + if (end == -1) { // If we have no hash sign, then we read till the end of the line end = line.length(); } - - if (end <= pos){ // If hash is before the '=', we may have a issue... it should be fine, cause we check for issues next, but lets make sure. + + if (end <= pos) { // If hash is before the '=', we may have a issue... it should be fine, cause we check for issues next, but lets make sure. end = line.length(); } - + if (pos != -1) { if (line.substring(0, pos).toLowerCase().equals("serverpath")) { serverPath = line.substring(pos + 1, end); @@ -1041,14 +1133,21 @@ public class Main { in.close(); if (serverPath == null || javaLine == null) { - System.err.println( MLG + "MinecraftLandGenerator.conf does not contain all requird properties. Please recreate it by running this application with no arguments."); + System.err + .println(MLG + + MinecraftLandGeneratorConf + + " does not contain all requird properties. Please recreate it by running this application with no arguments."); return false; } } catch (FileNotFoundException ex) { - System.out.println( MLG + "Could not find MinecraftLandGenerator.conf. It is recommended that you run the application with the -conf option to create it."); + System.out + .println(MLG + + "Could not find " + + MinecraftLandGeneratorConf + + ". It is recommended that you run the application with the -conf option to create it."); return false; } catch (IOException ex) { - System.err.println( MLG + "Could not read MinecraftLandGenerator.conf"); + System.err.println(MLG + "Could not read " + MinecraftLandGeneratorConf + "."); return false; } @@ -1056,45 +1155,629 @@ public class Main { // verify that we ended up with a good server path, either from the file or from an argument. File file = new File(serverPath); if (!file.exists() || !file.isDirectory()) { - System.err.println( MLG + "The server directory is invalid: " + serverPath); + System.err.println(MLG + "The server directory is invalid: " + serverPath); return false; } } try { // read the name of the current world from the server.properties file - BufferedReader props = new BufferedReader(new FileReader(new File(serverPath + separator + "server.properties"))); + BufferedReader props = + new BufferedReader(new FileReader(new File(serverPath + fileSeparator + + "server.properties"))); String line; while ((line = props.readLine()) != null) { int pos = line.indexOf('='); if (pos != -1) { if (line.substring(0, pos).toLowerCase().equals("level-name")) { - worldPath = serverPath + separator + line.substring(pos + 1); + worldPath = serverPath + fileSeparator + line.substring(pos + 1); } } } } catch (FileNotFoundException ex) { - System.err.println( MLG + "Could not open " + serverPath + separator + "server.properties"); + System.err.println(MLG + "Could not open " + serverPath + fileSeparator + + "server.properties"); return false; } catch (IOException ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); return false; } - File level = new File(worldPath + separator + "level.dat"); + File level = new File(worldPath + fileSeparator + "level.dat"); if (!level.exists() || !level.isFile()) { - System.err.println( MLG + "The currently-configured world does not exist. Please launch the server once, first."); + System.err + .println(MLG + + "The currently-configured world does not exist. Please launch the server once, first."); return false; } try { Integer[] spawn = getSpawn(level); - System.out.println( MLG + "The current spawn point is: [" + spawn[0] + ", " + spawn[2] + "]"); + System.out.println(MLG + "The current spawn point is: [" + spawn[0] + ", " + spawn[2] + + "]"); return true; } catch (IOException ex) { - System.err.println( MLG + "Error while reading " + level.getPath()); + System.err.println(MLG + "Error while reading " + level.getPath()); return false; } } -} \ No newline at end of file + + /** + * Saves a Readme file. + * + * @param readmeFile + * @author Morlok8k + * + */ + public static void readMe(String readmeFile) { + + if (readmeFile == "" || readmeFile == null) { + readmeFile = "MLG-Readme.txt"; + } + + String showHelpSTR = ""; + showHelpSTR = showHelp(false); //stored as a string for easier manipulation in the future + + //@formatter:off + String ReadMeText = ""; + ReadMeText = "Minecraft Land Generator version " + VERSION + newLine + + newLine + + "Updated " + dateFormat_MDY.format(MLG_Last_Modified_Date) + newLine + + newLine + + "Original Code by Corrodias November 2010" + newLine + + "Enhanced Code by Morlok8k Feb. 2011 to Now (or at least to the date listed above!)" + newLine + + "Additional Code by pr0f1x October 2011" + newLine + + "Forum: http://www.minecraftforum.net/topic/187737-minecraft-land-generator/" + newLine + + "Source: https://github.com/Morlok8k/MinecraftLandGenerator" + newLine + + newLine + + "-----------------------------------------------" + newLine + + newLine + + "This program lets you generate an area of land with your Minecraft Beta SMP server (and is prossibly future-proof for newer versions). You set up your java command line and minecraft server paths in the MinecraftLandGenerator.conf file, set up the server's server.properties file with the name of the world you wish to use, and then run this program." + newLine + + "When a Minecraft server is launched, it automatically generates chunks within a square area of 20x20 chunks (320x320 blocks), centered on the current spawn point. When provided X and Y ranges as arguments, this program will launch the server repeatedly, editing the level.dat file between sessions, to generate large amounts of land without players having to explore them. The generated land will have about the X and Y ranges as requested by the arguments, though it will not be exact due to the spawn point typically not on the border of a chunk. (Because of this, MLG by default adds a slight overlap with each pass - 300x300) You can use the -x and -y switches to override the spawn offset and center the land generation on a different point." + newLine + + "The program makes a backup of level.dat as level_backup.dat before editing, and restores the backup at the end. In the event that a level_backup.dat file already exists, the program will refuse to proceed, leaving the user to determine why the level_backup.dat file exists and whether they would rather restore it or delete it, which must be done manually." + newLine + + newLine + + "This program is public domain, and the source code is included in the .jar file. (If accidently missing, like in 1.3.0 and 1.4.0, it is always available at Github.)" + newLine + + "The JNLP library is included (inside the .jar) as jnbt-1.1.jar. It is not public domain. Its license is included within its .jar file, as LICENSE.TXT." + newLine + + "It is also available at: http://jnbt.sourceforge.net/" + newLine + + newLine + + "-----------------------------------------------" + newLine + + newLine + + "Version History:" + newLine + + "Morlok8k:" + newLine + + newLine + + "1.6.0" + newLine + + "- TODO: add features" + newLine + + "- Added the ability to download files from the internet (specifically for the BuildID file)" + newLine + + "- Added the ability to check what version the .jar is. (Using MD5 hashes, timestamps, and the BuildID file)" + newLine + + "- Minor Refactoring" + newLine + + newLine + + "1.5.1" + newLine + + "- pr0f1x: Added the \"save-all\" command to be sent to the server before shutting it down." + newLine + + "- pr0f1x: Added a 40 second wait before shutting down." + newLine + + "- Morlok8k: Made 40 second wait optional." + newLine + + "- Morlok8k: Changed the Dimensions code. (I had assumed it would be DIM-1, DIM-2, etc. but it turned out to be DIM-1 and DIM1. Change reflects Server output of \"Level n\")" + newLine + + "- Morlok8k: Config file is automatically updated to reflect these changes." + newLine + + "- Morlok8k: Cleaned up code." + newLine + + newLine + + "1.5.0" + newLine + + "- Supports Server Beta 1.6.4 (& hopefully future versions as well, while remaining backward compatible.)" + newLine + + "- Added \"-a\",\"-alt\" to use alternate method (a slightly simplier version of 1.3.0's code - pure verbose only)" + newLine + + "- Added world specific output for 9 dimensions (DIM-1 is the Nether, DIM-2 through DIM-9 dont exist yet, but if and when they do, you can configure it's text). (\"Level 0\", the default world, is displayed as the worlds name)" + newLine + + "- Updated Config File for these Dimensions." + newLine + + "- Reads and outputs the Seed to the output. (If you had used text for the Seed, Minecraft converts it into a number. This outputs the number.)" + newLine + + "- Changed the default 300 blocks to 380. The server now makes a 400x400 square block terrain instead of 320x320. Thus it is faster because there are less loops. To use the old way, use \"-i300\"" + newLine + + "- Added total Percentage done (technically, it displays the % done once the server finishes...)" + newLine + + "- Added debugging output vars of conf file (disabled - need to re-compile source to activate)" + newLine + + newLine + + " + (the goal is to have MLG be configureable, so it can work on any version of the server, past or present.)" + newLine + + newLine + + "*** 1.4.5 (pre 1.5.0) ***" + newLine + + "- sorry! I shouldn't release untested code..." + newLine + + "*************************" + newLine + + newLine + + "1.4.4" + newLine + + "- Added ablilty to ignore [WARNING] and [SEVERE] errors with \"-w\"" + newLine + + newLine + + "1.4.3" + newLine + + "- Fixed \"-ps\",\"-printspawn\" as I had forgot I had broken it in 1.4.0 - due to config file change." + newLine + + newLine + + "1.4.2" + newLine + + "- No New Features" + newLine + + "- Changed non-verbose mode to display server progress on the same line, saving a lot of space." + newLine + + " - This couldn't wait for 1.5.0 ... I (Morlok8k) liked it too much." + newLine + + newLine + + "1.4.0" + newLine + + "- Future Proofing" + newLine + + "- Configurble Server Message reading. (If server updates and breaks MLG, you can add the new text!)" + newLine + + "- Updated config file, and auto updating from old format." + newLine + + "- Added % of spawn area to non-verbose output." + newLine + + "- Removed datetime stamps from server output in verbose mode" + newLine + + "- Other Misc fixes." + newLine + + newLine + + "1.3.0" + newLine + + "- Fixed Problems with Minecraft Beta 1.3 -- Morlok8k" + newLine + + newLine + + "-----------------------------------------------" + newLine + + newLine + + "Corrodias:" + newLine + + "1.2.0" + newLine + + "- land generation now centers on the spawn point instead of [0, 0]" + newLine + + "- the server is launched once before the spawn point is changed, to verify that it can run and to create a world if one doesn't exist" + newLine + + "- added -printspawn [-ps] switch to print the current spawn coordinates to the console" + newLine + + "- added -x and -y switches to override the X and Y offsets" + newLine + + "- added -v switch, does the same as -verbose" + newLine + + "- improved status message spacing to make things easier to read" + newLine + + "- improved time estimation algorithm: it now averages the last 3 launches" + newLine + + newLine + + "1.1.0" + newLine + + "- added MinecraftLandGenerator.conf file to hold the java command line and the server path" + newLine + + "- added -conf solo switch to generate a .conf file" + newLine + + "- added -verbose switch to output server output to the console (default is to ignore it)" + newLine + + "- added -i switch to allow customizing the block increment size (default is 300)" + newLine + + "- added instructions output in this version, i think" + newLine + + "- improved status message output to include current iteration and total iterations" + newLine + + newLine + + "1.0.0" + newLine + + "- initial release" + newLine + + newLine + + "-----------------------------------------------" + newLine + + newLine + + "Notes:" + newLine + + "Due to changes in server beta 1.6, it now generates the nether as well as the world at the same time." + newLine + + "I recommend using MCE or MCEDIT to relight the map after you generate it. This will take a long time, but should fix all those incorrectly dark spots in your level." + newLine + + newLine + + "-----------------------------------------------" + newLine + + newLine; + //@formatter:on + + try { + File readme = new File(readmeFile); + BufferedWriter out = new BufferedWriter(new FileWriter(readme)); + + out.write(ReadMeText + showHelpSTR); + + out.newLine(); + out.close(); + + System.out.println(MLG + readmeFile + " file created."); + return; + + } catch (IOException ex) { + System.err.println(MLG + "Could not create " + readmeFile + "."); + return; + } + + } + + /** + * + * Downloads a File using a URL in a String.
+ * (If the file is a dynamic URL (Not like "http://example.com/file.txt") and it can't get the filename, it saves it as "System.currentTimeMillis();")
+ *
+ * Thanks to bs123 at
+ * http://www.daniweb.com/software-development/java/threads/84370 + * + * @author Morlok8k + * @param URL + */ + public static void downloadFile(String URL) { + + String fileName = URL.substring(URL.lastIndexOf("/") + 1, URL.length()); + int size = 1024 * 4; // 1024 * n should be tested to get the optimum + // size (for download speed.) + + if (fileName.equals("")) { + fileName = String.valueOf(System.currentTimeMillis()); + } + + System.out.println(MLG + "Downloading: " + URL); + System.out.println(MLG + "Saving as: " + fileName); + + long differenceTime = System.currentTimeMillis(); + Long[] timeTracking = new Long[] { differenceTime, differenceTime }; + timeTracking[0] = System.currentTimeMillis(); + + try { + BufferedInputStream in; + in = new BufferedInputStream(new URL(URL).openStream()); + FileOutputStream fos; + fos = new FileOutputStream(fileName); + BufferedOutputStream bout = new BufferedOutputStream(fos, size); + byte[] data = new byte[size]; + int x = 0; + int count = 0; + while ((x = in.read(data, 0, size)) >= 0) { + bout.write(data, 0, x); + count = count + x; + } + bout.close(); + in.close(); + System.out.println(count + " byte(s) copied"); + + timeTracking[1] = System.currentTimeMillis(); + differenceTime = (timeTracking[1] - timeTracking[0]) / 2; + + System.out.println(String.format(MLG + "Elapsed Time: %dm%ds", + (differenceTime % (1000 * 60 * 60)) / (1000 * 60), + ((differenceTime % (1000 * 60 * 60)) % (1000 * 60)) / 1000)); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + System.out.println(MLG + "Done"); + + } + + /** + * This is an "undocumented" function to create a BuildID file. It should only be used right after compiling a .jar file
+ * The resulting BuildID file is uploaded to github, and also distributed with the program.
+ * THE FILE SHOULD ONLY BE MADE FROM SCRATCH AT THE TIME OF PUBLISHING!
+ * (Otherwise, the purpose is defeated!) + * + * @author Morlok8k + */ + public static void buildID() { + + // TODO: Decide to download BuildID from Github. + // If not available, create. + // After downloading, check to see if it matches hash. + + // example: + // downloadFile(MinecraftLandGeneratorConfURL); + // downloadFile("https://raw.github.com/Morlok8k/MinecraftLandGenerator/master/bin/" + buildIDFile); + + if (MLGFileName == null) { + try { + MLGFileName = getClassLoader(cls); + } catch (Exception e) { + System.out.println(MLG + "Error: Finding file failed"); + e.printStackTrace(); + } + if (MLGFileName.equals(rsrcError)) { return; } + } + + if (MLG_Current_Hash == null) { + + try { + MLG_Current_Hash = fileMD5(MLGFileName); + // System.out.println(hash + " " + MLGFileName); + } catch (Exception e) { + System.out.println(MLG + "Error: MD5 from file failed"); + e.printStackTrace(); + } + } + + Date time = null; + try { + time = getCompileTimeStamp(cls); + } catch (Exception e) { + System.out.println(MLG + "Error: TimeStamp from file failed"); + e.printStackTrace(); + } + // System.out.println(d.toString()); + + boolean notNew = false; + String INFO = ""; + if (isCompiledAsJar == false) { + INFO = " (Class File, Not .Jar)"; + } + + try { + BufferedReader in = new BufferedReader(new FileReader(buildIDFile)); + BufferedWriter out = new BufferedWriter(new FileWriter(buildIDFile + ".temp")); + String line; + while ((line = in.readLine()) != null) { + + if (line.contains(MLG_Current_Hash)) { + notNew = true; + // System.out.println("[DEBUG] NotNew"); + } + + out.write(line); + out.newLine(); + } + + if (notNew == false) { + out.write(MLG_Current_Hash + "=" + String.valueOf(time.getTime()) + "#MLG v" + + VERSION + INFO); + out.newLine(); + } + out.close(); + in.close(); + + File fileDelete = new File(buildIDFile); + fileDelete.delete(); + File fileRename = new File(buildIDFile + ".temp"); + fileRename.renameTo(new File(buildIDFile)); + + } catch (FileNotFoundException ex) { + System.out.println(MLG + "\"" + buildIDFile + "\" file not Found. Generating New \"" + + buildIDFile + "\" File"); + try { + BufferedWriter out = new BufferedWriter(new FileWriter(buildIDFile)); + out.write(MLG_Current_Hash + "=" + String.valueOf(time.getTime()) + "#MLG v" + + VERSION + INFO); + out.newLine(); + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } catch (IOException ex) { + System.err.println(MLG + "Could not create \"" + buildIDFile + "\"."); + return; + } + + } + + /** + * Gets the BuildID for MLG + * + * @author Morlok8k + * + */ + private void readBuildID() { + + if (MLGFileName == null) { + try { + MLGFileName = getClassLoader(cls); + } catch (Exception e) { + System.out.println(MLG + "Error: Finding file failed"); + e.printStackTrace(); + } + if (MLGFileName.equals(rsrcError)) { return; } + } + + if (MLG_Current_Hash == null) { + + try { + MLG_Current_Hash = fileMD5(MLGFileName); + // System.out.println(hash + " " + MLGFileName); + } catch (Exception e) { + System.out.println(MLG + "Error: MD5 from file failed"); + e.printStackTrace(); + } + } + + if (MLG_Last_Modified_Date == null) { + boolean foundLine = false; + try { + BufferedReader in = new BufferedReader(new FileReader(buildIDFile)); + String line; + + while ((line = in.readLine()) != null) { + + if (line.contains(MLG_Current_Hash)) { + // System.out.println("[DEBUG] Found!"); + foundLine = true; + + int pos = line.indexOf('='); + int end = line.lastIndexOf('#'); // comments, ignored lines + + if (end == -1) { // If we have no hash sign, then we read till the end of the line + end = line.length(); + } + if (end <= pos) { // If hash is before the '=', we may have an issue... it should be fine, cause we check for issues next, but lets make + // sure. + end = line.length(); + } + + if (pos != -1) { + if (line.substring(0, pos).equals(MLG_Current_Hash)) { + MLG_Last_Modified_Date = + new Date(new Long(line.substring(pos + 1, end))); + return; + } + + } + } + + } + in.close(); + + if (foundLine == false) { + // System.out.println("[DEBUG] FoundLine False"); + buildID(); + readBuildID(); // yes I'm calling the function from itself. potential infinite loop? possibly. I haven't encountered it yet! + // TODO: Add safeguard to prevent Infinite Loops + return; + } + } catch (Exception e) { + System.err.println(MLG + "Cant Read " + buildIDFile + "!"); + // e.printStackTrace(); + buildID(); + readBuildID(); + // TODO: Add safeguard to prevent Infinite Loops + return; + + } + } + + } + + /** + * This gets the filename of a .jar (typically this one!) + * + * @author Morlok8k + */ + public static String getClassLoader(Class classFile) throws IOException { + ClassLoader loader = classFile.getClassLoader(); + String filename = classFile.getName().replace('.', '/') + ".class"; + URL resource = + (loader != null) ? loader.getResource(filename) : ClassLoader + .getSystemResource(filename); + filename = URLDecoder.decode(resource.toString(), "UTF-8"); + // System.out.println(filename); + + // START Garbage removal: + int bang = filename.indexOf("!"); // remove everything after xxxx.jar + if (bang == -1) { // a real example: + bang = filename.length(); // jar:file:/home/morlok8k/test.jar!/me/Morlok8k/test/Main.class + } + int file = filename.indexOf("file:"); // removes junk from the beginning + // of the path + file = file + 5; + if (file == -1) { + file = 0; + } + if (filename.contains("rsrc:")) { + System.out + .println(MLG + + "THIS WAS COMPILED USING \"org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader\"! "); + System.out.println(MLG + "DO NOT PACKAGE YOUR .JAR'S WITH THIS CLASSLOADER CODE!"); + System.out.println(MLG + "(Your Libraries need to be extracted.)"); + return rsrcError; + } + if (filename.contains(".jar")) { + isCompiledAsJar = true; + } + filename = filename.replace('/', File.separatorChar); + String returnString = filename.substring(file, bang); + // END Garbage removal + return returnString; + } + + /** + * This gets the TimeStamp (last modified date) of a class file (typically this one!)
+ *
+ * Thanks to Roedy Green at
+ * http://mindprod .com/jgloss/compiletimestamp.html + * + * @author Morlok8k + */ + public static Date getCompileTimeStamp(Class classFile) throws IOException { + ClassLoader loader = classFile.getClassLoader(); + String filename = classFile.getName().replace('.', '/') + ".class"; + // get the corresponding class file as a Resource. + URL resource = + (loader != null) ? loader.getResource(filename) : ClassLoader + .getSystemResource(filename); + URLConnection connection = resource.openConnection(); + // Note, we are using Connection.getLastModified not File.lastModifed. + // This will then work both or members of jars or standalone class files. + // NOTE: NOT TRUE! IT READS THE JAR, NOT THE FILES INSIDE! + long time = connection.getLastModified(); + return (time != 0L) ? new Date(time) : null; + } + + /** + * This gets the MD5 of a file
+ *
+ * Thanks to R.J. Lorimer at
+ * http://www. javalobby.org/java/forums/t84420.html + * + * @author Morlok8k + */ + public static String fileMD5(String fileName) throws NoSuchAlgorithmException, + FileNotFoundException { + // System.out.println(""); + // System.out.println(""); + MessageDigest digest = MessageDigest.getInstance("MD5"); + InputStream is = new FileInputStream(fileName); + byte[] buffer = new byte[8192]; + int read = 0; + try { + while ((read = is.read(buffer)) > 0) { + digest.update(buffer, 0, read); + } + byte[] md5sum = digest.digest(); + BigInteger bigInt = new BigInteger(1, md5sum); + String output = bigInt.toString(16); + // System.out.println(MLG + "MD5: " + output); + return output.toUpperCase(Locale.ENGLISH); + } catch (IOException e) { + throw new RuntimeException("Unable to process file for MD5", e); + } finally { + try { + is.close(); + } catch (IOException e) { + throw new RuntimeException("Unable to close input stream for MD5 calculation", e); + } + } + } + + /** + * Displays or returns Help information + * + * @param SysOut + *
+ * Set TRUE to display info to System.out. (Returns null)
+ * Set FALSE to return info as String. + * @author Morlok8k + */ + public static String showHelp(boolean SysOut) { + String Str = null; + + //@formatter:off + Str = "Usage: java -jar MinecraftLandGenerator.jar x y [serverpath] [switches]" + newLine + + newLine + + "Arguments:" + newLine + + " x : X range to generate" + newLine + + " y : Y range to generate" + newLine + + " serverpath : the path to the directory in which the server runs (takes precedence over the config file setting)" + newLine + + newLine + + "Switches:" + newLine + + " -verbose : causes the application to output the server's messages to the console" + newLine + + " -v : same as -verbose" + newLine + + " -w : Ignore [WARNING] and [SEVERE] messages." + newLine + + " -alt : alternate server launch sequence" + newLine + + " -a : same as -alt" + newLine + + " -i# : override the iteration spawn offset increment (default 300) (example: -i100)" + newLine + + " -x# : set the X offset to generate land around (example: -x0)" + newLine + + " -y# : set the X offset to generate land around (example: -y0)" + newLine + + newLine + + "Other options:" + newLine + + " java -jar MinecraftLandGenerator.jar -printspawn" + newLine + + " java -jar MinecraftLandGenerator.jar -ps" + newLine + + " Outputs the current world's spawn point coordinates." + newLine + + newLine + + " java -jar MinecraftLandGenerator.jar -conf" + newLine + + " Generates a "+ MinecraftLandGeneratorConf + " file." + newLine + + newLine + + " java -jar MinecraftLandGenerator.jar -readme readme.txt" + newLine + + " java -jar MinecraftLandGenerator.jar -readme" + newLine + + " Generates a readme file using supplied name or the default MLG-Readme.txt" + newLine + + newLine + + " java -jar MinecraftLandGenerator.jar -version" + newLine + + " java -jar MinecraftLandGenerator.jar -help" + newLine + + " java -jar MinecraftLandGenerator.jar /?" + newLine + + " Prints this message." + newLine + + newLine + + "When launched with the -conf switch, this application creates a " + MinecraftLandGeneratorConf + " file that contains configuration options." + newLine + + "If this file does not exist or does not contain all required properties, the application will not run." + newLine + + newLine + + MinecraftLandGeneratorConf + " properties:" + newLine + + " Java : The command line to use to launch the server" + newLine + + " ServerPath : The path to the directory in which the server runs (can be overridden by the serverpath argument)" + newLine + + " Done_Text : The output from the server that tells us that we are done" + newLine + + " Preparing_Text : The output from the server that tells us the percentage" + newLine + + "Preparing_Level : The output from the server that tells us the level it is working on" + newLine + + " Level-0 : Name of Level 0: The Overworld" + newLine + + " Level-1 : Name of Level 1: The Nether" + newLine + + " Level-2 : Name of Level 2: The End" + newLine + + " Level-3 : Name of Level 3: (Future Level)" + newLine + + " Level-4 : Name of Level 4: (Future Level)" + newLine + + " Level-5 : Name of Level 5: (Future Level)" + newLine + + " Level-6 : Name of Level 6: (Future Level)" + newLine + + " Level-7 : Name of Level 7: (Future Level)" + newLine + + " Level-8 : Name of Level 8: (Future Level)" + newLine + + " Level-9 : Name of Level 9: (Future Level)" + newLine + + " WaitSave : Optional: Wait before saving." + newLine; + //@formatter:on + + if (SysOut) { + System.out.print(Str); + System.out.println(""); + return null; + } else { + return Str; + } + + } + +}