__init__.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import json
  2. import os
  3. import subprocess
  4. import sys
  5. import urllib.parse
  6. import urllib.request
  7. """
  8. official api documentation:
  9. https://github.com/ToontownRewritten/api-doc/blob/master/login.md
  10. https://github.com/ToontownRewritten/api-doc/blob/master/invasions.md
  11. """
  12. INVASIONS_API_URL = 'https://www.toontownrewritten.com/api/invasions?format=json'
  13. LOGIN_API_URL = 'https://www.toontownrewritten.com/api/login?format=json'
  14. def start_engine(engine_path, gameserver, playcookie, **kwargs):
  15. env = {
  16. 'TTR_GAMESERVER': gameserver,
  17. 'TTR_PLAYCOOKIE': playcookie,
  18. }
  19. if sys.platform == 'darwin':
  20. toontown_library_path = os.path.join(
  21. os.path.expanduser('~'), 'Library',
  22. 'Application Support', 'Toontown Rewritten',
  23. )
  24. env['DYLD_LIBRARY_PATH'] = os.path.join(
  25. toontown_library_path,
  26. 'Libraries.bundle',
  27. )
  28. env['DYLD_FRAMEWORK_PATH'] = os.path.join(
  29. toontown_library_path,
  30. 'Frameworks',
  31. )
  32. return subprocess.Popen(
  33. args=[engine_path],
  34. cwd=os.path.dirname(engine_path),
  35. env=env,
  36. **kwargs,
  37. )
  38. def api_request(url, params=None):
  39. resp = urllib.request.urlopen(
  40. url=url,
  41. data=urllib.parse.urlencode(params).encode('ascii')
  42. if params else None,
  43. )
  44. return json.loads(resp.read().decode('ascii'))
  45. class LoginSuccessful:
  46. def __init__(self, playcookie, gameserver):
  47. self.playcookie = playcookie
  48. self.gameserver = gameserver
  49. class LoginDelayed:
  50. def __init__(self, queue_token):
  51. self.queue_token = queue_token
  52. def login(username=None, password=None, queue_token=None):
  53. if username is not None and queue_token is None:
  54. assert password is not None
  55. req_params = {
  56. 'username': username,
  57. 'password': password,
  58. }
  59. elif username is None and queue_token is not None:
  60. req_params = {
  61. 'queueToken': queue_token,
  62. }
  63. else:
  64. raise Exception('either specify username or queue token')
  65. resp_data = api_request(
  66. url=LOGIN_API_URL,
  67. params=req_params,
  68. )
  69. if resp_data['success'] == 'true':
  70. return LoginSuccessful(
  71. playcookie=resp_data['cookie'],
  72. gameserver=resp_data['gameserver'],
  73. )
  74. elif resp_data['success'] == 'delayed':
  75. return LoginDelayed(
  76. queue_token=resp_data['queueToken'],
  77. )
  78. else:
  79. raise Exception(repr(resp_data))
  80. def launch(engine_path, username, password):
  81. result = login(
  82. username=username,
  83. password=password,
  84. )
  85. if isinstance(result, LoginDelayed):
  86. result = login(queue_token=result.queue_token)
  87. if isinstance(result, LoginSuccessful):
  88. p = start_engine(
  89. engine_path=engine_path,
  90. gameserver=result.gameserver,
  91. playcookie=result.playcookie,
  92. )
  93. p.wait()
  94. else:
  95. raise Exception(repr(result))