dcss-watch.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #!/usr/bin/env python3
  2. # pacman -S icecat python python-selenium geckodriver
  3. import time
  4. from datetime import datetime
  5. import code
  6. import random
  7. from os import path
  8. from selenium import webdriver
  9. from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
  10. from selenium.webdriver.common.keys import Keys
  11. if path.isfile('/usr/bin/icecat'):
  12. ff_bin_location = '/usr/bin/icecat'
  13. elif path.isfile('/usr/bin/iceweasel'):
  14. ff_bin_location = '/usr/bin/iceweasel'
  15. elif path.isfile('/usr/bin/firefox'):
  16. ff_bin_location = '/usr/bin/firefox'
  17. ff_profile_location = '/home/main/.mozilla/icecat/vtz6h9c6.selenium'
  18. url = "https://crawl.kelbi.org"
  19. lobby_read_delay = 10
  20. interactive_mode = False
  21. ignore_other_spectators = True
  22. def tprint(string):
  23. print("[" + datetime.now().strftime("%Y-%m-%d %H:%M:%S") + "] " + string)
  24. def determine_ff_profile():
  25. print('todo')
  26. # icecat --CreateProfile selenium
  27. # still need to disable all extensions / addons
  28. # to lauch the profile manually do $ icecat -P selenium
  29. def get_server_list():
  30. print('todo')
  31. def setup_webdriver(ff_bin_location, ff_profile_location):
  32. ffbin = FirefoxBinary(ff_bin_location)
  33. ffprofile = webdriver.FirefoxProfile(ff_profile_location)
  34. browser = webdriver.Firefox(ffprofile, firefox_binary=ffbin)
  35. return browser
  36. def connect_to_lobby(browser, url, delay):
  37. browser.get(url)
  38. while True:
  39. time.sleep(delay)
  40. innerHTML = browser.execute_script("return document.body.innerHTML")
  41. if '<tr id="game-' in innerHTML:
  42. return innerHTML
  43. else:
  44. browser.refresh()
  45. def connect_to_game(url, game_dict):
  46. browser.get('about:blank')
  47. tprint("Now watching: {} a {} playing {}".format(game_dict['username'], game_dict['race_class'], game_dict['game_version']))
  48. browser.get(url + '/' + game_dict['href'])
  49. time.sleep(5)
  50. browser.find_element_by_tag_name('body').send_keys(Keys.F12)
  51. def go_fullscreen():
  52. browser.maximize_window()
  53. browser.fullscreen_window()
  54. def save_html_to_file(filename):
  55. html = browser.execute_script("return document.body.innerHTML")
  56. outF = open(filename, "w")
  57. outF.writelines(html)
  58. outF.close()
  59. def check_if_idle():
  60. print('todo')
  61. def check_if_finished():
  62. print('todo')
  63. # the string "Morgue" isnt in during_gameplay.html
  64. # the string "Morgue is in game_completed.html
  65. def parse_html_lobby_table(html):
  66. game_array = []
  67. html_player_table = html.split('<table id="player_list">')[1].split('</tbody>')[0].split('</tr>')[1:][:-1]
  68. for html_player_info in html_player_table:
  69. player_info = {}
  70. for line in html_player_info.splitlines():
  71. if '<tr id="game-' in line:
  72. player_info['id'] = line.split('"')[1]
  73. elif '<td class="username"><a href="#watch-' in line:
  74. player_info['href'] = line.split('"')[3]
  75. player_info['username'] = line.split('>')[2].split('<')[0]
  76. elif '<td class="game_id">' in line:
  77. player_info['game_version'] = line.split('>')[1].split('<')[0]
  78. elif '<td class="xl">' in line:
  79. player_info['xl'] = line.split('>')[1].split('<')[0]
  80. elif '<td class="char">' in line:
  81. player_info['race_class'] = line.split('>')[1].split('<')[0]
  82. #TODO: expand abreviations
  83. elif '<td class="place">' in line:
  84. player_info['place'] = line.split('>')[1].split('<')[0]
  85. elif '<td class="god">' in line:
  86. player_info['god'] = line.split('>')[1].split('<')[0]
  87. elif '<td class="idle_time" data-time="' in line:
  88. player_info['idle_time'] = line.split('"')[3]
  89. elif '<td class="spectator_count">' in line:
  90. player_info['spectator_count'] = line.split('>')[1].split('<')[0]
  91. if not player_info['spectator_count']:
  92. player_info['spectator_count'] = '0'
  93. #TODO: milestone
  94. if int(player_info['idle_time']) == 0:
  95. game_array.append(player_info)
  96. game_array = sorted(game_array, key=lambda k: k['spectator_count'], reverse=True)
  97. if (int(game_array[0]['spectator_count']) == 0) or (ignore_other_spectators):
  98. random.shuffle(game_array)
  99. return game_array
  100. browser = setup_webdriver(ff_bin_location, ff_profile_location)
  101. lobby_html = connect_to_lobby(browser, url, lobby_read_delay)
  102. #code.interact(local=locals())
  103. go_fullscreen()
  104. game_array = parse_html_lobby_table(lobby_html)
  105. current_username = game_array[0]['username']
  106. connect_to_game(url, game_array[0])
  107. game_end_strings = ['The WebSocket connection failed', 'Morgue', 'Character dump']
  108. current_html = browser.execute_script("return document.body.innerHTML")
  109. if interactive_mode:
  110. code.interact(local=locals())
  111. else:
  112. while True:
  113. time.sleep(30)
  114. last_html = current_html
  115. current_html = browser.execute_script("return document.body.innerHTML")
  116. game_array = parse_html_lobby_table(current_html)
  117. for str in game_end_strings:
  118. if str in current_html:
  119. # the game has finished, connect to a different game
  120. tprint("Gamed ended: found string {}".format(str))
  121. current_username = game_array[0]['username']
  122. connect_to_game(url, game_array[0])
  123. for game in game_array:
  124. if game['username'] == current_username:
  125. if int(game['idle_time']) > 0:
  126. tprint("Gamed ended: timeout of {}".format(game['idle_time']))
  127. # the player is idle, connect to a different game
  128. current_username = game_array[0]['username']
  129. connect_to_game(url, game_array[0])
  130. if last_html == current_html:
  131. # the game froze, probably due to network hiccup
  132. tprint("Gamed ended: not html change")
  133. current_username = game_array[0]['username']
  134. connect_to_game(url, game_array[0])