2023-06-18, merge local and online guess dictionary

master
CHUN YU YAO 2023-06-19 00:19:49 +08:00
parent 57535ea7a1
commit 91019fec33
5 changed files with 249 additions and 354 deletions

View File

@ -53,7 +53,7 @@ import webbrowser
import argparse import argparse
import itertools import itertools
CONST_APP_VERSION = "MaxBot (2023.6.17)" CONST_APP_VERSION = "MaxBot (2023.6.18)"
CONST_MAXBOT_CONFIG_FILE = "settings.json" CONST_MAXBOT_CONFIG_FILE = "settings.json"
CONST_MAXBOT_LAST_URL_FILE = "MAXBOT_LAST_URL.txt" CONST_MAXBOT_LAST_URL_FILE = "MAXBOT_LAST_URL.txt"
@ -805,68 +805,68 @@ def guess_answer_list_from_multi_options(tmp_text):
show_debug_message = True # debug. show_debug_message = True # debug.
show_debug_message = False # online show_debug_message = False # online
options_list = None options_list = []
matched_pattern = "" matched_pattern = ""
if options_list is None: if len(options_list) == 0:
if u'' in tmp_text and u'' in tmp_text: if u'' in tmp_text and u'' in tmp_text:
pattern = '【.{1,4}】' pattern = '【.{1,4}】'
options_list = re.findall(pattern, tmp_text) options_list = re.findall(pattern, tmp_text)
if len(options_list) <= 2: if len(options_list) <= 2:
options_list = None options_list = []
else: else:
matched_pattern = pattern matched_pattern = pattern
if options_list is None: if len(options_list) == 0:
if u'(' in tmp_text and u')' in tmp_text: if u'(' in tmp_text and u')' in tmp_text:
pattern = '\(.{1,4}\)' pattern = '\(.{1,4}\)'
options_list = re.findall(pattern, tmp_text) options_list = re.findall(pattern, tmp_text)
if len(options_list) <= 2: if len(options_list) <= 2:
options_list = None options_list = []
else: else:
matched_pattern = pattern matched_pattern = pattern
if options_list is None: if len(options_list) == 0:
if u'[' in tmp_text and u']' in tmp_text: if u'[' in tmp_text and u']' in tmp_text:
pattern = '\[.{1,4}\]' pattern = '\[.{1,4}\]'
options_list = re.findall(pattern, tmp_text) options_list = re.findall(pattern, tmp_text)
if len(options_list) <= 2: if len(options_list) <= 2:
options_list = None options_list = []
else: else:
matched_pattern = pattern matched_pattern = pattern
if options_list is None: if len(options_list) == 0:
if "\n" in tmp_text and u')' in tmp_text: if "\n" in tmp_text and u')' in tmp_text:
pattern = "\\n.{1,4}\)" pattern = "\\n.{1,4}\)"
options_list = re.findall(pattern, tmp_text) options_list = re.findall(pattern, tmp_text)
if len(options_list) <= 2: if len(options_list) <= 2:
options_list = None options_list = []
else: else:
matched_pattern = pattern matched_pattern = pattern
if options_list is None: if len(options_list) == 0:
if "\n" in tmp_text and u']' in tmp_text: if "\n" in tmp_text and u']' in tmp_text:
pattern = "\\n.{1,4}\]" pattern = "\\n.{1,4}\]"
options_list = re.findall(pattern, tmp_text) options_list = re.findall(pattern, tmp_text)
if len(options_list) <= 2: if len(options_list) <= 2:
options_list = None options_list = []
else: else:
matched_pattern = pattern matched_pattern = pattern
if options_list is None: if len(options_list) == 0:
if "\n" in tmp_text and u'' in tmp_text: if "\n" in tmp_text and u'' in tmp_text:
pattern = "\\n.{1,4}】" pattern = "\\n.{1,4}】"
options_list = re.findall(pattern, tmp_text) options_list = re.findall(pattern, tmp_text)
if len(options_list) <= 2: if len(options_list) <= 2:
options_list = None options_list = []
else: else:
matched_pattern = pattern matched_pattern = pattern
if options_list is None: if len(options_list) == 0:
if "\n" in tmp_text and u':' in tmp_text: if "\n" in tmp_text and u':' in tmp_text:
pattern = "\\n.{1,4}:" pattern = "\\n.{1,4}:"
options_list = re.findall(pattern, tmp_text) options_list = re.findall(pattern, tmp_text)
if len(options_list) <= 2: if len(options_list) <= 2:
options_list = None options_list = []
else: else:
matched_pattern = pattern matched_pattern = pattern
@ -878,8 +878,8 @@ def guess_answer_list_from_multi_options(tmp_text):
if show_debug_message: if show_debug_message:
print("is_trim_quota:", is_trim_quota) print("is_trim_quota:", is_trim_quota)
return_list = None return_list = []
if not options_list is None: if len(options_list) > 0:
options_list_length = len(options_list) options_list_length = len(options_list)
if show_debug_message: if show_debug_message:
print("options_list_length:", options_list_length) print("options_list_length:", options_list_length)
@ -928,13 +928,12 @@ def guess_answer_list_from_multi_options(tmp_text):
else: else:
return_list.append(each_option) return_list.append(each_option)
# something is wrong, give up those options. # something is wrong, give up when option equal 2 options.
if not return_list is None: if len(return_list) <= 2:
if len(return_list) <= 2: return_list = []
return_list = None
# remove chinese work options. # remove chinese work options.
if not return_list is None: if len(options_list) > 0:
new_list = [] new_list = []
for item in return_list: for item in return_list:
if is_all_alpha_or_numeric(item): if is_all_alpha_or_numeric(item):
@ -946,7 +945,7 @@ def guess_answer_list_from_multi_options(tmp_text):
#PS: this may get a wrong answer list. XD #PS: this may get a wrong answer list. XD
def guess_answer_list_from_symbols(captcha_text_div_text): def guess_answer_list_from_symbols(captcha_text_div_text):
return_list = None return_list = []
# need replace to space to get first options. # need replace to space to get first options.
tmp_text = captcha_text_div_text tmp_text = captcha_text_div_text
tmp_text = tmp_text.replace(u'?',u' ') tmp_text = tmp_text.replace(u'?',u' ')
@ -973,7 +972,7 @@ def guess_answer_list_from_symbols(captcha_text_div_text):
if len(my_anwser) > 0: if len(my_anwser) > 0:
return_list.append(my_anwser) return_list.append(my_anwser)
if not return_list is None: if len(return_list) > 0:
break break
return return_list return return_list
@ -1022,8 +1021,6 @@ def guess_answer_list_from_hint(CONST_EXAMPLE_SYMBOL, CONST_INPUT_SYMBOL, captch
show_debug_message = True # debug. show_debug_message = True # debug.
show_debug_message = False # online show_debug_message = False # online
return_list = None
tmp_text = format_question_string(CONST_EXAMPLE_SYMBOL, CONST_INPUT_SYMBOL, captcha_text_div_text) tmp_text = format_question_string(CONST_EXAMPLE_SYMBOL, CONST_INPUT_SYMBOL, captcha_text_div_text)
my_question = "" my_question = ""
@ -1212,6 +1209,7 @@ def guess_answer_list_from_hint(CONST_EXAMPLE_SYMBOL, CONST_INPUT_SYMBOL, captch
if show_debug_message: if show_debug_message:
print("is_trim_quota:", is_trim_quota) print("is_trim_quota:", is_trim_quota)
return_list = []
if len(my_anwser_formated) > 0: if len(my_anwser_formated) > 0:
new_pattern = my_anwser_formated new_pattern = my_anwser_formated
if len(my_answer_delimitor) > 0: if len(my_answer_delimitor) > 0:
@ -1242,6 +1240,9 @@ def guess_answer_list_from_hint(CONST_EXAMPLE_SYMBOL, CONST_INPUT_SYMBOL, captch
return_list[idx]=return_list[idx].replace(my_answer_delimitor,'') return_list[idx]=return_list[idx].replace(my_answer_delimitor,'')
if show_debug_message: if show_debug_message:
print("cleaned return_list:" , return_list) print("cleaned return_list:" , return_list)
if return_list is None:
return_list = []
return return_list, offical_hint_string_anwser return return_list, offical_hint_string_anwser
@ -1321,20 +1322,20 @@ def get_answer_list_by_question(CONST_EXAMPLE_SYMBOL, CONST_INPUT_SYMBOL, captch
show_debug_message = True # debug. show_debug_message = True # debug.
show_debug_message = False # online show_debug_message = False # online
return_list = None return_list = []
tmp_text = format_question_string(CONST_EXAMPLE_SYMBOL, CONST_INPUT_SYMBOL, captcha_text_div_text) tmp_text = format_question_string(CONST_EXAMPLE_SYMBOL, CONST_INPUT_SYMBOL, captcha_text_div_text)
# guess answer list from multi-options: 【】() [] # guess answer list from multi-options: 【】() []
if return_list is None: if len(return_list)==0:
return_list = guess_answer_list_from_multi_options(tmp_text) return_list = guess_answer_list_from_multi_options(tmp_text)
if show_debug_message: if show_debug_message:
print("captcha_text_div_text:", captcha_text_div_text) print("captcha_text_div_text:", captcha_text_div_text)
if not return_list is None: if len(return_list) > 0:
print("found, guess_answer_list_from_multi_options:", return_list) print("found, guess_answer_list_from_multi_options:", return_list)
offical_hint_string_anwser = "" offical_hint_string_anwser = ""
if return_list is None: if len(return_list)==0:
return_list, offical_hint_string_anwser = guess_answer_list_from_hint(CONST_EXAMPLE_SYMBOL, CONST_INPUT_SYMBOL, captcha_text_div_text) return_list, offical_hint_string_anwser = guess_answer_list_from_hint(CONST_EXAMPLE_SYMBOL, CONST_INPUT_SYMBOL, captcha_text_div_text)
else: else:
is_match_factorial = False is_match_factorial = False
@ -1366,15 +1367,15 @@ def get_answer_list_by_question(CONST_EXAMPLE_SYMBOL, CONST_INPUT_SYMBOL, captch
for item_tuple in new_array: for item_tuple in new_array:
return_list.append(''.join(item_tuple)) return_list.append(''.join(item_tuple))
if show_debug_message: if show_debug_message:
if not return_list is None: if len(return_list) > 0:
print("found, guess_answer_list_from_hint:", return_list) print("found, guess_answer_list_from_hint:", return_list)
if return_list is None: if len(return_list)==0:
return_list = guess_answer_list_from_symbols(captcha_text_div_text) return_list = guess_answer_list_from_symbols(captcha_text_div_text)
if show_debug_message: if show_debug_message:
if not return_list is None: if len(return_list) > 0:
print("found, guess_answer_list_from_symbols:", return_list) print("found, guess_answer_list_from_symbols:", return_list)
return return_list return return_list
@ -2292,7 +2293,6 @@ def guess_tixcraft_question(driver, question_text):
show_debug_message = True # debug. show_debug_message = True # debug.
show_debug_message = False # online show_debug_message = False # online
inferred_answer_string = None
answer_list = [] answer_list = []
formated_html_text = "" formated_html_text = ""
@ -2318,6 +2318,9 @@ def guess_tixcraft_question(driver, question_text):
if show_debug_message: if show_debug_message:
print("formated_html_text:", formated_html_text) print("formated_html_text:", formated_html_text)
# start to guess answer
inferred_answer_string = None
# 請輸入"YES",代表您已詳閱且瞭解並同意。 # 請輸入"YES",代表您已詳閱且瞭解並同意。
if inferred_answer_string is None: if inferred_answer_string is None:
@ -2333,12 +2336,15 @@ def guess_tixcraft_question(driver, question_text):
if '輸入【同意】' in formated_html_text: if '輸入【同意】' in formated_html_text:
inferred_answer_string = '同意' inferred_answer_string = '同意'
if len(question_text) > 0: if inferred_answer_string is None:
inferred_answer_string, answer_list = get_answer_list_from_question_string(None, question_text) if len(question_text) > 0:
answer_list = get_answer_list_from_question_string(None, question_text)
else:
answer_list = [answer_list]
return inferred_answer_string, answer_list return answer_list
def fill_common_verify_form(driver, config_dict, inferred_answer_string, fail_list, input_text_css, next_step_button_css, submit_by_enter): def fill_common_verify_form(driver, config_dict, inferred_answer_string, fail_list, input_text_css, next_step_button_css, submit_by_enter, check_input_interval):
show_debug_message = True # debug. show_debug_message = True # debug.
show_debug_message = False # online show_debug_message = False # online
@ -2383,27 +2389,28 @@ def fill_common_verify_form(driver, config_dict, inferred_answer_string, fail_li
is_answer_sent = False is_answer_sent = False
if form_input is not None: if form_input is not None:
if len(inferred_answer_string) > 0: if len(inferred_answer_string) > 0:
try: if inputed_value != inferred_answer_string:
# PS: sometime may send key twice... try:
form_input.clear() # PS: sometime may send key twice...
form_input.send_keys(inferred_answer_string) form_input.clear()
is_button_clicked = False form_input.send_keys(inferred_answer_string)
if is_do_press_next_button: is_button_clicked = False
if submit_by_enter: if is_do_press_next_button:
form_input.send_keys(Keys.ENTER) if submit_by_enter:
is_button_clicked = True form_input.send_keys(Keys.ENTER)
if len(next_step_button_css) > 0: is_button_clicked = True
is_button_clicked = force_press_button(driver, By.CSS_SELECTOR, next_step_button_css) if len(next_step_button_css) > 0:
is_button_clicked = force_press_button(driver, By.CSS_SELECTOR, next_step_button_css)
if is_button_clicked:
is_answer_sent = True if is_button_clicked:
fail_list.append(inferred_answer_string) is_answer_sent = True
fail_list.append(inferred_answer_string)
if show_debug_message:
print("sent password by bot:", inferred_answer_string, " at #", len(fail_list))
except Exception as exc:
if show_debug_message: if show_debug_message:
print("sent password by bot:", inferred_answer_string, " at #", len(fail_list)) print(exc)
except Exception as exc: pass
if show_debug_message:
print(exc)
pass
if is_answer_sent: if is_answer_sent:
for i in range(3): for i in range(3):
@ -2418,13 +2425,43 @@ def fill_common_verify_form(driver, config_dict, inferred_answer_string, fail_li
# no answer to fill. # no answer to fill.
if len(inputed_value)==0: if len(inputed_value)==0:
try: try:
form_input.click() # solution 1: js.
time.sleep(0.1) driver.execute_script("if(!(document.activeElement === arguments[0])){arguments[0].focus();}", form_input)
# solution 2: selenium.
#form_input.click()
time.sleep(check_input_interval)
except Exception as exc: except Exception as exc:
pass pass
return is_answer_sent, fail_list return is_answer_sent, fail_list
def get_answer_list_from_user_guess_string(config_dict):
local_array = []
online_array = []
user_guess_string = config_dict["advanced"]["user_guess_string"]
if len(user_guess_string) > 0:
user_guess_string = format_config_keyword_for_json(user_guess_string)
try:
local_array = json.loads("["+ user_guess_string +"]")
except Exception as exc:
local_array = []
# load from internet.
user_guess_string = ""
if len(config_dict["advanced"]["online_dictionary_url"]) > 0:
if os.path.exists(CONST_MAXBOT_ANSWER_ONLINE_FILE):
with open(CONST_MAXBOT_ANSWER_ONLINE_FILE, "r") as text_file:
user_guess_string = text_file.readline()
if len(user_guess_string) > 0:
user_guess_string = format_config_keyword_for_json(user_guess_string)
try:
online_array = json.loads("["+ user_guess_string +"]")
except Exception as exc:
online_array = []
return local_array + online_array
def tixcraft_verify(driver, config_dict, fail_list): def tixcraft_verify(driver, config_dict, fail_list):
show_debug_message = True # debug. show_debug_message = True # debug.
show_debug_message = False # online show_debug_message = False # online
@ -2432,47 +2469,34 @@ def tixcraft_verify(driver, config_dict, fail_list):
if config_dict["advanced"]["verbose"]: if config_dict["advanced"]["verbose"]:
show_debug_message = True show_debug_message = True
inferred_answer_string = ""
answer_list = [] answer_list = []
question_text = get_tixcraft_question_text(driver) question_text = get_tixcraft_question_text(driver)
write_question_to_file(question_text) if len(question_text) > 0:
write_question_to_file(question_text)
presale_code = config_dict["advanced"]["user_guess_string"] answer_list = get_answer_list_from_user_guess_string(config_dict)
if len(answer_list)==0:
if config_dict["advanced"]["auto_guess_options"]:
answer_list = guess_tixcraft_question(driver, question_text)
# load from internet. inferred_answer_string = ""
if len(presale_code) == 0: for answer_item in answer_list:
if len(config_dict["advanced"]["online_dictionary_url"]) > 0: if not answer_item in fail_list:
if os.path.exists(CONST_MAXBOT_ANSWER_ONLINE_FILE): inferred_answer_string = answer_item
with open(CONST_MAXBOT_ANSWER_ONLINE_FILE, "r") as text_file: break
presale_code = text_file.readline()
if len(presale_code) > 0: if show_debug_message:
presale_code = format_config_keyword_for_json(presale_code) print("answer_index:", answer_index)
answer_list = [] print("inferred_answer_string:", inferred_answer_string)
try: print("answer_list:", answer_list)
answer_list = json.loads("["+ presale_code +"]")
except Exception as exc:
answer_list = []
if len(inferred_answer_string)==0: # PS: auto-focus() when empty inferred_answer_string with empty inputed text value.
if config_dict["advanced"]["auto_guess_options"]: input_text_css = "input[name='checkCode']"
inferred_answer_string, answer_list = guess_tixcraft_question(driver, question_text) next_step_button_css = ""
submit_by_enter = True
for answer_item in answer_list: check_input_interval = 0.2
if not answer_item in fail_list: is_answer_sent, fail_list = fill_common_verify_form(driver, config_dict, inferred_answer_string, fail_list, input_text_css, next_step_button_css, submit_by_enter)
inferred_answer_string = answer_item
break
if show_debug_message:
print("answer_index:", answer_index)
print("inferred_answer_string:", inferred_answer_string)
print("answer_list:", answer_list)
input_text_css = "input[name='checkCode']"
next_step_button_css = ""
submit_by_enter = True
is_answer_sent, fail_list = fill_common_verify_form(driver, config_dict, inferred_answer_string, fail_list, input_text_css, next_step_button_css, submit_by_enter)
return fail_list return fail_list
@ -3658,7 +3682,7 @@ def get_answer_list_from_question_string(registrationsNewApp_div, captcha_text_d
show_debug_message = False # online show_debug_message = False # online
inferred_answer_string = None inferred_answer_string = None
answer_list = None answer_list = []
CONST_EXAMPLE_SYMBOL = "範例" CONST_EXAMPLE_SYMBOL = "範例"
CONST_INPUT_SYMBOL = "輸入" CONST_INPUT_SYMBOL = "輸入"
@ -3667,17 +3691,22 @@ def get_answer_list_from_question_string(registrationsNewApp_div, captcha_text_d
captcha_text_div_text = "" captcha_text_div_text = ""
# 請在下方空白處輸入引號內文字: # 請在下方空白處輸入引號內文字:
# 請回答下列問題,請在下方空格輸入DELIGHT請以半形輸入法作答大小寫需要一模一樣
if inferred_answer_string is None: if inferred_answer_string is None:
is_use_quota_message = False is_use_quota_message = False
if u"" in captcha_text_div_text and u"" in captcha_text_div_text: if u"" in captcha_text_div_text and u"" in captcha_text_div_text:
if u'' in captcha_text_div_text and u'' in captcha_text_div_text and CONST_INPUT_SYMBOL in captcha_text_div_text and u'引號' in captcha_text_div_text and u'' in captcha_text_div_text: # test for rule#1, it's seem very easy conflict...
match_quota_text_items = ["下方","空白","輸入","引號","文字"]
is_match_quota_text = True
for each_quota_text in match_quota_text_items:
if not each_quota_text in captcha_text_div_text:
is_match_quota_text = False
if is_match_quota_text:
is_use_quota_message = True is_use_quota_message = True
if u'半形' in captcha_text_div_text and CONST_INPUT_SYMBOL in captcha_text_div_text and u'引號' in captcha_text_div_text and u'' in captcha_text_div_text: print("is_use_quota_message:" , is_use_quota_message)
is_use_quota_message = True
#print("is_use_quota_message:" , is_use_quota_message)
if is_use_quota_message: if is_use_quota_message:
inferred_answer_string = find_between(captcha_text_div_text, u"", u"") inferred_answer_string = find_between(captcha_text_div_text, u"", u"")
#print("find captcha text:" , inferred_answer_string) print("find captcha text:" , inferred_answer_string)
if inferred_answer_string is None: if inferred_answer_string is None:
is_use_quota_message = False is_use_quota_message = False
@ -3735,7 +3764,6 @@ def get_answer_list_from_question_string(registrationsNewApp_div, captcha_text_d
inferred_answer_string = None inferred_answer_string = None
#print("is_combine_two_question:", is_combine_two_question) #print("is_combine_two_question:", is_combine_two_question)
# still no answer. # still no answer.
if inferred_answer_string is None: if inferred_answer_string is None:
if not is_combine_two_question: if not is_combine_two_question:
@ -3749,9 +3777,9 @@ def get_answer_list_from_question_string(registrationsNewApp_div, captcha_text_d
else: else:
if show_debug_message: if show_debug_message:
print("got an inferred_answer_string:", inferred_answer_string) print("got an inferred_answer_string:", inferred_answer_string)
answer_list = [inferred_answer_string]
return answer_list
return inferred_answer_string, answer_list
def kktix_reg_captcha_question_text(captcha_inner_div): def kktix_reg_captcha_question_text(captcha_inner_div):
captcha_text_div = None captcha_text_div = None
@ -3774,20 +3802,6 @@ def kktix_reg_captcha_question_text(captcha_inner_div):
return question_text return question_text
def kktix_reg_new_captcha(registrationsNewApp_div, question_text):
show_debug_message = True # debug.
show_debug_message = False # online
answer_list = None
inferred_answer_string = None
if len(question_text) > 0:
if show_debug_message:
print("question_text:", question_text)
inferred_answer_string, answer_list = get_answer_list_from_question_string(registrationsNewApp_div, question_text)
return inferred_answer_string, answer_list
def kktix_double_check_all_text_value(driver, ticket_number): def kktix_double_check_all_text_value(driver, ticket_number):
is_do_press_next_button = False is_do_press_next_button = False
@ -3824,169 +3838,70 @@ def kktix_double_check_all_text_value(driver, ticket_number):
return is_do_press_next_button return is_do_press_next_button
def kktix_reg_captcha(driver, config_dict, answer_index, is_finish_checkbox_click, registrationsNewApp_div): def get_kktix_question_text(driver):
question_text = ""
captcha_inner_div = None
try:
captcha_inner_div = driver.find_element(By.CSS_SELECTOR, 'div.custom-captcha-inner')
except Exception as exc:
pass
if not captcha_inner_div is None:
question_text = kktix_reg_captcha_question_text(captcha_inner_div)
return question_text
def kktix_reg_captcha(driver, config_dict, fail_list, captcha_sound_played, is_finish_checkbox_click, registrationsNewApp_div):
show_debug_message = True # debug. show_debug_message = True # debug.
show_debug_message = False # online show_debug_message = False # online
if config_dict["advanced"]["verbose"]: if config_dict["advanced"]["verbose"]:
show_debug_message = True show_debug_message = True
is_captcha_appear = False answer_list = []
is_captcha_appear_and_filled_password = False
answer_list = None
# TODO: in guess options mode, no need to travel div again. question_text = get_kktix_question_text(driver)
captcha_inner_div = None if len(question_text) > 0:
try:
captcha_inner_div = driver.find_element(By.CSS_SELECTOR, '.custom-captcha-inner')
except Exception as exc:
pass
captcha_password_input_element = None
question_text = ""
if not captcha_inner_div is None:
try:
captcha_password_input_element = captcha_inner_div.find_element(By.TAG_NAME, "input")
if show_debug_message:
print("found captcha input field")
except Exception as exc:
pass
question_text = kktix_reg_captcha_question_text(captcha_inner_div)
write_question_to_file(question_text) write_question_to_file(question_text)
if not captcha_password_input_element is None: if len(fail_list)==0:
inferred_answer_string = "" # only play sound once.
if captcha_inner_div is not None: if not captcha_sound_played:
is_captcha_appear = True captcha_sound_played = True
if show_debug_message:
print("found captcha_inner_div layor.")
user_guess_string = ""
if len(config_dict["advanced"]["user_guess_string"]) > 0:
user_guess_string = config_dict["advanced"]["user_guess_string"]
# load from internet.
if len(user_guess_string) == 0:
if len(config_dict["advanced"]["online_dictionary_url"]) > 0:
if os.path.exists(CONST_MAXBOT_ANSWER_ONLINE_FILE):
with open(CONST_MAXBOT_ANSWER_ONLINE_FILE, "r") as text_file:
user_guess_string = text_file.readline()
if len(user_guess_string) > 0:
user_guess_string = format_config_keyword_for_json(user_guess_string)
answer_list = []
try: try:
answer_list = json.loads("["+ user_guess_string +"]") check_and_play_sound_for_captcha(config_dict)
except Exception as exc: except Exception as exc:
answer_list = []
if len(answer_list) == 1:
inferred_answer_string = answer_list[0]
if len(user_guess_string) == 0:
if config_dict["advanced"]["auto_guess_options"]:
inferred_answer_string, answer_list = kktix_reg_new_captcha(registrationsNewApp_div, question_text)
if inferred_answer_string is None:
inferred_answer_string = ""
if len(inferred_answer_string) > 0:
# password is not None, try to send.
is_cpatcha_sent = kktix_input_captcha_text(captcha_password_input_element, inferred_answer_string)
if is_cpatcha_sent:
is_captcha_appear_and_filled_password = True
else:
is_try_to_focus = False
if answer_list is None:
is_try_to_focus = True
else:
if len(answer_list)==0:
is_try_to_focus = True
if is_try_to_focus:
# password is None, focus to input, and play sound.
inputed_captcha_text = None
try:
inputed_captcha_text = captcha_password_input_element.get_attribute('value')
except Exception as exc:
pass
if inputed_captcha_text is None:
inputed_captcha_text = ""
if len(inputed_captcha_text) == 0:
try:
#print("focus() captcha to input.")
# only this case: "ticket number not changed by bot" to play sound!
check_and_play_sound_for_captcha(config_dict)
captcha_password_input_element.click()
time.sleep(1.0)
# let user to input answer, bot sleep 1 second.
except Exception as exc:
pass
if show_debug_message:
print("is_captcha_appear:", is_captcha_appear)
print("is_captcha_appear_and_filled_password:", is_captcha_appear_and_filled_password)
# retry check agree checkbox again.
if not is_finish_checkbox_click:
if config_dict["auto_check_agree"]:
is_need_refresh, is_finish_checkbox_click = kktix_check_agree_checkbox(driver, config_dict)
is_do_press_next_button = False
auto_press_next_step_button = config_dict["kktix"]["auto_press_next_step_button"]
if auto_press_next_step_button:
if is_finish_checkbox_click:
is_do_press_next_button = kktix_double_check_all_text_value(driver, config_dict["ticket_number"])
else:
print("still unable to assign checkbox as selected.")
if show_debug_message:
print("is_do_press_next_button:", is_do_press_next_button)
if is_do_press_next_button:
if not is_captcha_appear:
click_ret = kktix_press_next_button(driver)
else:
if is_captcha_appear_and_filled_password:
# for easy guest mode, we can fill the password correct.
#print("for easy guest mode, we can fill the password correct.")
click_ret = kktix_press_next_button(driver)
else:
# not is easy guest mode.
#print("# not is easy guest mode.")
# merge with password dictionary, so need remove duplicate list
# PS: now, there are no password dictionary.
if not answer_list is None:
if len(answer_list) > 1:
unique = [x for i, x in enumerate(answer_list) if answer_list.index(x) == i]
answer_list = unique
# start to try answers.
if not answer_list is None:
# for popular event
if len(answer_list) > 0:
if answer_index < len(answer_list)-1:
if kktix_captcha_inputed_text(captcha_inner_div) == "":
answer_index += 1
answer_string = answer_list[answer_index]
if len(answer_string) > 0:
print("send answer:" + answer_string)
is_cpatcha_sent = kktix_input_captcha_text(captcha_password_input_element, answer_string)
if is_cpatcha_sent:
kktix_press_next_button(driver)
else:
# exceed index, do nothing.
pass
else:
# captcha appeared, but we don't have answer list.
pass pass
return answer_index answer_list = get_answer_list_from_user_guess_string(config_dict)
if len(answer_list)==0:
if config_dict["advanced"]["auto_guess_options"]:
answer_list = get_answer_list_from_question_string(registrationsNewApp_div, question_text)
def kktix_reg_new_main(driver, config_dict, answer_index, is_finish_checkbox_click): inferred_answer_string = ""
for answer_item in answer_list:
if not answer_item in fail_list:
inferred_answer_string = answer_item
break
if show_debug_message:
print("inferred_answer_string:", inferred_answer_string)
print("answer_list:", answer_list)
print("fail_list:", fail_list)
# PS: auto-focus() when empty inferred_answer_string with empty inputed text value.
input_text_css = 'div.custom-captcha-inner > div > div > input'
next_step_button_css = '#registrationsNewApp div.form-actions button.btn-primary'
submit_by_enter = False
check_input_interval = 0.2
is_answer_sent, fail_list = fill_common_verify_form(driver, config_dict, inferred_answer_string, fail_list, input_text_css, next_step_button_css, submit_by_enter, check_input_interval)
else:
# no captcha text popup, goto next page.
click_ret = kktix_press_next_button(driver)
return fail_list, captcha_sound_played
def kktix_reg_new_main(driver, config_dict, fail_list, captcha_sound_played, is_finish_checkbox_click):
show_debug_message = True # debug. show_debug_message = True # debug.
show_debug_message = False # online show_debug_message = False # online
@ -4032,7 +3947,7 @@ def kktix_reg_new_main(driver, config_dict, answer_index, is_finish_checkbox_cli
# part 3: captcha # part 3: captcha
if is_ticket_number_assigned: if is_ticket_number_assigned:
answer_index = kktix_reg_captcha(driver, config_dict, answer_index, is_finish_checkbox_click, registrationsNewApp_div) fail_list, captcha_sound_played = kktix_reg_captcha(driver, config_dict, fail_list, captcha_sound_played, is_finish_checkbox_click, registrationsNewApp_div)
else: else:
if is_need_refresh: if is_need_refresh:
try: try:
@ -4045,14 +3960,13 @@ def kktix_reg_new_main(driver, config_dict, answer_index, is_finish_checkbox_cli
if config_dict["advanced"]["auto_reload_random_delay"]: if config_dict["advanced"]["auto_reload_random_delay"]:
time.sleep(random.randint(0,CONST_AUTO_RELOAD_RANDOM_DELAY_MAX_SECOND)) time.sleep(random.randint(0,CONST_AUTO_RELOAD_RANDOM_DELAY_MAX_SECOND))
return answer_index return fail_list, captcha_sound_played
def kktix_reg_new(driver, url, answer_index, kktix_register_status_last, config_dict): def kktix_reg_auto_reload(driver, url, config_dict, kktix_register_status_last):
registerStatus = kktix_register_status_last registerStatus = kktix_register_status_last
# auto refresh for area list page. # auto refresh for area list page.
is_need_refresh = False is_need_refresh = False
is_finish_checkbox_click = False
if not is_need_refresh: if not is_need_refresh:
if registerStatus is None: if registerStatus is None:
@ -4065,6 +3979,7 @@ def kktix_reg_new(driver, url, answer_index, kktix_register_status_last, config_
if registerStatus != 'IN_STOCK': if registerStatus != 'IN_STOCK':
is_need_refresh = True is_need_refresh = True
is_finish_checkbox_click = False
if config_dict["auto_check_agree"]: if config_dict["auto_check_agree"]:
if not is_need_refresh: if not is_need_refresh:
is_need_refresh, is_finish_checkbox_click = kktix_check_agree_checkbox(driver, config_dict) is_need_refresh, is_finish_checkbox_click = kktix_check_agree_checkbox(driver, config_dict)
@ -4083,15 +3998,7 @@ def kktix_reg_new(driver, url, answer_index, kktix_register_status_last, config_
if config_dict["advanced"]["auto_reload_random_delay"]: if config_dict["advanced"]["auto_reload_random_delay"]:
time.sleep(random.randint(0,CONST_AUTO_RELOAD_RANDOM_DELAY_MAX_SECOND)) time.sleep(random.randint(0,CONST_AUTO_RELOAD_RANDOM_DELAY_MAX_SECOND))
# reset answer_index return is_need_refresh, is_finish_checkbox_click
answer_index = -1
registerStatus = None
else:
# check is able to buy.
if config_dict["kktix"]["auto_fill_ticket_number"]:
answer_index = kktix_reg_new_main(driver, config_dict, answer_index, is_finish_checkbox_click)
return answer_index, registerStatus
# PURPOSE: get target area list. # PURPOSE: get target area list.
@ -6742,7 +6649,6 @@ def tixcraft_main(driver, url, config_dict, tixcraft_dict, ocr, Captcha_Browser)
return tixcraft_dict return tixcraft_dict
def kktix_main(driver, url, config_dict, kktix_dict): def kktix_main(driver, url, config_dict, kktix_dict):
auto_press_next_step_button = config_dict["kktix"]["auto_press_next_step_button"]
kktix_account = config_dict["advanced"]["kktix_account"] kktix_account = config_dict["advanced"]["kktix_account"]
is_url_contain_sign_in = False is_url_contain_sign_in = False
@ -6754,7 +6660,17 @@ def kktix_main(driver, url, config_dict, kktix_dict):
if not is_url_contain_sign_in: if not is_url_contain_sign_in:
if '/registrations/new' in url: if '/registrations/new' in url:
kktix_dict["answer_index"], kktix_dict["kktix_register_status_last"] = kktix_reg_new(driver, url, kktix_dict["answer_index"], kktix_dict["kktix_register_status_last"], config_dict) is_need_refresh, is_finish_checkbox_click = kktix_reg_auto_reload(driver, url, config_dict, kktix_dict["kktix_register_status_last"])
if is_need_refresh:
# reset answer fail list.
kktix_dict["fail_list"] = []
kktix_dict["captcha_sound_played"] = False
kktix_dict["kktix_register_status_last"] = None
else:
# check is able to buy.
if config_dict["kktix"]["auto_fill_ticket_number"]:
kktix_dict["fail_list"], kktix_dict["captcha_sound_played"] = kktix_reg_new_main(driver, config_dict, kktix_dict["fail_list"], kktix_dict["captcha_sound_played"], is_finish_checkbox_click)
else: else:
is_event_page = False is_event_page = False
if '/events/' in url: if '/events/' in url:
@ -6763,12 +6679,14 @@ def kktix_main(driver, url, config_dict, kktix_dict):
is_event_page = True is_event_page = True
if is_event_page: if is_event_page:
if auto_press_next_step_button: if config_dict["kktix"]["auto_press_next_step_button"]:
# pass switch check. # pass switch check.
#print("should press next here.") #print("should press next here.")
kktix_events_press_next_button(driver) kktix_events_press_next_button(driver)
kktix_dict["answer_index"] = -1 # reset answer fail list.
kktix_dict["fail_list"] = []
kktix_dict["captcha_sound_played"] = False
kktix_dict["kktix_register_status_last"] = None kktix_dict["kktix_register_status_last"] = None
if '/events/' in url and '/registrations/' in url and "-" in url: if '/events/' in url and '/registrations/' in url and "-" in url:
@ -7314,18 +7232,6 @@ def get_ibon_question_text(driver):
return question_text return question_text
def guess_ibon_question(driver, question_text):
show_debug_message = True # debug.
show_debug_message = False # online
inferred_answer_string = None
answer_list = []
if len(question_text) > 0:
inferred_answer_string, answer_list = get_answer_list_from_question_string(None, question_text)
return inferred_answer_string, answer_list
def ibon_verification_question(driver, fail_list, config_dict): def ibon_verification_question(driver, fail_list, config_dict):
show_debug_message = True # debug. show_debug_message = True # debug.
show_debug_message = False # online show_debug_message = False # online
@ -7333,47 +7239,35 @@ def ibon_verification_question(driver, fail_list, config_dict):
if config_dict["advanced"]["verbose"]: if config_dict["advanced"]["verbose"]:
show_debug_message = True show_debug_message = True
inferred_answer_string = ""
answer_list = [] answer_list = []
question_text = get_ibon_question_text(driver) question_text = get_ibon_question_text(driver)
write_question_to_file(question_text) if len(question_text) > 0:
write_question_to_file(question_text)
presale_code = config_dict["advanced"]["user_guess_string"] answer_list = get_answer_list_from_user_guess_string(config_dict)
if len(answer_list)==0:
if config_dict["advanced"]["auto_guess_options"]:
answer_list = get_answer_list_from_question_string(None, question_text)
# load from internet. inferred_answer_string = ""
if len(presale_code) == 0: if len(answer_list) > 0:
if len(config_dict["advanced"]["online_dictionary_url"]) > 0: for answer_item in answer_list:
if os.path.exists(CONST_MAXBOT_ANSWER_ONLINE_FILE): if not answer_item in fail_list:
with open(CONST_MAXBOT_ANSWER_ONLINE_FILE, "r") as text_file: inferred_answer_string = answer_item
presale_code = text_file.readline() break
if len(presale_code) > 0: if show_debug_message:
presale_code = format_config_keyword_for_json(presale_code) print("inferred_answer_string:", inferred_answer_string)
answer_list = [] print("answer_list:", answer_list)
try: print("fail_list:", fail_list)
answer_list = json.loads("["+ presale_code +"]")
except Exception as exc:
answer_list = []
if len(inferred_answer_string)==0: # PS: auto-focus() when empty inferred_answer_string with empty inputed text value.
if config_dict["advanced"]["auto_guess_options"]: input_text_css = 'div.editor-box > div > div.form-group > input'
inferred_answer_string, answer_list = guess_ibon_question(driver, question_text) next_step_button_css = 'div.editor-box > div > a.btn'
submit_by_enter = False
for answer_item in answer_list: check_input_interval = 0.2
if not answer_item in fail_list: is_answer_sent, fail_list = fill_common_verify_form(driver, config_dict, inferred_answer_string, fail_list, input_text_css, next_step_button_css, submit_by_enter, check_input_interval)
inferred_answer_string = answer_item
break
if show_debug_message:
print("inferred_answer_string:", inferred_answer_string)
print("answer_list:", answer_list)
print("fail_list:", fail_list)
input_text_css = 'div.editor-box > div > div.form-group > input'
next_step_button_css = 'div.editor-box > div > a.btn'
submit_by_enter = False
is_answer_sent, fail_list = fill_common_verify_form(driver, config_dict, inferred_answer_string, fail_list, input_text_css, next_step_button_css, submit_by_enter)
return fail_list return fail_list
@ -10432,7 +10326,8 @@ def main(args):
# for kktix # for kktix
kktix_dict = {} kktix_dict = {}
kktix_dict["answer_index"]=-1 kktix_dict["fail_list"]=[]
kktix_dict["captcha_sound_played"] = False
kktix_dict["kktix_register_status_last"] = None kktix_dict["kktix_register_status_last"] = None
kktix_dict["is_popup_checkout"] = False kktix_dict["is_popup_checkout"] = False
@ -10716,11 +10611,10 @@ if __name__ == "__main__":
#captcha_text_div_text = "請問以下哪一部戲劇是Off Gun合作出演的戲劇【1G】Midnight Museum 【2F】10 Years Ticket 【8B】Not Me (請以半形輸入法作答,大小寫/阿拉伯數字需要一模一樣範例9A)" #captcha_text_div_text = "請問以下哪一部戲劇是Off Gun合作出演的戲劇【1G】Midnight Museum 【2F】10 Years Ticket 【8B】Not Me (請以半形輸入法作答,大小寫/阿拉伯數字需要一模一樣範例9A)"
#captcha_text_div_text = "請將以下【歌曲】已發行日期由「新到舊」依序排列 【H1】 After LIKE 【22】 I AM 【R3】 ELEVEN 【74】LOVE DIVE 請以半形輸入法輸入正確答案之\"選項\",大小寫/阿拉伯數字需要一模一樣範例A142X384" #captcha_text_div_text = "請將以下【歌曲】已發行日期由「新到舊」依序排列 【H1】 After LIKE 【22】 I AM 【R3】 ELEVEN 【74】LOVE DIVE 請以半形輸入法輸入正確答案之\"選項\",大小寫/阿拉伯數字需要一模一樣範例A142X384"
#captcha_text_div_text = "請將以下【歌曲】已發行日期由「新到舊」依序排列 【H】 After LIKE 【2】 I AM 【R】 ELEVEN 【7】LOVE DIVE 請以半形輸入法輸入正確答案之\"選項\",大小寫/阿拉伯數字需要一模一樣範例A4X8" #captcha_text_div_text = "請將以下【歌曲】已發行日期由「新到舊」依序排列 【H】 After LIKE 【2】 I AM 【R】 ELEVEN 【7】LOVE DIVE 請以半形輸入法輸入正確答案之\"選項\",大小寫/阿拉伯數字需要一模一樣範例A4X8"
captcha_text_div_text = "1. 以下哪個為正確的OffGun粉絲名稱請以半形數字及細楷英文字母於下方輸入答案\n3fBaby\n6rBabii\n9eBabe" #captcha_text_div_text = "1. 以下哪個為正確的OffGun粉絲名稱請以半形數字及細楷英文字母於下方輸入答案\n3fBaby\n6rBabii\n9eBabe"
#captcha_text_div_text = "2. 以下那齣並不是OffGun有份演出的劇集請以半形數字及細楷英文字母於下方輸入答案\n2m《我的貓貓男友》\n4v《愛情理論》\n6k《Not Me》" #captcha_text_div_text = "2. 以下那齣並不是OffGun有份演出的劇集請以半形數字及細楷英文字母於下方輸入答案\n2m《我的貓貓男友》\n4v《愛情理論》\n6k《Not Me》"
#captcha_text_div_text = "2. 以下那齣並不是OffGun有份演出的劇集請以半形數字及細楷英文字母於下方輸入答案\n2m:《我的貓貓男友》\n4v:《愛情理論》\n6k:《Not Me》" #captcha_text_div_text = "2. 以下那齣並不是OffGun有份演出的劇集請以半形數字及細楷英文字母於下方輸入答案\n2m:《我的貓貓男友》\n4v:《愛情理論》\n6k:《Not Me》"
inferred_answer_string, answer_list = get_answer_list_from_question_string(None, captcha_text_div_text) answer_list = get_answer_list_from_question_string(None, captcha_text_div_text)
print("inferred_answer_string:", inferred_answer_string)
print("answer_list:", answer_list) print("answer_list:", answer_list)
ocr = ddddocr.DdddOcr(show_ad=False, beta=True) ocr = ddddocr.DdddOcr(show_ad=False, beta=True)
@ -10732,10 +10626,11 @@ if __name__ == "__main__":
print(res) print(res)
# for urbtix survey. # for urbtix survey.
# PS: urttix use "open-end" qustion, must use external database to answer...
question_text = "「6- -V- -U - n--s- -z - j」由右起第三個數字/字母是甚麼?" question_text = "「6- -V- -U - n--s- -z - j」由右起第三個數字/字母是甚麼?"
question_text = "「6---2 - 3 _ 8- -8 _ 4 - 1--4 _ 7」中有多少個「二」?" question_text = "「6---2 - 3 _ 8- -8 _ 4 - 1--4 _ 7」中有多少個「二」?"
question_answer_char, question_direction = get_urbtix_survey_answer_by_question(question_text) question_answer_char, question_direction = get_urbtix_survey_answer_by_question(question_text)
print("question_text:", question_text) #print("question_text:", question_text)
print("question_answer_char:", question_answer_char) #print("question_answer_char:", question_answer_char)
print("question_text:", question_direction) #print("question_text:", question_direction)

View File

@ -22,7 +22,7 @@ import base64
import threading import threading
import subprocess import subprocess
CONST_APP_VERSION = "MaxBot (2023.6.17)" CONST_APP_VERSION = "MaxBot (2023.6.18)"
CONST_MAXBOT_LAUNCHER_FILE = "config_launcher.json" CONST_MAXBOT_LAUNCHER_FILE = "config_launcher.json"
CONST_MAXBOT_CONFIG_FILE = "settings.json" CONST_MAXBOT_CONFIG_FILE = "settings.json"

View File

@ -1 +1 @@
{"homepage": "https://tixcraft.com", "browser": "chrome", "language": "\u7e41\u9ad4\u4e2d\u6587", "ticket_number": 2, "pass_1_seat_remaining": true, "auto_check_agree": true, "ocr_captcha": {"enable": true, "force_submit": true, "image_source": "canvas"}, "webdriver_type": "undetected_chromedriver", "kktix": {"auto_press_next_step_button": true, "auto_fill_ticket_number": true}, "tixcraft": {"date_auto_select": {"enable": true, "date_keyword": "", "mode": "from top to bottom"}, "pass_date_is_sold_out": true, "auto_reload_coming_soon_page": true}, "area_auto_select": {"enable": true, "mode": "from top to bottom", "area_keyword": "", "area_keyword_exclude": "\"\u8f2a\u6905\",\"\u8eab\u969c\",\"\u8eab\u5fc3 \u969c\u7919\""}, "advanced": {"play_captcha_sound": {"enable": true, "filename": "ding-dong.wav"}, "tixcraft_sid": "", "ibonqware": "", "facebook_account": "", "kktix_account": "", "cityline_account": "", "urbtix_account": "", "hkticketing_account": "", "kham_account": "", "facebook_password": "", "kktix_password": "", "cityline_password": "", "urbtix_password": "", "hkticketing_password": "", "kham_password": "", "adblock_plus_enable": false, "disable_adjacent_seat": false, "headless": false, "verbose": false, "auto_guess_options": false, "user_guess_string": "", "online_dictionary_url": "", "auto_reload_page_interval": 1.5, "auto_reload_random_delay": false}} {"homepage": "https://tixcraft.com", "browser": "chrome", "language": "\u7e41\u9ad4\u4e2d\u6587", "ticket_number": 2, "pass_1_seat_remaining": true, "auto_check_agree": true, "ocr_captcha": {"enable": true, "force_submit": true, "image_source": "canvas"}, "webdriver_type": "undetected_chromedriver", "kktix": {"auto_press_next_step_button": true, "auto_fill_ticket_number": true}, "tixcraft": {"date_auto_select": {"enable": true, "date_keyword": "", "mode": "from top to bottom"}, "pass_date_is_sold_out": true, "auto_reload_coming_soon_page": true}, "area_auto_select": {"enable": true, "mode": "from top to bottom", "area_keyword": "", "area_keyword_exclude": "\"\u8f2a\u6905\",\"\u8eab\u969c\",\"\u8eab\u5fc3 \u969c\u7919\""}, "advanced": {"play_captcha_sound": {"enable": true, "filename": "ding-dong.wav"}, "tixcraft_sid": "", "ibonqware": "", "facebook_account": "", "kktix_account": "", "cityline_account": "", "urbtix_account": "", "hkticketing_account": "", "kham_account": "", "facebook_password": "", "kktix_password": "", "cityline_password": "", "urbtix_password": "", "hkticketing_password": "", "kham_password": "", "adblock_plus_enable": false, "disable_adjacent_seat": false, "headless": false, "verbose": false, "auto_guess_options": true, "user_guess_string": "", "online_dictionary_url": "", "auto_reload_page_interval": 1.5, "auto_reload_random_delay": false}}

View File

@ -32,7 +32,7 @@ warnings.simplefilter('ignore',InsecureRequestWarning)
import ssl import ssl
ssl._create_default_https_context = ssl._create_unverified_context ssl._create_default_https_context = ssl._create_unverified_context
CONST_APP_VERSION = "MaxBot (2023.6.17)" CONST_APP_VERSION = "MaxBot (2023.6.18)"
CONST_MAXBOT_CONFIG_FILE = "settings.json" CONST_MAXBOT_CONFIG_FILE = "settings.json"
CONST_MAXBOT_LAST_URL_FILE = "MAXBOT_LAST_URL.txt" CONST_MAXBOT_LAST_URL_FILE = "MAXBOT_LAST_URL.txt"
@ -118,8 +118,8 @@ def load_translate():
en_us["date_keyword"] = 'Date Keyword' en_us["date_keyword"] = 'Date Keyword'
en_us["pass_date_is_sold_out"] = 'Pass date is sold out' en_us["pass_date_is_sold_out"] = 'Pass date is sold out'
en_us["auto_reload_coming_soon_page"] = 'Reload coming soon page' en_us["auto_reload_coming_soon_page"] = 'Reload coming soon page'
en_us["auto_reload_page_interval"] = 'Reload page interval (sec.)' en_us["auto_reload_page_interval"] = 'Reload page interval sec.(HK)'
en_us["auto_reload_random_delay"] = 'Reload with random delay' en_us["auto_reload_random_delay"] = 'Reload with random delay(TW)'
en_us["area_select_order"] = 'Area select order' en_us["area_select_order"] = 'Area select order'
en_us["area_keyword"] = 'Area Keyword' en_us["area_keyword"] = 'Area Keyword'
@ -209,8 +209,8 @@ def load_translate():
zh_tw["date_keyword"] = '日期關鍵字' zh_tw["date_keyword"] = '日期關鍵字'
zh_tw["pass_date_is_sold_out"] = '避開「搶購一空」的日期' zh_tw["pass_date_is_sold_out"] = '避開「搶購一空」的日期'
zh_tw["auto_reload_coming_soon_page"] = '自動刷新倒數中的日期頁面' zh_tw["auto_reload_coming_soon_page"] = '自動刷新倒數中的日期頁面'
zh_tw["auto_reload_page_interval"] = '自動刷新頁面間隔(秒)' zh_tw["auto_reload_page_interval"] = '自動刷新頁面間隔(秒)(香港)'
zh_tw["auto_reload_random_delay"] = '自動刷新時隨機延遲' zh_tw["auto_reload_random_delay"] = '自動刷新時隨機延遲(台灣)'
zh_tw["area_select_order"] = '區域排序方式' zh_tw["area_select_order"] = '區域排序方式'
zh_tw["area_keyword"] = '區域關鍵字' zh_tw["area_keyword"] = '區域關鍵字'
@ -299,8 +299,8 @@ def load_translate():
zh_cn["date_keyword"] = '日期关键字' zh_cn["date_keyword"] = '日期关键字'
zh_cn["pass_date_is_sold_out"] = '避开“抢购一空”的日期' zh_cn["pass_date_is_sold_out"] = '避开“抢购一空”的日期'
zh_cn["auto_reload_coming_soon_page"] = '自动刷新倒数中的日期页面' zh_cn["auto_reload_coming_soon_page"] = '自动刷新倒数中的日期页面'
zh_cn["auto_reload_page_interval"] = '重新加载页面间隔(秒)' zh_cn["auto_reload_page_interval"] = '重新加载页面间隔(秒)(香港)'
zh_cn["auto_reload_random_delay"] = '重新加载时随机延迟' zh_cn["auto_reload_random_delay"] = '重新加载时随机延迟(台灣)'
zh_cn["area_select_order"] = '区域排序方式' zh_cn["area_select_order"] = '区域排序方式'
zh_cn["area_keyword"] = '区域关键字' zh_cn["area_keyword"] = '区域关键字'
@ -390,8 +390,8 @@ def load_translate():
ja_jp["date_keyword"] = '日付キーワード' ja_jp["date_keyword"] = '日付キーワード'
ja_jp["pass_date_is_sold_out"] = '「売り切れ」公演を避ける' ja_jp["pass_date_is_sold_out"] = '「売り切れ」公演を避ける'
ja_jp["auto_reload_coming_soon_page"] = '公開予定のページをリロード' ja_jp["auto_reload_coming_soon_page"] = '公開予定のページをリロード'
ja_jp["auto_reload_page_interval"] = 'ページのリロード間隔 (秒)' ja_jp["auto_reload_page_interval"] = 'ページのリロード間隔 (秒)(香港)'
ja_jp["auto_reload_random_delay"] = 'リロード時のランダムな遅延' ja_jp["auto_reload_random_delay"] = 'リロード時のランダムな遅延(台灣)'
ja_jp["area_select_order"] = 'エリアソート方法' ja_jp["area_select_order"] = 'エリアソート方法'
ja_jp["area_keyword"] = 'エリアキーワード' ja_jp["area_keyword"] = 'エリアキーワード'
@ -580,7 +580,7 @@ def get_default_config():
config_dict["advanced"]["disable_adjacent_seat"] = False config_dict["advanced"]["disable_adjacent_seat"] = False
config_dict["advanced"]["headless"] = False config_dict["advanced"]["headless"] = False
config_dict["advanced"]["verbose"] = False config_dict["advanced"]["verbose"] = False
config_dict["advanced"]["auto_guess_options"] = False config_dict["advanced"]["auto_guess_options"] = True
config_dict["advanced"]["user_guess_string"] = "" config_dict["advanced"]["user_guess_string"] = ""
config_dict["advanced"]["online_dictionary_url"] = "" config_dict["advanced"]["online_dictionary_url"] = ""

View File

@ -27,7 +27,7 @@ import asyncio
import tornado import tornado
from tornado.web import Application from tornado.web import Application
CONST_APP_VERSION = "MaxBot (2023.6.17)" CONST_APP_VERSION = "MaxBot (2023.6.18)"
CONST_MAXBOT_QUESTION_FILE = "MAXBOT_QUESTION.txt" CONST_MAXBOT_QUESTION_FILE = "MAXBOT_QUESTION.txt"