__init__.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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. else:
  21. TOONTOWN_LIBRARY_PATH = None
  22. def start_engine(engine_path, gameserver, playcookie, **kwargs):
  23. env = {
  24. 'TTR_GAMESERVER': gameserver,
  25. 'TTR_PLAYCOOKIE': playcookie,
  26. }
  27. if sys.platform == 'darwin':
  28. env['DYLD_LIBRARY_PATH'] = os.path.join(
  29. TOONTOWN_LIBRARY_PATH,
  30. 'Libraries.bundle',
  31. )
  32. env['DYLD_FRAMEWORK_PATH'] = os.path.join(
  33. TOONTOWN_LIBRARY_PATH,
  34. 'Frameworks',
  35. )
  36. return subprocess.Popen(
  37. args=[engine_path],
  38. cwd=os.path.dirname(engine_path),
  39. env=env,
  40. **kwargs,
  41. )
  42. def api_request(url, params=None, validate_ssl_cert=True):
  43. resp = urllib.request.urlopen(
  44. url=url,
  45. data=urllib.parse.urlencode(params).encode('ascii')
  46. if params else None,
  47. context=None if validate_ssl_cert
  48. else ssl._create_unverified_context(),
  49. )
  50. return json.loads(resp.read().decode('ascii'))
  51. class LoginSuccessful:
  52. def __init__(self, playcookie, gameserver):
  53. self.playcookie = playcookie
  54. self.gameserver = gameserver
  55. class LoginDelayed:
  56. def __init__(self, queue_token):
  57. self.queue_token = queue_token
  58. def login(username=None, password=None,
  59. queue_token=None, validate_ssl_cert=True):
  60. if username is not None and queue_token is None:
  61. assert password is not None
  62. req_params = {
  63. 'username': username,
  64. 'password': password,
  65. }
  66. elif username is None and queue_token is not None:
  67. req_params = {
  68. 'queueToken': queue_token,
  69. }
  70. else:
  71. raise Exception('either specify username or queue token')
  72. resp_data = api_request(
  73. url=LOGIN_API_URL,
  74. params=req_params,
  75. validate_ssl_cert=validate_ssl_cert,
  76. )
  77. if resp_data['success'] == 'true':
  78. return LoginSuccessful(
  79. playcookie=resp_data['cookie'],
  80. gameserver=resp_data['gameserver'],
  81. )
  82. elif resp_data['success'] == 'delayed':
  83. return LoginDelayed(
  84. queue_token=resp_data['queueToken'],
  85. )
  86. else:
  87. raise Exception(repr(resp_data))
  88. def launch(engine_path, username, password, validate_ssl_certs=True):
  89. result = login(
  90. username=username,
  91. password=password,
  92. validate_ssl_cert=validate_ssl_certs,
  93. )
  94. if isinstance(result, LoginDelayed):
  95. result = login(
  96. queue_token=result.queue_token,
  97. validate_ssl_cert=validate_ssl_certs,
  98. )
  99. if isinstance(result, LoginSuccessful):
  100. p = start_engine(
  101. engine_path=engine_path,
  102. gameserver=result.gameserver,
  103. playcookie=result.playcookie,
  104. )
  105. p.wait()
  106. else:
  107. raise Exception(repr(result))