__init__.py 3.3 KB

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