__init__.py 3.5 KB

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