mirror of
https://github.com/Eyre-S/Coeur-Morny-Cono.git
synced 2024-11-23 03:27:39 +08:00
[[[ release 0.4.2.11 ]]]
## 🧯Bug Fix - 修复 /user 命令在遇到无 username 用户时会将 java.null 转译为值而非报空的问题 - ((隐藏问题)) 为所有消息发送补全特殊字符转义,修复当拼接内容有 html 特殊字符 < > & 时,telegram api 将无法处理导致无法发送消息 ## 📇功能 - 添加呼叫 morny 主人功能 - 添加 /ip 和 /whois 命令 (#17 @186526 - 添加 /event_hack 命令 - 添加 /jrrp 命令以及其 xmomi 版本后端 - /user 命令现在在无参数时返回调用者的数据而非回报错误 - /runtime 命令的返回数据的 continuous 字段添加了启动时间回报 ## 🔌系统接口 - 添加了主人 id 记录,用作可信认证和部分功能 - 封装对象化了 MornyCoeur 和 MornyTrusted - 程序启动参数扩充 - 以选项方式为 token 与 username 字段赋值 - 实现 morny 主人和信任群组字段的赋值 - 同时标记旧的 token username 参数赋值可能废弃 - 添加 apache-commons-text 类库 用于进行 HTML 实体转义 - 添加了 escapeHtmlTelegram 工具 用于进行 telegram api HTML 实体转义 - 移除了没有再被使用的 repeatChars 工具 ## 🔩技术修改/typo - 事件的"忽略程序启动前"作用范围现在扩大为所有 Message 和 EditedMessage 事件 - 添加了贴纸管理类 - 修改 /runtime 的文本 - 补充部分 javadoc - 为项目添加 .editorconfig - 将部分误导入的 jetbrains.NotNull 改为 javax.Nonnull
This commit is contained in:
commit
31e25308bb
532
.editorconfig
Normal file
532
.editorconfig
Normal file
@ -0,0 +1,532 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = tab
|
||||||
|
insert_final_newline = true
|
||||||
|
max_line_length = 120
|
||||||
|
tab_width = 4
|
||||||
|
ij_continuation_indent_size = 8
|
||||||
|
ij_formatter_off_tag = @formatter:off
|
||||||
|
ij_formatter_on_tag = @formatter:on
|
||||||
|
ij_formatter_tags_enabled = false
|
||||||
|
ij_smart_tabs = false
|
||||||
|
ij_visual_guides = none
|
||||||
|
ij_wrap_on_typing = false
|
||||||
|
|
||||||
|
[*.java]
|
||||||
|
ij_java_align_consecutive_assignments = false
|
||||||
|
ij_java_align_consecutive_variable_declarations = false
|
||||||
|
ij_java_align_group_field_declarations = false
|
||||||
|
ij_java_align_multiline_annotation_parameters = false
|
||||||
|
ij_java_align_multiline_array_initializer_expression = false
|
||||||
|
ij_java_align_multiline_assignment = true
|
||||||
|
ij_java_align_multiline_binary_operation = false
|
||||||
|
ij_java_align_multiline_chained_methods = false
|
||||||
|
ij_java_align_multiline_extends_list = false
|
||||||
|
ij_java_align_multiline_for = false
|
||||||
|
ij_java_align_multiline_method_parentheses = false
|
||||||
|
ij_java_align_multiline_parameters = false
|
||||||
|
ij_java_align_multiline_parameters_in_calls = false
|
||||||
|
ij_java_align_multiline_parenthesized_expression = true
|
||||||
|
ij_java_align_multiline_records = true
|
||||||
|
ij_java_align_multiline_resources = false
|
||||||
|
ij_java_align_multiline_ternary_operation = true
|
||||||
|
ij_java_align_multiline_text_blocks = false
|
||||||
|
ij_java_align_multiline_throws_list = false
|
||||||
|
ij_java_align_subsequent_simple_methods = false
|
||||||
|
ij_java_align_throws_keyword = true
|
||||||
|
ij_java_annotation_parameter_wrap = off
|
||||||
|
ij_java_array_initializer_new_line_after_left_brace = true
|
||||||
|
ij_java_array_initializer_right_brace_on_new_line = true
|
||||||
|
ij_java_array_initializer_wrap = on_every_item
|
||||||
|
ij_java_assert_statement_colon_on_next_line = true
|
||||||
|
ij_java_assert_statement_wrap = normal
|
||||||
|
ij_java_assignment_wrap = normal
|
||||||
|
ij_java_binary_operation_sign_on_next_line = false
|
||||||
|
ij_java_binary_operation_wrap = off
|
||||||
|
ij_java_blank_lines_after_anonymous_class_header = 0
|
||||||
|
ij_java_blank_lines_after_class_header = 1
|
||||||
|
ij_java_blank_lines_after_imports = 1
|
||||||
|
ij_java_blank_lines_after_package = 1
|
||||||
|
ij_java_blank_lines_around_class = 1
|
||||||
|
ij_java_blank_lines_around_field = 0
|
||||||
|
ij_java_blank_lines_around_field_in_interface = 0
|
||||||
|
ij_java_blank_lines_around_initializer = 0
|
||||||
|
ij_java_blank_lines_around_method = 1
|
||||||
|
ij_java_blank_lines_around_method_in_interface = 1
|
||||||
|
ij_java_blank_lines_before_class_end = 1
|
||||||
|
ij_java_blank_lines_before_imports = 1
|
||||||
|
ij_java_blank_lines_before_method_body = 0
|
||||||
|
ij_java_blank_lines_before_package = 0
|
||||||
|
ij_java_block_brace_style = end_of_line
|
||||||
|
ij_java_block_comment_add_space = false
|
||||||
|
ij_java_block_comment_at_first_column = true
|
||||||
|
ij_java_builder_methods = none
|
||||||
|
ij_java_call_parameters_new_line_after_left_paren = true
|
||||||
|
ij_java_call_parameters_right_paren_on_new_line = true
|
||||||
|
ij_java_call_parameters_wrap = normal
|
||||||
|
ij_java_case_statement_on_separate_line = true
|
||||||
|
ij_java_catch_on_new_line = false
|
||||||
|
ij_java_class_annotation_wrap = split_into_lines
|
||||||
|
ij_java_class_brace_style = end_of_line
|
||||||
|
ij_java_class_count_to_use_import_on_demand = 5
|
||||||
|
ij_java_class_names_in_javadoc = 1
|
||||||
|
ij_java_do_not_indent_top_level_class_members = false
|
||||||
|
ij_java_do_not_wrap_after_single_annotation = false
|
||||||
|
ij_java_do_while_brace_force = never
|
||||||
|
ij_java_doc_add_blank_line_after_description = true
|
||||||
|
ij_java_doc_add_blank_line_after_param_comments = false
|
||||||
|
ij_java_doc_add_blank_line_after_return = false
|
||||||
|
ij_java_doc_add_p_tag_on_empty_lines = true
|
||||||
|
ij_java_doc_align_exception_comments = false
|
||||||
|
ij_java_doc_align_param_comments = false
|
||||||
|
ij_java_doc_do_not_wrap_if_one_line = true
|
||||||
|
ij_java_doc_enable_formatting = true
|
||||||
|
ij_java_doc_enable_leading_asterisks = true
|
||||||
|
ij_java_doc_indent_on_continuation = false
|
||||||
|
ij_java_doc_keep_empty_lines = true
|
||||||
|
ij_java_doc_keep_empty_parameter_tag = true
|
||||||
|
ij_java_doc_keep_empty_return_tag = true
|
||||||
|
ij_java_doc_keep_empty_throws_tag = true
|
||||||
|
ij_java_doc_keep_invalid_tags = true
|
||||||
|
ij_java_doc_param_description_on_new_line = false
|
||||||
|
ij_java_doc_preserve_line_breaks = true
|
||||||
|
ij_java_doc_use_throws_not_exception_tag = true
|
||||||
|
ij_java_else_on_new_line = false
|
||||||
|
ij_java_entity_dd_suffix = EJB
|
||||||
|
ij_java_entity_eb_suffix = Bean
|
||||||
|
ij_java_entity_hi_suffix = Home
|
||||||
|
ij_java_entity_lhi_prefix = Local
|
||||||
|
ij_java_entity_lhi_suffix = Home
|
||||||
|
ij_java_entity_li_prefix = Local
|
||||||
|
ij_java_entity_pk_class = java.lang.String
|
||||||
|
ij_java_entity_vo_suffix = VO
|
||||||
|
ij_java_enum_constants_wrap = on_every_item
|
||||||
|
ij_java_extends_keyword_wrap = normal
|
||||||
|
ij_java_extends_list_wrap = off
|
||||||
|
ij_java_field_annotation_wrap = normal
|
||||||
|
ij_java_finally_on_new_line = false
|
||||||
|
ij_java_for_brace_force = if_multiline
|
||||||
|
ij_java_for_statement_new_line_after_left_paren = true
|
||||||
|
ij_java_for_statement_right_paren_on_new_line = true
|
||||||
|
ij_java_for_statement_wrap = on_every_item
|
||||||
|
ij_java_generate_final_locals = false
|
||||||
|
ij_java_generate_final_parameters = false
|
||||||
|
ij_java_if_brace_force = never
|
||||||
|
ij_java_imports_layout = *,|,javax.**,java.**,|,$*
|
||||||
|
ij_java_indent_case_from_switch = true
|
||||||
|
ij_java_insert_inner_class_imports = false
|
||||||
|
ij_java_insert_override_annotation = true
|
||||||
|
ij_java_keep_blank_lines_before_right_brace = 2
|
||||||
|
ij_java_keep_blank_lines_between_package_declaration_and_header = 2
|
||||||
|
ij_java_keep_blank_lines_in_code = 2
|
||||||
|
ij_java_keep_blank_lines_in_declarations = 2
|
||||||
|
ij_java_keep_builder_methods_indents = false
|
||||||
|
ij_java_keep_control_statement_in_one_line = false
|
||||||
|
ij_java_keep_first_column_comment = false
|
||||||
|
ij_java_keep_indents_on_empty_lines = true
|
||||||
|
ij_java_keep_line_breaks = false
|
||||||
|
ij_java_keep_multiple_expressions_in_one_line = false
|
||||||
|
ij_java_keep_simple_blocks_in_one_line = false
|
||||||
|
ij_java_keep_simple_classes_in_one_line = false
|
||||||
|
ij_java_keep_simple_lambdas_in_one_line = false
|
||||||
|
ij_java_keep_simple_methods_in_one_line = false
|
||||||
|
ij_java_label_indent_absolute = false
|
||||||
|
ij_java_label_indent_size = 0
|
||||||
|
ij_java_lambda_brace_style = end_of_line
|
||||||
|
ij_java_layout_static_imports_separately = true
|
||||||
|
ij_java_line_comment_add_space = false
|
||||||
|
ij_java_line_comment_at_first_column = true
|
||||||
|
ij_java_message_dd_suffix = EJB
|
||||||
|
ij_java_message_eb_suffix = Bean
|
||||||
|
ij_java_method_annotation_wrap = split_into_lines
|
||||||
|
ij_java_method_brace_style = end_of_line
|
||||||
|
ij_java_method_call_chain_wrap = normal
|
||||||
|
ij_java_method_parameters_new_line_after_left_paren = true
|
||||||
|
ij_java_method_parameters_right_paren_on_new_line = true
|
||||||
|
ij_java_method_parameters_wrap = normal
|
||||||
|
ij_java_modifier_list_wrap = false
|
||||||
|
ij_java_names_count_to_use_import_on_demand = 3
|
||||||
|
ij_java_new_line_after_lparen_in_record_header = false
|
||||||
|
ij_java_packages_to_use_import_on_demand = java.awt.*,javax.swing.*
|
||||||
|
ij_java_parameter_annotation_wrap = normal
|
||||||
|
ij_java_parentheses_expression_new_line_after_left_paren = false
|
||||||
|
ij_java_parentheses_expression_right_paren_on_new_line = false
|
||||||
|
ij_java_place_assignment_sign_on_next_line = false
|
||||||
|
ij_java_prefer_longer_names = true
|
||||||
|
ij_java_prefer_parameters_wrap = false
|
||||||
|
ij_java_record_components_wrap = normal
|
||||||
|
ij_java_repeat_synchronized = true
|
||||||
|
ij_java_replace_instanceof_and_cast = false
|
||||||
|
ij_java_replace_null_check = true
|
||||||
|
ij_java_replace_sum_lambda_with_method_ref = true
|
||||||
|
ij_java_resource_list_new_line_after_left_paren = true
|
||||||
|
ij_java_resource_list_right_paren_on_new_line = true
|
||||||
|
ij_java_resource_list_wrap = normal
|
||||||
|
ij_java_rparen_on_new_line_in_record_header = false
|
||||||
|
ij_java_session_dd_suffix = EJB
|
||||||
|
ij_java_session_eb_suffix = Bean
|
||||||
|
ij_java_session_hi_suffix = Home
|
||||||
|
ij_java_session_lhi_prefix = Local
|
||||||
|
ij_java_session_lhi_suffix = Home
|
||||||
|
ij_java_session_li_prefix = Local
|
||||||
|
ij_java_session_si_suffix = Service
|
||||||
|
ij_java_space_after_closing_angle_bracket_in_type_argument = false
|
||||||
|
ij_java_space_after_colon = true
|
||||||
|
ij_java_space_after_comma = true
|
||||||
|
ij_java_space_after_comma_in_type_arguments = true
|
||||||
|
ij_java_space_after_for_semicolon = true
|
||||||
|
ij_java_space_after_quest = true
|
||||||
|
ij_java_space_after_type_cast = false
|
||||||
|
ij_java_space_before_annotation_array_initializer_left_brace = false
|
||||||
|
ij_java_space_before_annotation_parameter_list = false
|
||||||
|
ij_java_space_before_array_initializer_left_brace = false
|
||||||
|
ij_java_space_before_catch_keyword = true
|
||||||
|
ij_java_space_before_catch_left_brace = true
|
||||||
|
ij_java_space_before_catch_parentheses = true
|
||||||
|
ij_java_space_before_class_left_brace = true
|
||||||
|
ij_java_space_before_colon = true
|
||||||
|
ij_java_space_before_colon_in_foreach = true
|
||||||
|
ij_java_space_before_comma = false
|
||||||
|
ij_java_space_before_do_left_brace = true
|
||||||
|
ij_java_space_before_else_keyword = true
|
||||||
|
ij_java_space_before_else_left_brace = true
|
||||||
|
ij_java_space_before_finally_keyword = true
|
||||||
|
ij_java_space_before_finally_left_brace = true
|
||||||
|
ij_java_space_before_for_left_brace = true
|
||||||
|
ij_java_space_before_for_parentheses = true
|
||||||
|
ij_java_space_before_for_semicolon = false
|
||||||
|
ij_java_space_before_if_left_brace = true
|
||||||
|
ij_java_space_before_if_parentheses = true
|
||||||
|
ij_java_space_before_method_call_parentheses = false
|
||||||
|
ij_java_space_before_method_left_brace = true
|
||||||
|
ij_java_space_before_method_parentheses = true
|
||||||
|
ij_java_space_before_opening_angle_bracket_in_type_parameter = true
|
||||||
|
ij_java_space_before_quest = true
|
||||||
|
ij_java_space_before_switch_left_brace = true
|
||||||
|
ij_java_space_before_switch_parentheses = true
|
||||||
|
ij_java_space_before_synchronized_left_brace = true
|
||||||
|
ij_java_space_before_synchronized_parentheses = true
|
||||||
|
ij_java_space_before_try_left_brace = true
|
||||||
|
ij_java_space_before_try_parentheses = true
|
||||||
|
ij_java_space_before_type_parameter_list = false
|
||||||
|
ij_java_space_before_while_keyword = true
|
||||||
|
ij_java_space_before_while_left_brace = true
|
||||||
|
ij_java_space_before_while_parentheses = true
|
||||||
|
ij_java_space_inside_one_line_enum_braces = false
|
||||||
|
ij_java_space_within_empty_array_initializer_braces = false
|
||||||
|
ij_java_space_within_empty_method_call_parentheses = false
|
||||||
|
ij_java_space_within_empty_method_parentheses = false
|
||||||
|
ij_java_spaces_around_additive_operators = true
|
||||||
|
ij_java_spaces_around_assignment_operators = true
|
||||||
|
ij_java_spaces_around_bitwise_operators = true
|
||||||
|
ij_java_spaces_around_equality_operators = true
|
||||||
|
ij_java_spaces_around_lambda_arrow = true
|
||||||
|
ij_java_spaces_around_logical_operators = true
|
||||||
|
ij_java_spaces_around_method_ref_dbl_colon = false
|
||||||
|
ij_java_spaces_around_multiplicative_operators = true
|
||||||
|
ij_java_spaces_around_relational_operators = true
|
||||||
|
ij_java_spaces_around_shift_operators = true
|
||||||
|
ij_java_spaces_around_type_bounds_in_type_parameters = true
|
||||||
|
ij_java_spaces_around_unary_operator = false
|
||||||
|
ij_java_spaces_within_angle_brackets = false
|
||||||
|
ij_java_spaces_within_annotation_parentheses = false
|
||||||
|
ij_java_spaces_within_array_initializer_braces = false
|
||||||
|
ij_java_spaces_within_braces = false
|
||||||
|
ij_java_spaces_within_brackets = false
|
||||||
|
ij_java_spaces_within_cast_parentheses = false
|
||||||
|
ij_java_spaces_within_catch_parentheses = false
|
||||||
|
ij_java_spaces_within_for_parentheses = false
|
||||||
|
ij_java_spaces_within_if_parentheses = false
|
||||||
|
ij_java_spaces_within_method_call_parentheses = false
|
||||||
|
ij_java_spaces_within_method_parentheses = false
|
||||||
|
ij_java_spaces_within_parentheses = false
|
||||||
|
ij_java_spaces_within_record_header = false
|
||||||
|
ij_java_spaces_within_switch_parentheses = false
|
||||||
|
ij_java_spaces_within_synchronized_parentheses = false
|
||||||
|
ij_java_spaces_within_try_parentheses = false
|
||||||
|
ij_java_spaces_within_while_parentheses = false
|
||||||
|
ij_java_special_else_if_treatment = true
|
||||||
|
ij_java_subclass_name_suffix = Impl
|
||||||
|
ij_java_ternary_operation_signs_on_next_line = false
|
||||||
|
ij_java_ternary_operation_wrap = on_every_item
|
||||||
|
ij_java_test_name_suffix = Test
|
||||||
|
ij_java_throws_keyword_wrap = normal
|
||||||
|
ij_java_throws_list_wrap = off
|
||||||
|
ij_java_use_external_annotations = false
|
||||||
|
ij_java_use_fq_class_names = false
|
||||||
|
ij_java_use_relative_indents = true
|
||||||
|
ij_java_use_single_class_imports = true
|
||||||
|
ij_java_variable_annotation_wrap = on_every_item
|
||||||
|
ij_java_visibility = public
|
||||||
|
ij_java_while_brace_force = never
|
||||||
|
ij_java_while_on_new_line = true
|
||||||
|
ij_java_wrap_comments = false
|
||||||
|
ij_java_wrap_first_method_in_call_chain = true
|
||||||
|
ij_java_wrap_long_lines = false
|
||||||
|
|
||||||
|
[.editorconfig]
|
||||||
|
ij_editorconfig_align_group_field_declarations = false
|
||||||
|
ij_editorconfig_space_after_colon = false
|
||||||
|
ij_editorconfig_space_after_comma = true
|
||||||
|
ij_editorconfig_space_before_colon = false
|
||||||
|
ij_editorconfig_space_before_comma = false
|
||||||
|
ij_editorconfig_spaces_around_assignment_operators = true
|
||||||
|
|
||||||
|
[{*.ant,*.fxml,*.isc,*.jhm,*.jnlp,*.jrxml,*.pom,*.rng,*.tld,*.wadl,*.wsdd,*.wsdl,*.xjb,*.xml,*.xsd,*.xsl,*.xslt,*.xul}]
|
||||||
|
ij_smart_tabs = true
|
||||||
|
ij_xml_align_attributes = false
|
||||||
|
ij_xml_align_text = false
|
||||||
|
ij_xml_attribute_wrap = off
|
||||||
|
ij_xml_block_comment_add_space = false
|
||||||
|
ij_xml_block_comment_at_first_column = true
|
||||||
|
ij_xml_keep_blank_lines = 2
|
||||||
|
ij_xml_keep_indents_on_empty_lines = true
|
||||||
|
ij_xml_keep_line_breaks = true
|
||||||
|
ij_xml_keep_line_breaks_in_text = true
|
||||||
|
ij_xml_keep_whitespaces = false
|
||||||
|
ij_xml_keep_whitespaces_around_cdata = preserve
|
||||||
|
ij_xml_keep_whitespaces_inside_cdata = false
|
||||||
|
ij_xml_line_comment_at_first_column = true
|
||||||
|
ij_xml_space_after_tag_name = false
|
||||||
|
ij_xml_space_around_equals_in_attribute = false
|
||||||
|
ij_xml_space_inside_empty_tag = true
|
||||||
|
ij_xml_text_wrap = normal
|
||||||
|
ij_xml_use_custom_settings = false
|
||||||
|
|
||||||
|
[{*.gant,*.groovy,*.gson,*.gy}]
|
||||||
|
ij_smart_tabs = true
|
||||||
|
ij_groovy_align_group_field_declarations = false
|
||||||
|
ij_groovy_align_multiline_array_initializer_expression = false
|
||||||
|
ij_groovy_align_multiline_assignment = false
|
||||||
|
ij_groovy_align_multiline_binary_operation = false
|
||||||
|
ij_groovy_align_multiline_chained_methods = false
|
||||||
|
ij_groovy_align_multiline_extends_list = false
|
||||||
|
ij_groovy_align_multiline_for = true
|
||||||
|
ij_groovy_align_multiline_list_or_map = true
|
||||||
|
ij_groovy_align_multiline_method_parentheses = false
|
||||||
|
ij_groovy_align_multiline_parameters = true
|
||||||
|
ij_groovy_align_multiline_parameters_in_calls = false
|
||||||
|
ij_groovy_align_multiline_resources = true
|
||||||
|
ij_groovy_align_multiline_ternary_operation = false
|
||||||
|
ij_groovy_align_multiline_throws_list = false
|
||||||
|
ij_groovy_align_named_args_in_map = true
|
||||||
|
ij_groovy_align_throws_keyword = true
|
||||||
|
ij_groovy_array_initializer_new_line_after_left_brace = true
|
||||||
|
ij_groovy_array_initializer_right_brace_on_new_line = true
|
||||||
|
ij_groovy_array_initializer_wrap = on_every_item
|
||||||
|
ij_groovy_assert_statement_wrap = off
|
||||||
|
ij_groovy_assignment_wrap = off
|
||||||
|
ij_groovy_binary_operation_wrap = off
|
||||||
|
ij_groovy_blank_lines_after_class_header = 1
|
||||||
|
ij_groovy_blank_lines_after_imports = 1
|
||||||
|
ij_groovy_blank_lines_after_package = 1
|
||||||
|
ij_groovy_blank_lines_around_class = 1
|
||||||
|
ij_groovy_blank_lines_around_field = 0
|
||||||
|
ij_groovy_blank_lines_around_field_in_interface = 0
|
||||||
|
ij_groovy_blank_lines_around_method = 1
|
||||||
|
ij_groovy_blank_lines_around_method_in_interface = 1
|
||||||
|
ij_groovy_blank_lines_before_imports = 1
|
||||||
|
ij_groovy_blank_lines_before_method_body = 0
|
||||||
|
ij_groovy_blank_lines_before_package = 0
|
||||||
|
ij_groovy_block_brace_style = end_of_line
|
||||||
|
ij_groovy_block_comment_add_space = false
|
||||||
|
ij_groovy_block_comment_at_first_column = true
|
||||||
|
ij_groovy_call_parameters_new_line_after_left_paren = true
|
||||||
|
ij_groovy_call_parameters_right_paren_on_new_line = true
|
||||||
|
ij_groovy_call_parameters_wrap = on_every_item
|
||||||
|
ij_groovy_catch_on_new_line = false
|
||||||
|
ij_groovy_class_annotation_wrap = split_into_lines
|
||||||
|
ij_groovy_class_brace_style = end_of_line
|
||||||
|
ij_groovy_class_count_to_use_import_on_demand = 5
|
||||||
|
ij_groovy_do_while_brace_force = never
|
||||||
|
ij_groovy_else_on_new_line = true
|
||||||
|
ij_groovy_enum_constants_wrap = on_every_item
|
||||||
|
ij_groovy_extends_keyword_wrap = normal
|
||||||
|
ij_groovy_extends_list_wrap = off
|
||||||
|
ij_groovy_field_annotation_wrap = split_into_lines
|
||||||
|
ij_groovy_finally_on_new_line = false
|
||||||
|
ij_groovy_for_brace_force = never
|
||||||
|
ij_groovy_for_statement_new_line_after_left_paren = true
|
||||||
|
ij_groovy_for_statement_right_paren_on_new_line = true
|
||||||
|
ij_groovy_for_statement_wrap = on_every_item
|
||||||
|
ij_groovy_if_brace_force = never
|
||||||
|
ij_groovy_import_annotation_wrap = 2
|
||||||
|
ij_groovy_imports_layout = *,|,javax.**,java.**,|,$*
|
||||||
|
ij_groovy_indent_case_from_switch = true
|
||||||
|
ij_groovy_indent_label_blocks = true
|
||||||
|
ij_groovy_insert_inner_class_imports = false
|
||||||
|
ij_groovy_keep_blank_lines_before_right_brace = 2
|
||||||
|
ij_groovy_keep_blank_lines_in_code = 2
|
||||||
|
ij_groovy_keep_blank_lines_in_declarations = 2
|
||||||
|
ij_groovy_keep_control_statement_in_one_line = true
|
||||||
|
ij_groovy_keep_first_column_comment = true
|
||||||
|
ij_groovy_keep_indents_on_empty_lines = true
|
||||||
|
ij_groovy_keep_line_breaks = true
|
||||||
|
ij_groovy_keep_multiple_expressions_in_one_line = false
|
||||||
|
ij_groovy_keep_simple_blocks_in_one_line = false
|
||||||
|
ij_groovy_keep_simple_classes_in_one_line = true
|
||||||
|
ij_groovy_keep_simple_lambdas_in_one_line = true
|
||||||
|
ij_groovy_keep_simple_methods_in_one_line = true
|
||||||
|
ij_groovy_label_indent_absolute = false
|
||||||
|
ij_groovy_label_indent_size = 0
|
||||||
|
ij_groovy_lambda_brace_style = end_of_line
|
||||||
|
ij_groovy_layout_static_imports_separately = true
|
||||||
|
ij_groovy_line_comment_add_space = false
|
||||||
|
ij_groovy_line_comment_at_first_column = true
|
||||||
|
ij_groovy_method_annotation_wrap = split_into_lines
|
||||||
|
ij_groovy_method_brace_style = end_of_line
|
||||||
|
ij_groovy_method_call_chain_wrap = off
|
||||||
|
ij_groovy_method_parameters_new_line_after_left_paren = true
|
||||||
|
ij_groovy_method_parameters_right_paren_on_new_line = true
|
||||||
|
ij_groovy_method_parameters_wrap = on_every_item
|
||||||
|
ij_groovy_modifier_list_wrap = false
|
||||||
|
ij_groovy_names_count_to_use_import_on_demand = 3
|
||||||
|
ij_groovy_packages_to_use_import_on_demand = java.awt.*,javax.swing.*
|
||||||
|
ij_groovy_parameter_annotation_wrap = normal
|
||||||
|
ij_groovy_parentheses_expression_new_line_after_left_paren = false
|
||||||
|
ij_groovy_parentheses_expression_right_paren_on_new_line = false
|
||||||
|
ij_groovy_prefer_parameters_wrap = false
|
||||||
|
ij_groovy_resource_list_new_line_after_left_paren = true
|
||||||
|
ij_groovy_resource_list_right_paren_on_new_line = true
|
||||||
|
ij_groovy_resource_list_wrap = on_every_item
|
||||||
|
ij_groovy_space_after_assert_separator = true
|
||||||
|
ij_groovy_space_after_colon = true
|
||||||
|
ij_groovy_space_after_comma = true
|
||||||
|
ij_groovy_space_after_comma_in_type_arguments = true
|
||||||
|
ij_groovy_space_after_for_semicolon = true
|
||||||
|
ij_groovy_space_after_quest = true
|
||||||
|
ij_groovy_space_after_type_cast = false
|
||||||
|
ij_groovy_space_before_annotation_parameter_list = false
|
||||||
|
ij_groovy_space_before_array_initializer_left_brace = false
|
||||||
|
ij_groovy_space_before_assert_separator = false
|
||||||
|
ij_groovy_space_before_catch_keyword = true
|
||||||
|
ij_groovy_space_before_catch_left_brace = true
|
||||||
|
ij_groovy_space_before_catch_parentheses = true
|
||||||
|
ij_groovy_space_before_class_left_brace = true
|
||||||
|
ij_groovy_space_before_closure_left_brace = true
|
||||||
|
ij_groovy_space_before_colon = true
|
||||||
|
ij_groovy_space_before_comma = false
|
||||||
|
ij_groovy_space_before_do_left_brace = true
|
||||||
|
ij_groovy_space_before_else_keyword = true
|
||||||
|
ij_groovy_space_before_else_left_brace = true
|
||||||
|
ij_groovy_space_before_finally_keyword = true
|
||||||
|
ij_groovy_space_before_finally_left_brace = true
|
||||||
|
ij_groovy_space_before_for_left_brace = true
|
||||||
|
ij_groovy_space_before_for_parentheses = true
|
||||||
|
ij_groovy_space_before_for_semicolon = false
|
||||||
|
ij_groovy_space_before_if_left_brace = true
|
||||||
|
ij_groovy_space_before_if_parentheses = true
|
||||||
|
ij_groovy_space_before_method_call_parentheses = false
|
||||||
|
ij_groovy_space_before_method_left_brace = true
|
||||||
|
ij_groovy_space_before_method_parentheses = true
|
||||||
|
ij_groovy_space_before_quest = true
|
||||||
|
ij_groovy_space_before_record_parentheses = false
|
||||||
|
ij_groovy_space_before_switch_left_brace = true
|
||||||
|
ij_groovy_space_before_switch_parentheses = true
|
||||||
|
ij_groovy_space_before_synchronized_left_brace = true
|
||||||
|
ij_groovy_space_before_synchronized_parentheses = true
|
||||||
|
ij_groovy_space_before_try_left_brace = true
|
||||||
|
ij_groovy_space_before_try_parentheses = true
|
||||||
|
ij_groovy_space_before_while_keyword = true
|
||||||
|
ij_groovy_space_before_while_left_brace = true
|
||||||
|
ij_groovy_space_before_while_parentheses = true
|
||||||
|
ij_groovy_space_in_named_argument = true
|
||||||
|
ij_groovy_space_in_named_argument_before_colon = false
|
||||||
|
ij_groovy_space_within_empty_array_initializer_braces = false
|
||||||
|
ij_groovy_space_within_empty_method_call_parentheses = false
|
||||||
|
ij_groovy_spaces_around_additive_operators = true
|
||||||
|
ij_groovy_spaces_around_assignment_operators = true
|
||||||
|
ij_groovy_spaces_around_bitwise_operators = true
|
||||||
|
ij_groovy_spaces_around_equality_operators = true
|
||||||
|
ij_groovy_spaces_around_lambda_arrow = true
|
||||||
|
ij_groovy_spaces_around_logical_operators = true
|
||||||
|
ij_groovy_spaces_around_multiplicative_operators = true
|
||||||
|
ij_groovy_spaces_around_regex_operators = true
|
||||||
|
ij_groovy_spaces_around_relational_operators = true
|
||||||
|
ij_groovy_spaces_around_shift_operators = true
|
||||||
|
ij_groovy_spaces_within_annotation_parentheses = false
|
||||||
|
ij_groovy_spaces_within_array_initializer_braces = false
|
||||||
|
ij_groovy_spaces_within_braces = true
|
||||||
|
ij_groovy_spaces_within_brackets = false
|
||||||
|
ij_groovy_spaces_within_cast_parentheses = false
|
||||||
|
ij_groovy_spaces_within_catch_parentheses = false
|
||||||
|
ij_groovy_spaces_within_for_parentheses = false
|
||||||
|
ij_groovy_spaces_within_gstring_injection_braces = false
|
||||||
|
ij_groovy_spaces_within_if_parentheses = false
|
||||||
|
ij_groovy_spaces_within_list_or_map = false
|
||||||
|
ij_groovy_spaces_within_method_call_parentheses = false
|
||||||
|
ij_groovy_spaces_within_method_parentheses = false
|
||||||
|
ij_groovy_spaces_within_parentheses = false
|
||||||
|
ij_groovy_spaces_within_switch_parentheses = false
|
||||||
|
ij_groovy_spaces_within_synchronized_parentheses = false
|
||||||
|
ij_groovy_spaces_within_try_parentheses = false
|
||||||
|
ij_groovy_spaces_within_tuple_expression = false
|
||||||
|
ij_groovy_spaces_within_while_parentheses = false
|
||||||
|
ij_groovy_special_else_if_treatment = true
|
||||||
|
ij_groovy_ternary_operation_wrap = normal
|
||||||
|
ij_groovy_throws_keyword_wrap = normal
|
||||||
|
ij_groovy_throws_list_wrap = off
|
||||||
|
ij_groovy_use_flying_geese_braces = false
|
||||||
|
ij_groovy_use_fq_class_names = false
|
||||||
|
ij_groovy_use_fq_class_names_in_javadoc = true
|
||||||
|
ij_groovy_use_relative_indents = false
|
||||||
|
ij_groovy_use_single_class_imports = true
|
||||||
|
ij_groovy_variable_annotation_wrap = normal
|
||||||
|
ij_groovy_while_brace_force = never
|
||||||
|
ij_groovy_while_on_new_line = false
|
||||||
|
ij_groovy_wrap_chain_calls_after_dot = false
|
||||||
|
ij_groovy_wrap_long_lines = false
|
||||||
|
|
||||||
|
[{*.htm,*.html,*.ng,*.sht,*.shtm,*.shtml}]
|
||||||
|
ij_smart_tabs = true
|
||||||
|
ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3
|
||||||
|
ij_html_align_attributes = false
|
||||||
|
ij_html_align_text = false
|
||||||
|
ij_html_attribute_wrap = off
|
||||||
|
ij_html_block_comment_add_space = false
|
||||||
|
ij_html_block_comment_at_first_column = true
|
||||||
|
ij_html_do_not_align_children_of_min_lines = 0
|
||||||
|
ij_html_do_not_break_if_inline_tags = title,h1,h2,h3,h4,h5,h6,p
|
||||||
|
ij_html_do_not_indent_children_of_tags = none
|
||||||
|
ij_html_enforce_quotes = false
|
||||||
|
ij_html_inline_tags = a,abbr,acronym,b,basefont,bdo,big,br,cite,cite,code,dfn,em,font,i,img,input,kbd,label,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var
|
||||||
|
ij_html_keep_blank_lines = 0
|
||||||
|
ij_html_keep_indents_on_empty_lines = true
|
||||||
|
ij_html_keep_line_breaks = false
|
||||||
|
ij_html_keep_line_breaks_in_text = true
|
||||||
|
ij_html_keep_whitespaces = false
|
||||||
|
ij_html_keep_whitespaces_inside = span,pre,textarea
|
||||||
|
ij_html_line_comment_at_first_column = true
|
||||||
|
ij_html_new_line_after_last_attribute = never
|
||||||
|
ij_html_new_line_before_first_attribute = never
|
||||||
|
ij_html_quote_style = double
|
||||||
|
ij_html_remove_new_line_before_tags = br
|
||||||
|
ij_html_space_after_tag_name = false
|
||||||
|
ij_html_space_around_equality_in_attribute = false
|
||||||
|
ij_html_space_inside_empty_tag = true
|
||||||
|
ij_html_text_wrap = off
|
||||||
|
|
||||||
|
[{*.markdown,*.md}]
|
||||||
|
ij_smart_tabs = true
|
||||||
|
ij_markdown_force_one_space_after_blockquote_symbol = true
|
||||||
|
ij_markdown_force_one_space_after_header_symbol = true
|
||||||
|
ij_markdown_force_one_space_after_list_bullet = true
|
||||||
|
ij_markdown_force_one_space_between_words = true
|
||||||
|
ij_markdown_keep_indents_on_empty_lines = true
|
||||||
|
ij_markdown_max_lines_around_block_elements = 1
|
||||||
|
ij_markdown_max_lines_around_header = 1
|
||||||
|
ij_markdown_max_lines_between_paragraphs = 1
|
||||||
|
ij_markdown_min_lines_around_block_elements = 1
|
||||||
|
ij_markdown_min_lines_around_header = 1
|
||||||
|
ij_markdown_min_lines_between_paragraphs = 1
|
||||||
|
|
||||||
|
[{*.properties,spring.handlers,spring.schemas}]
|
||||||
|
ij_properties_align_group_field_declarations = false
|
||||||
|
ij_properties_keep_blank_lines = true
|
||||||
|
ij_properties_key_value_delimiter = equals
|
||||||
|
ij_properties_spaces_around_key_value_delimiter = true
|
||||||
|
|
@ -1,10 +1,10 @@
|
|||||||
## Core
|
## Core
|
||||||
|
|
||||||
VERSION = 0.4.1.3
|
VERSION = 0.4.2.11
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
|
|
||||||
libSpotbugsVersion = 4.5.0
|
libSpotbugsVersion = 4.5.2
|
||||||
|
|
||||||
libMessivaVersion = 0.1.0.1
|
libMessivaVersion = 0.1.0.1
|
||||||
|
|
||||||
|
@ -4,6 +4,6 @@ package cc.sukazyo.cono.morny;
|
|||||||
* the final field that will be updated by gradle automatically.
|
* the final field that will be updated by gradle automatically.
|
||||||
*/
|
*/
|
||||||
public class GradleProjectConfigures {
|
public class GradleProjectConfigures {
|
||||||
public static final String VERSION = "0.4.1.3";
|
public static final String VERSION = "0.4.2.11";
|
||||||
public static final long COMPILE_TIMESTAMP = 1639476313268L;
|
public static final long COMPILE_TIMESTAMP = 1640595623685L;
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,14 @@ import static cc.sukazyo.cono.morny.Log.logger;
|
|||||||
*/
|
*/
|
||||||
public class MornyCoeur {
|
public class MornyCoeur {
|
||||||
|
|
||||||
|
/** 当前程序的 Morny Coeur 实例 */
|
||||||
|
private static MornyCoeur INSTANCE;
|
||||||
|
|
||||||
|
/** 当前 Morny 的{@link MornyTrusted 信任验证机}实例 */
|
||||||
|
private final MornyTrusted trusted;
|
||||||
|
|
||||||
/** morny 的 bot 账户 */
|
/** morny 的 bot 账户 */
|
||||||
private static TelegramBot account;
|
private final TelegramBot account;
|
||||||
/**
|
/**
|
||||||
* morny 的 bot 账户的用户名<br>
|
* morny 的 bot 账户的用户名<br>
|
||||||
* <br>
|
* <br>
|
||||||
@ -28,36 +34,40 @@ public class MornyCoeur {
|
|||||||
* 如果在登陆之前就定义了此字段,则登陆代码会验证登陆的 bot 的 username
|
* 如果在登陆之前就定义了此字段,则登陆代码会验证登陆的 bot 的 username
|
||||||
* 是否与定义的 username 符合。如果不符合则会报错。
|
* 是否与定义的 username 符合。如果不符合则会报错。
|
||||||
*/
|
*/
|
||||||
private static String username;
|
private final String username;
|
||||||
/**
|
/**
|
||||||
* morny 的事件忽略前缀时间<br>
|
* morny 的事件忽略前缀时间<br>
|
||||||
* <br>
|
* <br>
|
||||||
* {@link cc.sukazyo.cono.morny.bot.event.OnUpdateTimestampOffsetLock}
|
* {@link cc.sukazyo.cono.morny.bot.event.OnUpdateTimestampOffsetLock}
|
||||||
* 会根据这里定义的时间戳取消掉比此时间更早的事件链
|
* 会根据这里定义的时间戳取消掉比此时间更早的事件链
|
||||||
*/
|
*/
|
||||||
public static long latestEventTimestamp;
|
public long latestEventTimestamp;
|
||||||
/**
|
/**
|
||||||
* morny 主程序启动时间<br>
|
* morny 主程序启动时间<br>
|
||||||
* 用于统计数据
|
* 用于统计数据
|
||||||
*/
|
*/
|
||||||
public static final long coeurStartTimestamp = System.currentTimeMillis();
|
public static final long coeurStartTimestamp = System.currentTimeMillis();
|
||||||
|
|
||||||
|
private record LogInResult(TelegramBot account, String username) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bot 启动入口,执行 bot 初始化
|
* 执行 bot 初始化
|
||||||
*
|
*
|
||||||
* @param botKey bot 的 telegram bot api token
|
* @param botKey bot 的 telegram bot api token
|
||||||
* @param botUsername bot 的 username 限定。如果为 null 则表示不限定,
|
* @param botUsername bot 的 username 限定。如果为 null 则表示不限定,
|
||||||
* 如果指定,则登录时会检查所登陆的 bot 的用户名是否与此相等
|
* 如果指定,则登录时会检查所登陆的 bot 的用户名是否与此相等
|
||||||
|
* @param master morny 实例所信任的主人的 id。用于初始化 {@link #trusted}
|
||||||
|
* @param trustedChat morny 实例所信任的群组的 id。用于初始化 {@link #trusted}
|
||||||
* @param latestEventTimestamp 事件处理器会处理事件的最早时间戳 ——
|
* @param latestEventTimestamp 事件处理器会处理事件的最早时间戳 ——
|
||||||
* 只有限定的 message 事件会受此影响。
|
* 只有限定的 message 事件会受此影响。
|
||||||
* 单位为毫秒
|
* 单位为毫秒
|
||||||
*/
|
*/
|
||||||
public static void main (@Nonnull String botKey, @Nullable String botUsername, long latestEventTimestamp) {
|
private MornyCoeur (
|
||||||
|
@Nonnull String botKey, @Nullable String botUsername,
|
||||||
MornyCoeur.latestEventTimestamp = latestEventTimestamp;
|
long master, long trustedChat, long latestEventTimestamp
|
||||||
|
) {
|
||||||
logger.info("System Starting");
|
|
||||||
|
|
||||||
|
this.latestEventTimestamp = latestEventTimestamp;
|
||||||
configureSafeExit();
|
configureSafeExit();
|
||||||
|
|
||||||
logger.info("args key:\n " + botKey);
|
logger.info("args key:\n " + botKey);
|
||||||
@ -65,23 +75,57 @@ public class MornyCoeur {
|
|||||||
logger.info("login as:\n " + botUsername);
|
logger.info("login as:\n " + botUsername);
|
||||||
}
|
}
|
||||||
|
|
||||||
try { account = login(botKey); }
|
try {
|
||||||
catch (Exception e) { logger.error("Cannot login to bot/api. :\n " + e.getMessage()); System.exit(-1); }
|
final LogInResult loginResult = login(botKey);
|
||||||
|
this.account = loginResult.account;
|
||||||
|
this.username = loginResult.username;
|
||||||
|
this.trusted = new MornyTrusted(master, trustedChat);
|
||||||
|
logger.info(String.format("""
|
||||||
|
trusted param set:
|
||||||
|
- master (id)
|
||||||
|
%d
|
||||||
|
- trusted chat (id)
|
||||||
|
%d""",
|
||||||
|
master, trustedChat
|
||||||
|
));
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
RuntimeException ex = new RuntimeException("Cannot login to bot/api. :\n " + e.getMessage());
|
||||||
|
logger.error(ex.getMessage());
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
logger.info("Bot login succeed.");
|
logger.info("Bot login succeed.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 向外界暴露的 morny 初始化入口.
|
||||||
|
* <p>
|
||||||
|
* 如果 morny 已经初始化,则不会进行初始化,抛出错误消息并直接退出方法。
|
||||||
|
*
|
||||||
|
* @see #MornyCoeur 程序初始化方法
|
||||||
|
*/
|
||||||
|
public static void main (
|
||||||
|
@Nonnull String botKey, @Nullable String botUsername,
|
||||||
|
long master, long trustedChat, long latestEventTimestamp
|
||||||
|
) {
|
||||||
|
if (INSTANCE == null) {
|
||||||
|
logger.info("System Starting");
|
||||||
|
INSTANCE = new MornyCoeur(botKey, botUsername, master, trustedChat, latestEventTimestamp);
|
||||||
TrackerDataManager.init();
|
TrackerDataManager.init();
|
||||||
EventListeners.registerAllListeners();
|
EventListeners.registerAllListeners();
|
||||||
account.setUpdatesListener(OnUpdate::onNormalUpdate);
|
INSTANCE.account.setUpdatesListener(OnUpdate::onNormalUpdate);
|
||||||
|
|
||||||
logger.info("System start complete");
|
logger.info("System start complete");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger.error("System already started coeur!!!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于退出时进行缓存的任务处理等进行安全退出
|
* 用于退出时进行缓存的任务处理等进行安全退出
|
||||||
*/
|
*/
|
||||||
private static void exitCleanup () {
|
private void exitCleanup () {
|
||||||
TrackerDataManager.DAEMON.interrupt();
|
TrackerDataManager.DAEMON.interrupt();
|
||||||
TrackerDataManager.trackingLock.lock();
|
TrackerDataManager.trackingLock.lock();
|
||||||
}
|
}
|
||||||
@ -89,8 +133,8 @@ public class MornyCoeur {
|
|||||||
/**
|
/**
|
||||||
* 为程序在虚拟机上添加退出钩子
|
* 为程序在虚拟机上添加退出钩子
|
||||||
*/
|
*/
|
||||||
private static void configureSafeExit () {
|
private void configureSafeExit () {
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread(MornyCoeur::exitCleanup));
|
Runtime.getRuntime().addShutdownHook(new Thread(this::exitCleanup));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -104,18 +148,17 @@ public class MornyCoeur {
|
|||||||
* @return 成功登录后的 {@link TelegramBot} 对象
|
* @return 成功登录后的 {@link TelegramBot} 对象
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static TelegramBot login (@Nonnull String key) {
|
private LogInResult login (@Nonnull String key) {
|
||||||
final TelegramBot account = new TelegramBot(key);
|
final TelegramBot account = new TelegramBot(key);
|
||||||
logger.info("Trying to login...");
|
logger.info("Trying to login...");
|
||||||
for (int i = 1; i < 4; i++) {
|
for (int i = 1; i < 4; i++) {
|
||||||
if (i != 1) logger.info("retrying...");
|
if (i != 1) logger.info("retrying...");
|
||||||
try {
|
try {
|
||||||
final String username = account.execute(new GetMe()).user().username();
|
final String username = account.execute(new GetMe()).user().username();
|
||||||
if (MornyCoeur.username != null && !MornyCoeur.username.equals(username))
|
if (this.username != null && !this.username.equals(username))
|
||||||
throw new RuntimeException("Required the bot @" + MornyCoeur.username + " but @" + username + " logged in!");
|
throw new RuntimeException("Required the bot @" + this.username + " but @" + username + " logged in!");
|
||||||
else MornyCoeur.username = username;
|
|
||||||
logger.info("Succeed login to @" + username);
|
logger.info("Succeed login to @" + username);
|
||||||
return account;
|
return new LogInResult(account, username);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace(System.out);
|
e.printStackTrace(System.out);
|
||||||
logger.error("login failed.");
|
logger.error("login failed.");
|
||||||
@ -129,8 +172,9 @@ public class MornyCoeur {
|
|||||||
*
|
*
|
||||||
* @return {@link #account MornyCoeur.account}
|
* @return {@link #account MornyCoeur.account}
|
||||||
*/
|
*/
|
||||||
|
@Nonnull
|
||||||
public static TelegramBot getAccount () {
|
public static TelegramBot getAccount () {
|
||||||
return account;
|
return INSTANCE.account;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,8 +182,29 @@ public class MornyCoeur {
|
|||||||
*
|
*
|
||||||
* @return {@link #username MornyCoeur.username}
|
* @return {@link #username MornyCoeur.username}
|
||||||
*/
|
*/
|
||||||
|
@Nonnull
|
||||||
public static String getUsername () {
|
public static String getUsername () {
|
||||||
return username;
|
return INSTANCE.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 获取忽略时间点
|
||||||
|
*
|
||||||
|
* @return {@link #latestEventTimestamp MornyCoeur.latestEventTimestamp}
|
||||||
|
*/
|
||||||
|
public static long getLatestEventTimestamp () {
|
||||||
|
return INSTANCE.latestEventTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 Morny 的{@link MornyTrusted 信任验证机}
|
||||||
|
*
|
||||||
|
* @return {@link #trusted MornyCoeur.trusted}
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public static MornyTrusted trustedInstance () {
|
||||||
|
return INSTANCE.trusted;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,18 @@ public class MornyTrusted {
|
|||||||
* 群聊id,其指向的群聊指示了哪个群的成员是受信任的
|
* 群聊id,其指向的群聊指示了哪个群的成员是受信任的
|
||||||
* @see #isTrusted(long) 受信检查
|
* @see #isTrusted(long) 受信检查
|
||||||
*/
|
*/
|
||||||
public static final long TRUSTED_CHAT_ID = -1001541451710L;
|
public final Long TRUSTED_CHAT_ID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* morny 的主人<br>
|
||||||
|
* 这项值的对象总是会被认为是可信任的
|
||||||
|
*/
|
||||||
|
public final long MASTER;
|
||||||
|
|
||||||
|
public MornyTrusted (long master, long trustedChatId) {
|
||||||
|
this.TRUSTED_CHAT_ID = trustedChatId;
|
||||||
|
this.MASTER = master;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于检查一个 telegram-user 是否受信任<br>
|
* 用于检查一个 telegram-user 是否受信任<br>
|
||||||
@ -24,7 +35,8 @@ public class MornyTrusted {
|
|||||||
* @param userId 需要检查的用户的id
|
* @param userId 需要检查的用户的id
|
||||||
* @return 所传递的用户id对应的用户是否受信任
|
* @return 所传递的用户id对应的用户是否受信任
|
||||||
*/
|
*/
|
||||||
public static boolean isTrusted (long userId) {
|
public boolean isTrusted (long userId) {
|
||||||
|
if (userId == MASTER) return true;
|
||||||
final ChatMember chatMember = MornyCoeur.getAccount().execute(new GetChatMember(TRUSTED_CHAT_ID, userId)).chatMember();
|
final ChatMember chatMember = MornyCoeur.getAccount().execute(new GetChatMember(TRUSTED_CHAT_ID, userId)).chatMember();
|
||||||
return (
|
return (
|
||||||
chatMember != null && (
|
chatMember != null && (
|
||||||
|
@ -35,6 +35,13 @@ public class ServerMain {
|
|||||||
* 不要同时使用 {@code --no-hello},原因见下。
|
* 不要同时使用 {@code --no-hello},原因见下。
|
||||||
* </li>
|
* </li>
|
||||||
* <li>
|
* <li>
|
||||||
|
* {@code --token} <b>主程序模式的必选项</b><br>
|
||||||
|
* 用于 bot 启动的 telegram bot api token
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
|
* {@code --username} {@link MornyCoeur#getUsername() bot 的 username} 预定义
|
||||||
|
* </li>
|
||||||
|
* <li>
|
||||||
* {@code --no-hello} 不在主程序启动时输出用于欢迎消息的字符画。
|
* {@code --no-hello} 不在主程序启动时输出用于欢迎消息的字符画。
|
||||||
* 与 {@code --only-hello} 参数不兼容 —— 会导致程序完全没有任何输出
|
* 与 {@code --only-hello} 参数不兼容 —— 会导致程序完全没有任何输出
|
||||||
* </li>
|
* </li>
|
||||||
@ -44,9 +51,15 @@ public class ServerMain {
|
|||||||
* </li>
|
* </li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* 除去选项之外,第一个参数会被赋值为 bot 的 telegram bot api token,
|
* 除去选项之外,第一个参数会被赋值为 bot 的 telegram bot api token,
|
||||||
* 第二个参数会被赋值为 bot 的 username 限定名。其余的参数会被认定为无法理解。
|
* 第二个参数会被赋值为 bot 的 username 限定名。其余的参数会被认定为无法理解。<br>
|
||||||
|
* <br>
|
||||||
|
* <b>自 {@code 0.4.2.3},token 和 username 的赋值已被选项组支持</b><br>
|
||||||
|
* 使用参数所进行取值的 token 和 username 已被转移至 {@code --token} 和 {@code --username} 参数,
|
||||||
|
* <u>或许,直接参数赋值的支持将计划在 {@code 0.4.3} 标记废弃并在 {@code 0.5} 删除。</u>
|
||||||
|
* <s>但实际上这并不影响现在的使用,选项赋值目前仍属于测试功能</s><br>
|
||||||
|
* <b>但请勿混用</b>,这将使两个赋值出现混淆并<b>产生不可知的结果</b>
|
||||||
*
|
*
|
||||||
* @see MornyCoeur#main(String, String, long)
|
* @see MornyCoeur#main(String, String, long, long, long)
|
||||||
* @since 0.4.0.0
|
* @since 0.4.0.0
|
||||||
* @param args 参数组
|
* @param args 参数组
|
||||||
*/
|
*/
|
||||||
@ -55,12 +68,14 @@ public class ServerMain {
|
|||||||
String key = null;
|
String key = null;
|
||||||
String username = null;
|
String username = null;
|
||||||
boolean outdatedBlock = false;
|
boolean outdatedBlock = false;
|
||||||
|
long master = 793274677L;
|
||||||
|
long trustedChat = -1001541451710L;
|
||||||
|
|
||||||
for (String arg : args) {
|
for (int i = 0; i < args.length; i++) {
|
||||||
|
|
||||||
if (arg.startsWith("-")) {
|
if (args[i].startsWith("-")) {
|
||||||
|
|
||||||
switch (arg) {
|
switch (args[i]) {
|
||||||
case "--outdated-block" -> {
|
case "--outdated-block" -> {
|
||||||
outdatedBlock = true;
|
outdatedBlock = true;
|
||||||
continue;
|
continue;
|
||||||
@ -77,22 +92,42 @@ public class ServerMain {
|
|||||||
versionEchoMode = true;
|
versionEchoMode = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
case "--token" -> {
|
||||||
|
i++;
|
||||||
|
key = args[i];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case "--username" -> {
|
||||||
|
i++;
|
||||||
|
username = args[i];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case "--master" -> {
|
||||||
|
i++;
|
||||||
|
master = Long.parseLong(args[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case "--trusted-chat" -> {
|
||||||
|
i++;
|
||||||
|
trustedChat = Long.parseLong(args[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
key = arg;
|
key = args[i];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (username == null) {
|
if (username == null) {
|
||||||
username = arg;
|
username = args[i];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.warn("Can't understand arg to some meaning :\n " + arg);
|
logger.warn("Can't understand arg to some meaning :\n " + args[i]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +155,7 @@ public class ServerMain {
|
|||||||
if (welcomeEchoMode) return;
|
if (welcomeEchoMode) return;
|
||||||
|
|
||||||
assert key != null;
|
assert key != null;
|
||||||
MornyCoeur.main(key, username, outdatedBlock?System.currentTimeMillis():0);
|
MornyCoeur.main(key, username, master, trustedChat, outdatedBlock?System.currentTimeMillis():0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@ public class EventListeners {
|
|||||||
public static final OnUserSlashAction USER_SLASH_ACTION = new OnUserSlashAction();
|
public static final OnUserSlashAction USER_SLASH_ACTION = new OnUserSlashAction();
|
||||||
public static final OnUpdateTimestampOffsetLock UPDATE_TIMESTAMP_OFFSET_LOCK = new OnUpdateTimestampOffsetLock();
|
public static final OnUpdateTimestampOffsetLock UPDATE_TIMESTAMP_OFFSET_LOCK = new OnUpdateTimestampOffsetLock();
|
||||||
public static final OnInlineQuery INLINE_QUERY = new OnInlineQuery();
|
public static final OnInlineQuery INLINE_QUERY = new OnInlineQuery();
|
||||||
|
public static final OnCallMe CALL_ME = new OnCallMe();
|
||||||
|
public static final OnEventHackHandle EVENT_HACK_HANDLE = new OnEventHackHandle();
|
||||||
|
|
||||||
public static void registerAllListeners () {
|
public static void registerAllListeners () {
|
||||||
EventListenerManager.addListener(
|
EventListenerManager.addListener(
|
||||||
@ -16,7 +18,9 @@ public class EventListeners {
|
|||||||
UPDATE_TIMESTAMP_OFFSET_LOCK,
|
UPDATE_TIMESTAMP_OFFSET_LOCK,
|
||||||
COMMANDS_LISTENER,
|
COMMANDS_LISTENER,
|
||||||
USER_SLASH_ACTION,
|
USER_SLASH_ACTION,
|
||||||
INLINE_QUERY
|
INLINE_QUERY,
|
||||||
|
CALL_ME,
|
||||||
|
EVENT_HACK_HANDLE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
139
src/main/java/cc/sukazyo/cono/morny/bot/event/OnCallMe.java
Normal file
139
src/main/java/cc/sukazyo/cono/morny/bot/event/OnCallMe.java
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
package cc.sukazyo.cono.morny.bot.event;
|
||||||
|
|
||||||
|
import cc.sukazyo.cono.morny.MornyCoeur;
|
||||||
|
import cc.sukazyo.cono.morny.MornyTrusted;
|
||||||
|
import cc.sukazyo.cono.morny.bot.api.EventListener;
|
||||||
|
import cc.sukazyo.cono.morny.data.TelegramStickers;
|
||||||
|
import com.pengrad.telegrambot.model.Chat;
|
||||||
|
import com.pengrad.telegrambot.model.Update;
|
||||||
|
import com.pengrad.telegrambot.model.request.ParseMode;
|
||||||
|
import com.pengrad.telegrambot.request.ForwardMessage;
|
||||||
|
import com.pengrad.telegrambot.request.SendMessage;
|
||||||
|
import com.pengrad.telegrambot.request.SendSticker;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import static cc.sukazyo.cono.morny.util.StringUtils.escapeHtmlTelegram;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过 bot 呼叫主人的事件监听管理类
|
||||||
|
* @since 0.4.2.1
|
||||||
|
*/
|
||||||
|
public class OnCallMe extends EventListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主人的 telegram user id,同时被用于 chat id<br>
|
||||||
|
* 跟随 {@link MornyTrusted#MASTER} 的值
|
||||||
|
* @since 0.4.2.1
|
||||||
|
*/
|
||||||
|
private static final long ME = MornyCoeur.trustedInstance().MASTER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听私聊 bot 的消息进行呼叫关键字匹配。
|
||||||
|
* 如果成功,将会执行呼叫函数,并向呼叫者回显{@link TelegramStickers#ID_WAITING "已呼叫"贴纸}
|
||||||
|
*
|
||||||
|
* @param update 事件基础参数,消息事件所属的 tgapi:update 对象
|
||||||
|
* @return 事件基础返回值,是否已完成处理事件:<br>
|
||||||
|
* 如果匹配到呼叫,则返回{@code true},反之返回{@code false}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean onMessage (@Nonnull Update update) {
|
||||||
|
if (update.message().text() == null)
|
||||||
|
return false;
|
||||||
|
if (update.message().chat().type() != Chat.Type.Private)
|
||||||
|
return false;
|
||||||
|
switch (update.message().text().toLowerCase()) {
|
||||||
|
case "steam", "sbeam", "sdeam" ->
|
||||||
|
requestSteamJoin(update);
|
||||||
|
case "hana paresu", "花宫", "内群" ->
|
||||||
|
requestHanaParesuJoin(update);
|
||||||
|
default -> {
|
||||||
|
if (update.message().text().startsWith("cc::")) {
|
||||||
|
requestCustomCall(update);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MornyCoeur.getAccount().execute(new SendSticker(
|
||||||
|
update.message().chat().id(),
|
||||||
|
TelegramStickers.ID_SENT
|
||||||
|
).replyToMessageId(update.message().messageId())
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行 steam library 呼叫<br>
|
||||||
|
* 将会向 {@link #ME} 发送
|
||||||
|
*
|
||||||
|
* @param event 执行呼叫的tg事件
|
||||||
|
*/
|
||||||
|
private static void requestSteamJoin (Update event) {
|
||||||
|
MornyCoeur.getAccount().execute(new SendMessage(
|
||||||
|
ME, String.format(
|
||||||
|
"""
|
||||||
|
request <b>STEAM LIBRARY</b>
|
||||||
|
from <a href="tg://user?id=%d">%s</a>""",
|
||||||
|
event.message().from().id(),
|
||||||
|
escapeHtmlTelegram(
|
||||||
|
event.message().from().firstName() + " " + event.message().from().lastName()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).parseMode(ParseMode.HTML));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行花宫呼叫<br>
|
||||||
|
* 将会向 {@link #ME} 发送
|
||||||
|
*
|
||||||
|
* @param event 执行呼叫的tg事件
|
||||||
|
*/
|
||||||
|
private static void requestHanaParesuJoin (Update event) {
|
||||||
|
MornyCoeur.getAccount().execute(new SendMessage(
|
||||||
|
ME, String.format(
|
||||||
|
"""
|
||||||
|
request <b>Hana Paresu</b>
|
||||||
|
from <a href="tg://user?id=%d">%s</a>""",
|
||||||
|
event.message().from().id(),
|
||||||
|
escapeHtmlTelegram(
|
||||||
|
event.message().from().firstName() + " " + event.message().from().lastName()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).parseMode(ParseMode.HTML));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行自定义呼叫<br>
|
||||||
|
* 将会向 {@link #ME} 发送一个 request 数据消息和转发的原始请求消息<br>
|
||||||
|
* <br>
|
||||||
|
* <u>known issue</u><ul>
|
||||||
|
* <li>无法处理与转发带有媒体的消息</li>
|
||||||
|
* </ul>
|
||||||
|
* <br>
|
||||||
|
* 现在你可以通过这个 bot 来呼叫主人(sukazyo)任何事情了 ——
|
||||||
|
* <s>但是直接私聊sukazyo不好吗</s>
|
||||||
|
*
|
||||||
|
* @param event 执行呼叫的tg事件
|
||||||
|
* @since 0.4.2.2
|
||||||
|
*/
|
||||||
|
private static void requestCustomCall (Update event) {
|
||||||
|
MornyCoeur.getAccount().execute(new SendMessage(
|
||||||
|
ME, String.format(
|
||||||
|
"""
|
||||||
|
request <u>[???]</u>
|
||||||
|
from <a href="tg://user?id=%d">%s</a>""",
|
||||||
|
event.message().from().id(),
|
||||||
|
escapeHtmlTelegram(
|
||||||
|
event.message().from().firstName() + " " + event.message().from().lastName()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).parseMode(ParseMode.HTML));
|
||||||
|
MornyCoeur.getAccount().execute(new ForwardMessage(
|
||||||
|
ME,
|
||||||
|
event.message().chat().id(),
|
||||||
|
event.message().messageId()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -3,11 +3,13 @@ package cc.sukazyo.cono.morny.bot.event;
|
|||||||
import cc.sukazyo.cono.morny.GradleProjectConfigures;
|
import cc.sukazyo.cono.morny.GradleProjectConfigures;
|
||||||
import cc.sukazyo.cono.morny.MornyCoeur;
|
import cc.sukazyo.cono.morny.MornyCoeur;
|
||||||
import cc.sukazyo.cono.morny.MornySystem;
|
import cc.sukazyo.cono.morny.MornySystem;
|
||||||
import cc.sukazyo.cono.morny.MornyTrusted;
|
|
||||||
import cc.sukazyo.cono.morny.bot.api.EventListener;
|
import cc.sukazyo.cono.morny.bot.api.EventListener;
|
||||||
import cc.sukazyo.cono.morny.bot.api.InputCommand;
|
import cc.sukazyo.cono.morny.bot.api.InputCommand;
|
||||||
|
import cc.sukazyo.cono.morny.bot.event.on_commands.EventHack;
|
||||||
import cc.sukazyo.cono.morny.bot.event.on_commands.GetUsernameAndId;
|
import cc.sukazyo.cono.morny.bot.event.on_commands.GetUsernameAndId;
|
||||||
import cc.sukazyo.cono.morny.util.CommonFormatUtils;
|
import cc.sukazyo.cono.morny.bot.event.on_commands.Ip186Query;
|
||||||
|
import cc.sukazyo.cono.morny.data.MornyJrrp;
|
||||||
|
import cc.sukazyo.cono.morny.data.TelegramStickers;
|
||||||
import com.pengrad.telegrambot.model.Update;
|
import com.pengrad.telegrambot.model.Update;
|
||||||
import com.pengrad.telegrambot.model.request.ParseMode;
|
import com.pengrad.telegrambot.model.request.ParseMode;
|
||||||
import com.pengrad.telegrambot.request.SendMessage;
|
import com.pengrad.telegrambot.request.SendMessage;
|
||||||
@ -16,15 +18,12 @@ import com.pengrad.telegrambot.request.SendSticker;
|
|||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import static cc.sukazyo.cono.morny.Log.logger;
|
import static cc.sukazyo.cono.morny.Log.logger;
|
||||||
|
import static cc.sukazyo.cono.morny.util.CommonFormatUtils.formatDate;
|
||||||
|
import static cc.sukazyo.cono.morny.util.CommonFormatUtils.formatDuration;
|
||||||
|
import static cc.sukazyo.cono.morny.util.StringUtils.escapeHtmlTelegram;
|
||||||
|
|
||||||
public class OnCommandExecute extends EventListener {
|
public class OnCommandExecute extends EventListener {
|
||||||
|
|
||||||
private static final String ONLINE_STATUS_RETURN_STICKER_ID = "CAACAgEAAx0CW-CvvgAC5eBhhhODGRuu0pxKLwoQ3yMsowjviAACcycAAnj8xgVVU666si1utiIE";
|
|
||||||
private static final String HELLO_STICKER_ID = "CAACAgEAAxkBAAMnYYYWKNXO4ibo9dlsmDctHhhV6fIAAqooAAJ4_MYFJJhrHS74xUAiBA";
|
|
||||||
private static final String EXIT_STICKER_ID = "CAACAgEAAxkBAAMoYYYWt8UjvP0N405SAyvg2SQZmokAAkMiAAJ4_MYFw6yZLu06b-MiBA";
|
|
||||||
private static final String EXIT_403_STICKER_ID = "CAACAgEAAxkBAAMqYYYa_7hpXH6hMOYMX4Nh8AVYd74AAnQnAAJ4_MYFRdmmsQKLDZgiBA";
|
|
||||||
private static final String NON_COMMAND_QUESTION_STICKER_ID = "CAACAgEAAx0CSQh32gABA966YbRJpbmi2lCHINBDuo1DknSTsbsAAqUoAAJ4_MYFUa8SIaZriAojBA";
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onMessage (@Nonnull Update event) {
|
public boolean onMessage (@Nonnull Update event) {
|
||||||
if (event.message().text() == null) {
|
if (event.message().text() == null) {
|
||||||
@ -38,6 +37,9 @@ public class OnCommandExecute extends EventListener {
|
|||||||
case "/user":
|
case "/user":
|
||||||
GetUsernameAndId.exec(command.getArgs(), event);
|
GetUsernameAndId.exec(command.getArgs(), event);
|
||||||
break;
|
break;
|
||||||
|
case "/event_hack":
|
||||||
|
EventHack.exec(event, command);
|
||||||
|
break;
|
||||||
case "/o":
|
case "/o":
|
||||||
onCommandOnExec(event);
|
onCommandOnExec(event);
|
||||||
break;
|
break;
|
||||||
@ -54,6 +56,13 @@ public class OnCommandExecute extends EventListener {
|
|||||||
case "/runtime":
|
case "/runtime":
|
||||||
onCommandRuntimeExec(event);
|
onCommandRuntimeExec(event);
|
||||||
break;
|
break;
|
||||||
|
case "/jrrp":
|
||||||
|
onCommandJrrpExec(event);
|
||||||
|
break;
|
||||||
|
case "/ip":
|
||||||
|
case "/whois":
|
||||||
|
Ip186Query.exec(event, command);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return nonCommandExecutable(event, command);
|
return nonCommandExecutable(event, command);
|
||||||
}
|
}
|
||||||
@ -65,7 +74,7 @@ public class OnCommandExecute extends EventListener {
|
|||||||
else { // 无法解析的显式命令格式,报错找不到命令
|
else { // 无法解析的显式命令格式,报错找不到命令
|
||||||
MornyCoeur.getAccount().execute(new SendSticker(
|
MornyCoeur.getAccount().execute(new SendSticker(
|
||||||
event.message().chat().id(),
|
event.message().chat().id(),
|
||||||
NON_COMMAND_QUESTION_STICKER_ID
|
TelegramStickers.ID_404
|
||||||
).replyToMessageId(event.message().messageId())
|
).replyToMessageId(event.message().messageId())
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
@ -75,7 +84,7 @@ public class OnCommandExecute extends EventListener {
|
|||||||
private void onCommandOnExec (@Nonnull Update event) {
|
private void onCommandOnExec (@Nonnull Update event) {
|
||||||
MornyCoeur.getAccount().execute(new SendSticker(
|
MornyCoeur.getAccount().execute(new SendSticker(
|
||||||
event.message().chat().id(),
|
event.message().chat().id(),
|
||||||
ONLINE_STATUS_RETURN_STICKER_ID
|
TelegramStickers.ID_ONLINE_STATUS_RETURN
|
||||||
).replyToMessageId(event.message().messageId())
|
).replyToMessageId(event.message().messageId())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -83,16 +92,16 @@ public class OnCommandExecute extends EventListener {
|
|||||||
private void onCommandHelloExec (@Nonnull Update event) {
|
private void onCommandHelloExec (@Nonnull Update event) {
|
||||||
MornyCoeur.getAccount().execute(new SendSticker(
|
MornyCoeur.getAccount().execute(new SendSticker(
|
||||||
event.message().chat().id(),
|
event.message().chat().id(),
|
||||||
HELLO_STICKER_ID
|
TelegramStickers.ID_HELLO
|
||||||
).replyToMessageId(event.message().messageId())
|
).replyToMessageId(event.message().messageId())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onCommandExitExec (@Nonnull Update event) {
|
private void onCommandExitExec (@Nonnull Update event) {
|
||||||
if (MornyTrusted.isTrusted(event.message().from().id())) {
|
if (MornyCoeur.trustedInstance().isTrusted(event.message().from().id())) {
|
||||||
MornyCoeur.getAccount().execute(new SendSticker(
|
MornyCoeur.getAccount().execute(new SendSticker(
|
||||||
event.message().chat().id(),
|
event.message().chat().id(),
|
||||||
EXIT_STICKER_ID
|
TelegramStickers.ID_EXIT
|
||||||
).replyToMessageId(event.message().messageId())
|
).replyToMessageId(event.message().messageId())
|
||||||
);
|
);
|
||||||
logger.info("Morny exited by user @" + event.message().from().username());
|
logger.info("Morny exited by user @" + event.message().from().username());
|
||||||
@ -100,7 +109,7 @@ public class OnCommandExecute extends EventListener {
|
|||||||
} else {
|
} else {
|
||||||
MornyCoeur.getAccount().execute(new SendSticker(
|
MornyCoeur.getAccount().execute(new SendSticker(
|
||||||
event.message().chat().id(),
|
event.message().chat().id(),
|
||||||
EXIT_403_STICKER_ID
|
TelegramStickers.ID_403
|
||||||
).replyToMessageId(event.message().messageId())
|
).replyToMessageId(event.message().messageId())
|
||||||
);
|
);
|
||||||
logger.info("403 exited tag from user @" + event.message().from().username());
|
logger.info("403 exited tag from user @" + event.message().from().username());
|
||||||
@ -110,7 +119,8 @@ public class OnCommandExecute extends EventListener {
|
|||||||
private void onCommandVersionExec (@Nonnull Update event) {
|
private void onCommandVersionExec (@Nonnull Update event) {
|
||||||
MornyCoeur.getAccount().execute(new SendMessage(
|
MornyCoeur.getAccount().execute(new SendMessage(
|
||||||
event.message().chat().id(),
|
event.message().chat().id(),
|
||||||
String.format("""
|
String.format(
|
||||||
|
"""
|
||||||
version:
|
version:
|
||||||
- <code>%s</code>
|
- <code>%s</code>
|
||||||
core md5_hash:
|
core md5_hash:
|
||||||
@ -118,14 +128,17 @@ public class OnCommandExecute extends EventListener {
|
|||||||
compile timestamp:
|
compile timestamp:
|
||||||
- <code>%d</code>
|
- <code>%d</code>
|
||||||
- <code>%s [UTC]</code>""",
|
- <code>%s [UTC]</code>""",
|
||||||
MornySystem.VERSION,
|
escapeHtmlTelegram(MornySystem.VERSION),
|
||||||
MornySystem.getJarMd5(),
|
escapeHtmlTelegram(MornySystem.getJarMd5()),
|
||||||
GradleProjectConfigures.COMPILE_TIMESTAMP,
|
GradleProjectConfigures.COMPILE_TIMESTAMP,
|
||||||
CommonFormatUtils.formatDate(GradleProjectConfigures.COMPILE_TIMESTAMP, 0)
|
escapeHtmlTelegram(formatDate(GradleProjectConfigures.COMPILE_TIMESTAMP, 0))
|
||||||
)
|
)
|
||||||
).replyToMessageId(event.message().messageId()).parseMode(ParseMode.HTML));
|
).replyToMessageId(event.message().messageId()).parseMode(ParseMode.HTML));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 0.4.1.2
|
||||||
|
*/
|
||||||
private void onCommandRuntimeExec (@Nonnull Update event) {
|
private void onCommandRuntimeExec (@Nonnull Update event) {
|
||||||
MornyCoeur.getAccount().execute(new SendMessage(
|
MornyCoeur.getAccount().execute(new SendMessage(
|
||||||
event.message().chat().id(),
|
event.message().chat().id(),
|
||||||
@ -137,34 +150,52 @@ public class OnCommandExecute extends EventListener {
|
|||||||
java runtime:
|
java runtime:
|
||||||
- <code>%s</code>
|
- <code>%s</code>
|
||||||
- <code>%s</code>
|
- <code>%s</code>
|
||||||
memory:
|
vm memory:
|
||||||
- <code>%d</code> / <code>%d</code> MB
|
- <code>%d</code> / <code>%d</code> MB
|
||||||
morny version:
|
morny version:
|
||||||
- <code>%s</code>
|
- <code>%s</code>
|
||||||
- <code>%s</code>
|
- <code>%s</code>
|
||||||
- <code>%s [UTC]</code>
|
- <code>%s [UTC]</code>
|
||||||
- [<code>%d</code>]
|
- [<code>%d</code>]
|
||||||
continuous
|
continuous:
|
||||||
- <code>%s</code>
|
- <code>%s</code>
|
||||||
|
- [<code>%d</code>]
|
||||||
|
- <code>%s [UTC]</code>
|
||||||
- [<code>%d</code>]""",
|
- [<code>%d</code>]""",
|
||||||
// system
|
// system
|
||||||
System.getProperty("os.name"),
|
escapeHtmlTelegram(System.getProperty("os.name")),
|
||||||
System.getProperty("os.version"),
|
escapeHtmlTelegram(System.getProperty("os.version")),
|
||||||
Runtime.getRuntime().availableProcessors(),
|
Runtime.getRuntime().availableProcessors(),
|
||||||
// java
|
// java
|
||||||
System.getProperty("java.vm.name"),
|
escapeHtmlTelegram(System.getProperty("java.vm.name")),
|
||||||
System.getProperty("java.version"),
|
escapeHtmlTelegram(System.getProperty("java.version")),
|
||||||
// memory
|
// memory
|
||||||
Runtime.getRuntime().totalMemory() / 1024 / 1024,
|
Runtime.getRuntime().totalMemory() / 1024 / 1024,
|
||||||
Runtime.getRuntime().maxMemory() / 1024 / 1024,
|
Runtime.getRuntime().maxMemory() / 1024 / 1024,
|
||||||
// version
|
// version
|
||||||
MornySystem.VERSION,
|
escapeHtmlTelegram(MornySystem.VERSION),
|
||||||
MornySystem.getJarMd5(),
|
escapeHtmlTelegram(MornySystem.getJarMd5()),
|
||||||
CommonFormatUtils.formatDate(GradleProjectConfigures.COMPILE_TIMESTAMP, 0),
|
escapeHtmlTelegram(formatDate(GradleProjectConfigures.COMPILE_TIMESTAMP, 0)),
|
||||||
GradleProjectConfigures.COMPILE_TIMESTAMP,
|
GradleProjectConfigures.COMPILE_TIMESTAMP,
|
||||||
// continuous
|
// continuous
|
||||||
CommonFormatUtils.formatDuration(System.currentTimeMillis() - MornyCoeur.coeurStartTimestamp),
|
escapeHtmlTelegram(formatDuration(System.currentTimeMillis() - MornyCoeur.coeurStartTimestamp)),
|
||||||
System.currentTimeMillis() - MornyCoeur.coeurStartTimestamp
|
System.currentTimeMillis() - MornyCoeur.coeurStartTimestamp,
|
||||||
|
escapeHtmlTelegram(formatDate(MornyCoeur.coeurStartTimestamp, 0)),
|
||||||
|
MornyCoeur.coeurStartTimestamp
|
||||||
|
)
|
||||||
|
).replyToMessageId(event.message().messageId()).parseMode(ParseMode.HTML));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onCommandJrrpExec (Update event) {
|
||||||
|
final double jrrp = MornyJrrp.getJrrpFromTelegramUser(event.message().from(), System.currentTimeMillis());
|
||||||
|
final String endChar = jrrp>70 ? "!" : jrrp>30 ? ";" : "...";
|
||||||
|
MornyCoeur.getAccount().execute(new SendMessage(
|
||||||
|
event.message().chat().id(),
|
||||||
|
String.format(
|
||||||
|
"<a href='tg://user?id=%d'>%s</a> 在(utc的)今天的运气指数是———— <code>%.2f%%</code> %s",
|
||||||
|
event.message().from().id(),
|
||||||
|
escapeHtmlTelegram(event.message().from().firstName()),
|
||||||
|
jrrp, escapeHtmlTelegram(endChar)
|
||||||
)
|
)
|
||||||
).replyToMessageId(event.message().messageId()).parseMode(ParseMode.HTML));
|
).replyToMessageId(event.message().messageId()).parseMode(ParseMode.HTML));
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,144 @@
|
|||||||
|
package cc.sukazyo.cono.morny.bot.event;
|
||||||
|
|
||||||
|
import cc.sukazyo.cono.morny.MornyCoeur;
|
||||||
|
import cc.sukazyo.cono.morny.bot.api.EventListener;
|
||||||
|
import cc.sukazyo.cono.morny.util.StringUtils;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.pengrad.telegrambot.model.Update;
|
||||||
|
import com.pengrad.telegrambot.model.request.ParseMode;
|
||||||
|
import com.pengrad.telegrambot.request.SendMessage;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static cc.sukazyo.cono.morny.Log.logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件劫持与序列化工具.
|
||||||
|
* @since 0.4.2.0
|
||||||
|
*/
|
||||||
|
public class OnEventHackHandle extends EventListener {
|
||||||
|
|
||||||
|
/** 事件劫持请求列表 */
|
||||||
|
private static final Map<String, Hacker> hackers = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 触发事件劫持的限定条件.
|
||||||
|
* @since 0.4.2.0
|
||||||
|
*/
|
||||||
|
public enum HackType {
|
||||||
|
/** 只有相同用户发起的事件才会被触发 */
|
||||||
|
USER,
|
||||||
|
/** 只有相同群组内发生的事件才会触发 */
|
||||||
|
GROUP,
|
||||||
|
/** 任何事件都可以触发 */
|
||||||
|
ANY
|
||||||
|
}
|
||||||
|
|
||||||
|
public record Hacker(long fromChatId, long fromMessageId) {
|
||||||
|
@Override public String toString() {
|
||||||
|
return fromChatId + "/" + fromMessageId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 0.4.2.0
|
||||||
|
*/
|
||||||
|
public static void registerHack(long fromMessageId, long fromUserId, long fromChatId, @Nonnull HackType type) {
|
||||||
|
String rec = null;
|
||||||
|
switch (type) {
|
||||||
|
case USER -> rec = String.format("((%d))", fromUserId);
|
||||||
|
case GROUP -> rec = String.format("{{%d}}", fromChatId);
|
||||||
|
case ANY -> rec = "[[]]";
|
||||||
|
}
|
||||||
|
hackers.put(rec, new Hacker(fromChatId, fromMessageId));
|
||||||
|
logger.debug("add hacker track " + rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean onEventHacked (Update update, long chatId, long fromUser) {
|
||||||
|
logger.debug(String.format("try hack {{%d}}((%d))", chatId, fromUser));
|
||||||
|
Hacker x;
|
||||||
|
x = hackers.remove(String.format("((%d))", fromUser));
|
||||||
|
if (x == null) x = hackers.remove(String.format("{{%d}}", chatId));
|
||||||
|
if (x == null) x = hackers.remove("[[]]");
|
||||||
|
if (x == null) return false;
|
||||||
|
logger.debug("hacked event by " + x);
|
||||||
|
MornyCoeur.getAccount().execute(new SendMessage(x.fromChatId, String.format(
|
||||||
|
"<code>%s</code>",
|
||||||
|
StringUtils.escapeHtmlTelegram(new GsonBuilder().setPrettyPrinting().create().toJson(update))
|
||||||
|
)).parseMode(ParseMode.HTML).replyToMessageId((int)x.fromMessageId));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onMessage (@Nonnull Update update) {
|
||||||
|
return onEventHacked(update, update.message().chat().id(), update.message().from().id());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onEditedMessage (@Nonnull Update update) {
|
||||||
|
return onEventHacked(update, update.editedMessage().chat().id(), update.editedMessage().from().id());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onChannelPost (@Nonnull Update update) {
|
||||||
|
return onEventHacked(update, update.channelPost().chat().id(), update.channelPost().from().id());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onEditedChannelPost (@Nonnull Update update) {
|
||||||
|
return onEventHacked(update, update.editedChannelPost().chat().id(), update.editedChannelPost().from().id());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onInlineQuery (@Nonnull Update update) {
|
||||||
|
return onEventHacked(update, 0, update.inlineQuery().from().id());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onChosenInlineResult (@Nonnull Update update) {
|
||||||
|
return onEventHacked(update, 0, update.chosenInlineResult().from().id());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCallbackQuery (@Nonnull Update update) {
|
||||||
|
return onEventHacked(update, 0, update.callbackQuery().from().id());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onShippingQuery (@Nonnull Update update) {
|
||||||
|
return onEventHacked(update, 0, update.shippingQuery().from().id());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPreCheckoutQuery (@Nonnull Update update) {
|
||||||
|
return onEventHacked(update, 0, update.preCheckoutQuery().from().id());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPoll (@Nonnull Update update) {
|
||||||
|
return onEventHacked(update, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPollAnswer (@Nonnull Update update) {
|
||||||
|
return onEventHacked(update, 0, update.pollAnswer().user().id());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onMyChatMemberUpdated (@Nonnull Update update) {
|
||||||
|
return onEventHacked(update, update.myChatMember().chat().id(), update.myChatMember().from().id());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onChatMemberUpdated (@Nonnull Update update) {
|
||||||
|
return onEventHacked(update, update.chatMember().chat().id(), update.chatMember().from().id());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onChatJoinRequest (@Nonnull Update update) {
|
||||||
|
return onEventHacked(update, update.chatJoinRequest().chat().id(), update.chatJoinRequest().from().id());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -8,9 +8,13 @@ import com.pengrad.telegrambot.model.request.InlineQueryResultArticle;
|
|||||||
import com.pengrad.telegrambot.model.request.InputTextMessageContent;
|
import com.pengrad.telegrambot.model.request.InputTextMessageContent;
|
||||||
import com.pengrad.telegrambot.model.request.ParseMode;
|
import com.pengrad.telegrambot.model.request.ParseMode;
|
||||||
import com.pengrad.telegrambot.request.AnswerInlineQuery;
|
import com.pengrad.telegrambot.request.AnswerInlineQuery;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* telegram inlineQuery 功能的处理类,
|
||||||
|
* 也是一个 InlineQueryManager(还没做)
|
||||||
|
*
|
||||||
* @since 0.4.1.3
|
* @since 0.4.1.3
|
||||||
*/
|
*/
|
||||||
public class OnInlineQuery extends EventListener {
|
public class OnInlineQuery extends EventListener {
|
||||||
@ -19,7 +23,7 @@ public class OnInlineQuery extends EventListener {
|
|||||||
* @since 0.4.1.3
|
* @since 0.4.1.3
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean onInlineQuery (@NotNull Update update) {
|
public boolean onInlineQuery (@Nonnull Update update) {
|
||||||
MornyCoeur.getAccount().execute(new AnswerInlineQuery(update.inlineQuery().id(), new InlineQueryResultArticle[]{
|
MornyCoeur.getAccount().execute(new AnswerInlineQuery(update.inlineQuery().id(), new InlineQueryResultArticle[]{
|
||||||
new InlineQueryResultArticle(
|
new InlineQueryResultArticle(
|
||||||
EncryptUtils.encryptByMD5(update.inlineQuery().query()),
|
EncryptUtils.encryptByMD5(update.inlineQuery().query()),
|
||||||
|
@ -3,13 +3,54 @@ package cc.sukazyo.cono.morny.bot.event;
|
|||||||
import cc.sukazyo.cono.morny.MornyCoeur;
|
import cc.sukazyo.cono.morny.MornyCoeur;
|
||||||
import cc.sukazyo.cono.morny.bot.api.EventListener;
|
import cc.sukazyo.cono.morny.bot.api.EventListener;
|
||||||
import com.pengrad.telegrambot.model.Update;
|
import com.pengrad.telegrambot.model.Update;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 阻止 {@link MornyCoeur#latestEventTimestamp 指定时间} 之前的事件处理.
|
||||||
|
* <p>
|
||||||
|
* 只支持以下事件
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link EventListener#onMessage(Update) 收到消息}</li>
|
||||||
|
* <li>{@link EventListener#onEditedMessage(Update) 消息被更新}</li>
|
||||||
|
* <li>{@link EventListener#onChannelPost(Update) 收到频道消息}</li>
|
||||||
|
* <li>{@link EventListener#onEditedChannelPost(Update) 频道消息被更新}</li>
|
||||||
|
* </ul>
|
||||||
|
* @see #isOutdated 时间判断
|
||||||
|
*/
|
||||||
public class OnUpdateTimestampOffsetLock extends EventListener {
|
public class OnUpdateTimestampOffsetLock extends EventListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查传入时间是否在要求时间之前(即"过期").
|
||||||
|
* @param timestamp 传入时间,秒级
|
||||||
|
* @return 如果传入时间在要求时间<u>之前</u>,返回true,反之false
|
||||||
|
* @since 0.4.2.7
|
||||||
|
*/
|
||||||
|
public boolean isOutdated(long timestamp) {
|
||||||
|
return timestamp < MornyCoeur.getLatestEventTimestamp()/1000;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onMessage (@NotNull Update update) {
|
public boolean onMessage (@Nonnull Update update) {
|
||||||
return update.message().date() < MornyCoeur.latestEventTimestamp/1000;
|
return isOutdated(update.message().date());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 0.4.2.6 */
|
||||||
|
@Override
|
||||||
|
public boolean onEditedMessage (@Nonnull Update update) {
|
||||||
|
return isOutdated(update.editedMessage().editDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 0.4.2.6 */
|
||||||
|
@Override
|
||||||
|
public boolean onChannelPost (@Nonnull Update update) {
|
||||||
|
return isOutdated(update.channelPost().date());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 0.4.2.6 */
|
||||||
|
@Override
|
||||||
|
public boolean onEditedChannelPost (@Nonnull Update update) {
|
||||||
|
return isOutdated(update.editedChannelPost().editDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ import com.pengrad.telegrambot.request.SendMessage;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import static cc.sukazyo.cono.morny.util.StringUtils.escapeHtmlTelegram;
|
||||||
|
|
||||||
public class OnUserSlashAction extends EventListener {
|
public class OnUserSlashAction extends EventListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -48,11 +50,11 @@ public class OnUserSlashAction extends EventListener {
|
|||||||
event.message().chat().id(),
|
event.message().chat().id(),
|
||||||
String.format(
|
String.format(
|
||||||
"<a href='tg://user?id=%d'>%s</a> %s%s <a href='tg://user?id=%d'>%s</a>%s%s",
|
"<a href='tg://user?id=%d'>%s</a> %s%s <a href='tg://user?id=%d'>%s</a>%s%s",
|
||||||
origin.id(), origin.firstName(),
|
origin.id(), escapeHtmlTelegram(origin.firstName()),
|
||||||
verb, (useVerbSuffix?"了":""),
|
verb, escapeHtmlTelegram((useVerbSuffix?"了":"")),
|
||||||
target.id(), (origin==target ? "自己" : target.firstName()),
|
target.id(), escapeHtmlTelegram((origin==target ? "自己" : target.firstName())),
|
||||||
(hasObject ? (useObjectPrefix ?" 的": " ") : ""),
|
escapeHtmlTelegram((hasObject ? (useObjectPrefix ?" 的": " ") : "")),
|
||||||
(hasObject ? object : "")
|
escapeHtmlTelegram((hasObject ? object : ""))
|
||||||
)
|
)
|
||||||
).parseMode(ParseMode.HTML));
|
).parseMode(ParseMode.HTML));
|
||||||
|
|
||||||
|
@ -0,0 +1,82 @@
|
|||||||
|
package cc.sukazyo.cono.morny.bot.event.on_commands;
|
||||||
|
|
||||||
|
import cc.sukazyo.cono.morny.MornyCoeur;
|
||||||
|
import cc.sukazyo.cono.morny.MornyTrusted;
|
||||||
|
import cc.sukazyo.cono.morny.bot.api.InputCommand;
|
||||||
|
import cc.sukazyo.cono.morny.bot.event.OnEventHackHandle;
|
||||||
|
import cc.sukazyo.cono.morny.data.TelegramStickers;
|
||||||
|
import com.pengrad.telegrambot.model.Update;
|
||||||
|
import com.pengrad.telegrambot.request.SendSticker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link OnEventHackHandle} 的命令行前端
|
||||||
|
* @since 0.4.2.0
|
||||||
|
*/
|
||||||
|
public class EventHack {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link OnEventHackHandle} 的命令行前端<br>
|
||||||
|
* <br>
|
||||||
|
* 实现了通过命令行进行 EventHack 功能。<br>
|
||||||
|
* 支持三种模式,默认为 {@link OnEventHackHandle.HackType#USER USER},
|
||||||
|
* {@link OnEventHackHandle.HackType#ANY ANY} 时,将会通过 {@link MornyTrusted#isTrusted(long)} 检查触发用户的权限
|
||||||
|
*
|
||||||
|
* @param event 命令基础参数,触发的事件对象本身
|
||||||
|
* @param command 命令基础参数,解析出的命令对象
|
||||||
|
* @since 0.4.2.0
|
||||||
|
*/
|
||||||
|
public static void exec (Update event, InputCommand command) {
|
||||||
|
|
||||||
|
boolean isOk = false;
|
||||||
|
|
||||||
|
String x_mode = "";
|
||||||
|
if (command.hasArgs()) {
|
||||||
|
x_mode = command.getArgs()[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (x_mode) {
|
||||||
|
case "any":
|
||||||
|
if (MornyCoeur.trustedInstance().isTrusted(event.message().from().id())) {
|
||||||
|
OnEventHackHandle.registerHack(
|
||||||
|
event.message().messageId(),
|
||||||
|
event.message().from().id(),
|
||||||
|
event.message().chat().id(),
|
||||||
|
OnEventHackHandle.HackType.ANY
|
||||||
|
);isOk = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "group":
|
||||||
|
OnEventHackHandle.registerHack(
|
||||||
|
event.message().messageId(),
|
||||||
|
event.message().from().id(),
|
||||||
|
event.message().chat().id(),
|
||||||
|
OnEventHackHandle.HackType.GROUP
|
||||||
|
);isOk = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
OnEventHackHandle.registerHack(
|
||||||
|
event.message().messageId(),
|
||||||
|
event.message().from().id(),
|
||||||
|
event.message().chat().id(),
|
||||||
|
OnEventHackHandle.HackType.USER
|
||||||
|
);isOk = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isOk) {
|
||||||
|
MornyCoeur.getAccount().execute(new SendSticker(
|
||||||
|
event.message().chat().id(),
|
||||||
|
TelegramStickers.ID_WAITING
|
||||||
|
).replyToMessageId(event.message().messageId())
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
MornyCoeur.getAccount().execute(new SendSticker(
|
||||||
|
event.message().chat().id(),
|
||||||
|
TelegramStickers.ID_403
|
||||||
|
).replyToMessageId(event.message().messageId())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -10,6 +10,8 @@ import com.pengrad.telegrambot.response.GetChatMemberResponse;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import static cc.sukazyo.cono.morny.util.StringUtils.escapeHtmlTelegram;
|
||||||
|
|
||||||
public class GetUsernameAndId {
|
public class GetUsernameAndId {
|
||||||
|
|
||||||
public static void exec (@Nonnull String[] args, @Nonnull Update event) {
|
public static void exec (@Nonnull String[] args, @Nonnull Update event) {
|
||||||
@ -19,7 +21,7 @@ public class GetUsernameAndId {
|
|||||||
"[Unavailable] Too much arguments."
|
"[Unavailable] Too much arguments."
|
||||||
).replyToMessageId(event.message().messageId())); return; }
|
).replyToMessageId(event.message().messageId())); return; }
|
||||||
|
|
||||||
long userId = 0;
|
long userId = event.message().from().id();
|
||||||
|
|
||||||
if ( event.message().replyToMessage()!= null) {
|
if ( event.message().replyToMessage()!= null) {
|
||||||
userId = event.message().replyToMessage().from().id();
|
userId = event.message().replyToMessage().from().id();
|
||||||
@ -36,14 +38,6 @@ public class GetUsernameAndId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userId == 0) {
|
|
||||||
MornyCoeur.getAccount().execute(new SendMessage(
|
|
||||||
event.message().chat().id(),
|
|
||||||
"[Unavailable] no userid given."
|
|
||||||
).replyToMessageId(event.message().messageId()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final GetChatMemberResponse response = MornyCoeur.getAccount().execute(
|
final GetChatMemberResponse response = MornyCoeur.getAccount().execute(
|
||||||
new GetChatMember(event.message().chat().id(), userId)
|
new GetChatMember(event.message().chat().id(), userId)
|
||||||
);
|
);
|
||||||
@ -62,11 +56,20 @@ public class GetUsernameAndId {
|
|||||||
userInformation.append(String.format(
|
userInformation.append(String.format(
|
||||||
"""
|
"""
|
||||||
userid :
|
userid :
|
||||||
- <code>%d</code>
|
- <code>%d</code>""",
|
||||||
|
userId
|
||||||
|
));
|
||||||
|
if (user.username() == null) {
|
||||||
|
userInformation.append("\nusername : <u>null</u>");
|
||||||
|
} else {
|
||||||
|
userInformation.append(String.format(
|
||||||
|
"""
|
||||||
|
|
||||||
username :
|
username :
|
||||||
- <code>%s</code>""",
|
- <code>%s</code>""",
|
||||||
userId, user.username()
|
escapeHtmlTelegram(user.username())
|
||||||
));
|
));
|
||||||
|
}
|
||||||
if (user.firstName() == null) {
|
if (user.firstName() == null) {
|
||||||
userInformation.append("\nfirstname : <u>null</u>");
|
userInformation.append("\nfirstname : <u>null</u>");
|
||||||
} else {
|
} else {
|
||||||
@ -75,7 +78,7 @@ public class GetUsernameAndId {
|
|||||||
|
|
||||||
firstname :
|
firstname :
|
||||||
- <code>%s</code>""",
|
- <code>%s</code>""",
|
||||||
user.firstName()
|
escapeHtmlTelegram(user.firstName())
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if (user.lastName() == null) {
|
if (user.lastName() == null) {
|
||||||
@ -86,7 +89,7 @@ public class GetUsernameAndId {
|
|||||||
|
|
||||||
lastname :
|
lastname :
|
||||||
- <code>%s</code>""",
|
- <code>%s</code>""",
|
||||||
user.lastName()
|
escapeHtmlTelegram(user.lastName())
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if (user.languageCode() != null) {
|
if (user.languageCode() != null) {
|
||||||
@ -95,7 +98,7 @@ public class GetUsernameAndId {
|
|||||||
|
|
||||||
language-code :
|
language-code :
|
||||||
- <code>%s</code>""",
|
- <code>%s</code>""",
|
||||||
user.languageCode()
|
escapeHtmlTelegram(user.languageCode())
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
package cc.sukazyo.cono.morny.bot.event.on_commands;
|
||||||
|
|
||||||
|
import cc.sukazyo.cono.morny.MornyCoeur;
|
||||||
|
import cc.sukazyo.cono.morny.bot.api.InputCommand;
|
||||||
|
import cc.sukazyo.cono.morny.data.ip186.IP186QueryResponse;
|
||||||
|
import cc.sukazyo.cono.morny.data.ip186.IP186QueryHandler;
|
||||||
|
import com.pengrad.telegrambot.model.Update;
|
||||||
|
import com.pengrad.telegrambot.model.request.ParseMode;
|
||||||
|
import com.pengrad.telegrambot.request.SendMessage;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import static cc.sukazyo.cono.morny.util.StringUtils.escapeHtmlTelegram;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@value IP186QueryHandler#SITE_URL} 查询的 telegram 命令前端
|
||||||
|
* @since 0.4.2.10
|
||||||
|
*/
|
||||||
|
public class Ip186Query {
|
||||||
|
|
||||||
|
public static void exec (@Nonnull Update event, @Nonnull InputCommand command) {
|
||||||
|
|
||||||
|
if (!command.hasArgs()) { MornyCoeur.getAccount().execute(new SendMessage(
|
||||||
|
event.message().chat().id(),
|
||||||
|
"[Unavailable] No ip defined."
|
||||||
|
).replyToMessageId(event.message().messageId())); return; }
|
||||||
|
|
||||||
|
if (command.getArgs().length > 1) { MornyCoeur.getAccount().execute(new SendMessage(
|
||||||
|
event.message().chat().id(),
|
||||||
|
"[Unavailable] Too much arguments."
|
||||||
|
).replyToMessageId(event.message().messageId())); return; }
|
||||||
|
|
||||||
|
try {
|
||||||
|
IP186QueryResponse response = switch (command.getCommand()) {
|
||||||
|
case "/ip" -> IP186QueryHandler.queryIp(command.getArgs()[0]);
|
||||||
|
case "/whois" -> IP186QueryHandler.queryWhois(command.getArgs()[0]);
|
||||||
|
default -> throw new IllegalArgumentException("Unknown 186-IP query method " + command.getCommand());
|
||||||
|
};
|
||||||
|
MornyCoeur.getAccount().execute(new SendMessage(
|
||||||
|
event.message().chat().id(),
|
||||||
|
escapeHtmlTelegram(response.url()) + "\n<code>" + escapeHtmlTelegram(response.body()) + "</code>"
|
||||||
|
).parseMode(ParseMode.HTML).replyToMessageId(event.message().messageId()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
MornyCoeur.getAccount().execute(new SendMessage(
|
||||||
|
event.message().chat().id(),
|
||||||
|
"[Exception] in query:\n<code>" + escapeHtmlTelegram(e.getMessage()) + "</code>"
|
||||||
|
).parseMode(ParseMode.HTML).replyToMessageId(event.message().messageId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
package cc.sukazyo.cono.morny.bot.event.on_commands;
|
||||||
|
|
||||||
|
public class Roll {
|
||||||
|
}
|
45
src/main/java/cc/sukazyo/cono/morny/data/MornyJrrp.java
Normal file
45
src/main/java/cc/sukazyo/cono/morny/data/MornyJrrp.java
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package cc.sukazyo.cono.morny.data;
|
||||||
|
|
||||||
|
import cc.sukazyo.cono.morny.util.EncryptUtils;
|
||||||
|
import com.pengrad.telegrambot.model.User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Morny 的 jrrp 运算类.
|
||||||
|
*
|
||||||
|
* @see #getJrrpFromTelegramUser(User,long)
|
||||||
|
* @see #calcJrrpXmomi(long,long)
|
||||||
|
* @since 0.4.2.9
|
||||||
|
*/
|
||||||
|
public class MornyJrrp {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过 telegram 用户和时间戳作为参数获取 jrrp.
|
||||||
|
*
|
||||||
|
* @see #calcJrrpXmomi 当前版本的实现算法 {@code Xmomi}
|
||||||
|
* @since 0.4.2.9
|
||||||
|
* @param user telegram 用户
|
||||||
|
* @param timestamp 时间戳
|
||||||
|
* @return 通过当前版本的算法计算出的用户 jrrp 值,取值为 {@code [0.00, 100.00]}
|
||||||
|
*/
|
||||||
|
public static double getJrrpFromTelegramUser (User user, long timestamp) {
|
||||||
|
return calcJrrpXmomi(user.id(), timestamp / (1000 * 60 * 60 * 24)) * 100.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code Xmomi} 版本的 jrrp 算法.
|
||||||
|
* <p>
|
||||||
|
* 算法规则为,将用户id与日期戳链接为 <u><code>uid@daystamp</code></u> 这样的字符串,
|
||||||
|
* 然后通过 MD5 计算出字符串的哈希值,取哈希值前4个字节,将其作为16进制数值表示法转换为取值为 {@code [0x0000, 0xffff]} 的数值,
|
||||||
|
* 得到的数值除以区间最大值 {@code 0xffff} 即可得到一个分布在 {@code [0.0, 1.0]} 之间的分布值,
|
||||||
|
* 这个分布值乘以 {@code 100.0},即为计算得到的 jrrp 数值。
|
||||||
|
*
|
||||||
|
* @since 0.4.2.9
|
||||||
|
* @param userId telegram 用户 uid
|
||||||
|
* @param dayStamp unix 时间戳转换为日期单位后的数值. 数值应该在转换前转换时区
|
||||||
|
* @return 算法得到的 jrrp 值,取值为 {@code [0.00. 100.00]}
|
||||||
|
*/
|
||||||
|
public static double calcJrrpXmomi (long userId, long dayStamp) {
|
||||||
|
return (double)Long.parseLong(EncryptUtils.encryptByMD5(userId + "@" + dayStamp).substring(0, 4), 16) / (double)0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package cc.sukazyo.cono.morny.data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存放 bot 使用到的贴纸
|
||||||
|
* @since 0.4.2.0
|
||||||
|
*/
|
||||||
|
public class TelegramStickers {
|
||||||
|
|
||||||
|
public static final String ID_ONLINE_STATUS_RETURN = "CAACAgEAAx0CW-CvvgAC5eBhhhODGRuu0pxKLwoQ3yMsowjviAACcycAAnj8xgVVU666si1utiIE";
|
||||||
|
public static final String ID_HELLO = "CAACAgEAAxkBAAMnYYYWKNXO4ibo9dlsmDctHhhV6fIAAqooAAJ4_MYFJJhrHS74xUAiBA";
|
||||||
|
public static final String ID_EXIT = "CAACAgEAAxkBAAMoYYYWt8UjvP0N405SAyvg2SQZmokAAkMiAAJ4_MYFw6yZLu06b-MiBA";
|
||||||
|
public static final String ID_403 = "CAACAgEAAxkBAAMqYYYa_7hpXH6hMOYMX4Nh8AVYd74AAnQnAAJ4_MYFRdmmsQKLDZgiBA";
|
||||||
|
public static final String ID_404 = "CAACAgEAAx0CSQh32gABA966YbRJpbmi2lCHINBDuo1DknSTsbsAAqUoAAJ4_MYFUa8SIaZriAojBA";
|
||||||
|
public static final String ID_WAITING = "CAACAgEAAx0CSQh32gABA-8DYbh7W2VhJ490ucfZMUMrgMR2FW4AAm4nAAJ4_MYFjx6zpxJPWsQjBA";
|
||||||
|
public static final String ID_SENT = "CAACAgEAAx0CSQh32gABA--zYbiyU_wOijEitp-0tSl_k7W6l3gAAgMmAAJ4_MYF4GrompjXPx4jBA";
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
package cc.sukazyo.cono.morny.data.ip186;
|
||||||
|
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
import okhttp3.ResponseBody;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过 {@value #SITE_URL} 进行 {@link #queryIp ip}/{@link #queryWhois whois} 数据查询的工具类
|
||||||
|
*
|
||||||
|
* @since 0.4.2.10
|
||||||
|
*/
|
||||||
|
public class IP186QueryHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求所使用的 HTTP API 站点链接
|
||||||
|
* @since 0.4.2.10
|
||||||
|
*/
|
||||||
|
public static final String SITE_URL = "https://ip.186526.xyz/";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进行 {@link #queryIp ip 查询}时所使用的 API 参数.<br>
|
||||||
|
* 目的使 API 直接返回原始数据
|
||||||
|
*/
|
||||||
|
private static final String QUERY_IP_PARAM = "type=json&format=true";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进行 {@link #queryWhois whois 查询}时所使用的 API 参数.<br>
|
||||||
|
* 目的使 API 直接返回原始数据
|
||||||
|
*/
|
||||||
|
private static final String QUERY_WHOIS_PARAM = "type=plain";
|
||||||
|
|
||||||
|
/** 请求时使用的 OkHttp 请求工具实例 */
|
||||||
|
private static final OkHttpClient httpClient = new OkHttpClient();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过 {@value #SITE_URL} 获取 ip 信息.
|
||||||
|
* @see #QUERY_IP_PARAM 发送请求时所使用的 API 参数
|
||||||
|
* @param ip 需要进行查询的 ip
|
||||||
|
* @return 查询结果。data 根据 {@value #SITE_URL} 的规则以 json 序列化
|
||||||
|
* @throws IOException 任何请求或解析错误
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public static IP186QueryResponse queryIp (String ip) throws IOException {
|
||||||
|
final String requestUrl = SITE_URL + ip;
|
||||||
|
return commonQuery(requestUrl, QUERY_IP_PARAM);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过 {@value #SITE_URL} 获取域名信息.
|
||||||
|
* @see #QUERY_WHOIS_PARAM 发送请求时所使用的 API 参数
|
||||||
|
* @param domain 需要进行查询的域名
|
||||||
|
* @return 查询结果。data 根据 {@value #SITE_URL} 的规则以 plain 序列化
|
||||||
|
* @throws IOException 任何请求或解析错误
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
public static IP186QueryResponse queryWhois (String domain) throws IOException {
|
||||||
|
final String requestUrl = SITE_URL + "whois/" + domain;
|
||||||
|
return commonQuery(requestUrl, QUERY_WHOIS_PARAM);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private static IP186QueryResponse commonQuery (String requestUrl, String queryIpParam) throws IOException {
|
||||||
|
Request request = new Request.Builder().url(requestUrl + "?" + queryIpParam).build();
|
||||||
|
try (Response response = httpClient.newCall(request).execute()) {
|
||||||
|
final ResponseBody body = response.body();
|
||||||
|
if (body == null) throw new IOException("Null body.");
|
||||||
|
return new IP186QueryResponse(requestUrl, body.string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package cc.sukazyo.cono.morny.data.ip186;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link IP186QueryHandler} 的请求结果数据的通用封装类.
|
||||||
|
*
|
||||||
|
* @since 0.4.2.10
|
||||||
|
* @param url 请求数据的<u>人类可读的</u>来源链接,<b>并非api链接</b>
|
||||||
|
* @param body API 传回的数据内容
|
||||||
|
*/
|
||||||
|
public record IP186QueryResponse(String url, String body) {
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package cc.sukazyo.cono.morny.util;
|
package cc.sukazyo.cono.morny.util;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
@ -18,6 +19,7 @@ public class EncryptUtils {
|
|||||||
/***
|
/***
|
||||||
* 对指定的字符串进行MD5加密
|
* 对指定的字符串进行MD5加密
|
||||||
*/
|
*/
|
||||||
|
@Nonnull
|
||||||
public static String encryptByMD5(String originString) {
|
public static String encryptByMD5(String originString) {
|
||||||
try {
|
try {
|
||||||
//创建具有MD5算法的信息摘要
|
//创建具有MD5算法的信息摘要
|
||||||
@ -28,9 +30,8 @@ public class EncryptUtils {
|
|||||||
String s = byteArrayToHex(bytes);
|
String s = byteArrayToHex(bytes);
|
||||||
return s.toUpperCase();
|
return s.toUpperCase();
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
e.printStackTrace();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,17 +3,9 @@ package cc.sukazyo.cono.morny.util;
|
|||||||
import javax.annotation.Nonnegative;
|
import javax.annotation.Nonnegative;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public class StringUtils {
|
public class StringUtils {
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public static String repeatChar (char c, int i) {
|
|
||||||
final char[] chars = new char[i];
|
|
||||||
Arrays.fill(chars, c);
|
|
||||||
return new String(chars);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static String[] formatCommand (@Nonnull String com) {
|
public static String[] formatCommand (@Nonnull String com) {
|
||||||
|
|
||||||
@ -66,4 +58,12 @@ public class StringUtils {
|
|||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static String escapeHtmlTelegram (String raw) {
|
||||||
|
raw = raw.replaceAll("&", "&");
|
||||||
|
raw = raw.replaceAll("<", "<");
|
||||||
|
raw = raw.replaceAll(">", ">");
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user