From 2b9b4682e0304ec1d6fe991430474568e346c611 Mon Sep 17 00:00:00 2001 From: Merg1n Date: Fri, 17 Apr 2020 19:08:10 +0800 Subject: [PATCH 1/4] implements changing yggdrasil server and fixes a bug in pyCraft --- utils/config.py | 3 ++ utils/pycraft/authentication.py | 64 ++++++++++++++++++++++++--------- utils/recorder.py | 7 +++- 3 files changed, 56 insertions(+), 18 deletions(-) diff --git a/utils/config.py b/utils/config.py index 6377cff..5cc5f69 100644 --- a/utils/config.py +++ b/utils/config.py @@ -9,6 +9,7 @@ "__2__": "-------- Account and Server --------", "online_mode": false, + "yggdrasil_server": "", "username": "bot_PCRC", "password": "secret", "address": "localhost", @@ -46,6 +47,7 @@ SettableOptions = [ 'language', + 'yggdrasil_server', 'server_name', 'minimal_packets', 'daytime', @@ -117,6 +119,7 @@ def secret(text): messages.append(f"Debug mode = {self.get('debug_mode')}") messages.append('-------- Account and Server --------') messages.append(f"Online mode = {self.get('online_mode')}") + messages.append(f"Yggdrasil server = {self.get('yggdrasil_server')}") messages.append(f"User name = {secret(self.get('username'))}") messages.append(f"Password = ******") messages.append(f"Server address = {self.get('address')}") diff --git a/utils/pycraft/authentication.py b/utils/pycraft/authentication.py index e78e875..826acd8 100644 --- a/utils/pycraft/authentication.py +++ b/utils/pycraft/authentication.py @@ -11,6 +11,34 @@ HEADERS = {"content-type": CONTENT_TYPE} +class YggdrasilServer(object): + def __init__(self, url): + if not url == None: + self.url = _get_yggdrasil_url(url) + + def request_auth_server(self, endpoint, data): + return _make_request(self.url + "/authserver", endpoint, data) + + def request_session_server(self, endpoint, data): + return _make_request(self.url + "/sessionserver/session/minecraft", endpoint, data) + + +def _get_yggdrasil_url(url): + # TODO impl ALI + return url + + +class MojangServer(YggdrasilServer): + def __init__(self): + super().__init__(None) + + def request_auth_server(self, endpoint, data): + return _make_request(AUTH_SERVER, endpoint, data) + + def request_session_server(self, endpoint, data): + return _make_request(SESSION_SERVER, endpoint, data) + + class Profile(object): """ Container class for a MineCraft Selected profile. @@ -48,7 +76,7 @@ class AuthenticationToken(object): AGENT_NAME = "Minecraft" AGENT_VERSION = 1 - def __init__(self, username=None, access_token=None, client_token=None): + def __init__(self, username=None, access_token=None, client_token=None, yggdrasil_server=MojangServer()): """ Constructs an `AuthenticationToken` based on `access_token` and `client_token`. @@ -63,6 +91,7 @@ def __init__(self, username=None, access_token=None, client_token=None): self.username = username self.access_token = access_token self.client_token = client_token + self.yggdrasil_server = yggdrasil_server self.profile = Profile() @property @@ -119,7 +148,8 @@ def authenticate(self, username, password, invalidate_previous=False): # is `None` generate a `client_token` using uuid4 payload["clientToken"] = self.client_token or uuid.uuid4().hex - res = _make_request(AUTH_SERVER, "authenticate", payload) + res = self.yggdrasil_server.request_auth_server( + "authenticate", payload) _raise_from_response(res) @@ -154,9 +184,9 @@ def refresh(self): if self.client_token is None: raise ValueError("'client_token' is not set!") - res = _make_request(AUTH_SERVER, - "refresh", {"accessToken": self.access_token, - "clientToken": self.client_token}) + res = self.yggdrasil_server.request_auth_server("refresh", + {"accessToken": self.access_token, + "clientToken": self.client_token}) _raise_from_response(res) @@ -186,8 +216,8 @@ def validate(self): if self.access_token is None: raise ValueError("'access_token' not set!") - res = _make_request(AUTH_SERVER, "validate", - {"accessToken": self.access_token}) + res = self.yggdrasil_server.request_auth_server("validate", + {"accessToken": self.access_token}) # Validate returns 204 to indicate success # http://wiki.vg/Authentication#Response_3 @@ -195,7 +225,7 @@ def validate(self): return True @staticmethod - def sign_out(username, password): + def sign_out(username, password, yggdrasil_server=MojangServer()): """ Invalidates `access_token`s using an account's `username` and `password`. @@ -211,8 +241,8 @@ def sign_out(username, password): Raises: pycraft.exceptions.YggdrasilError """ - res = _make_request(AUTH_SERVER, "signout", - {"username": username, "password": password}) + res = yggdrasil_server.request_auth_server("signout", + {"username": username, "password": password}) if _raise_from_response(res) is None: return True @@ -228,9 +258,9 @@ def invalidate(self): Raises: :class:`pycraft.exceptions.YggdrasilError` """ - res = _make_request(AUTH_SERVER, "invalidate", - {"accessToken": self.access_token, - "clientToken": self.client_token}) + res = self.yggdrasil_server.request_auth_server("invalidate", + {"accessToken": self.access_token, + "clientToken": self.client_token}) if res.status_code != 204: _raise_from_response(res) @@ -255,10 +285,10 @@ def join(self, server_id): err = "AuthenticationToken hasn't been authenticated yet!" raise YggdrasilError(err) - res = _make_request(SESSION_SERVER, "join", - {"accessToken": self.access_token, - "selectedProfile": self.profile.to_dict(), - "serverId": server_id}) + res = self.yggdrasil_server.request_session_server("join", + {"accessToken": self.access_token, + "selectedProfile": self.profile.id_, #this is a hidden bug in pyCraft + "serverId": server_id}) if res.status_code != 204: _raise_from_response(res) diff --git a/utils/recorder.py b/utils/recorder.py index 84de81f..ae70158 100644 --- a/utils/recorder.py +++ b/utils/recorder.py @@ -51,7 +51,12 @@ def __init__(self, config_file, translation_folder): ) else: self.logger.log("Login in online mode") - auth_token = authentication.AuthenticationToken() + yggdrasil_server = self.config.get('yggdrasil_server') + if yggdrasil_server == "": + yggdrasil_server = authentication.MojangServer() + else: + yggdrasil_server = authentication.YggdrasilServer(yggdrasil_server) + auth_token = authentication.AuthenticationToken(yggdrasil_server = yggdrasil_server) auth_token.authenticate(self.config.get('username'), self.config.get('password')) self.logger.log("Logged in as %s" % auth_token.profile.name) self.config.set_value('username', auth_token.profile.name) From 72db1556bc94aa935cb600136d2f7935125f236d Mon Sep 17 00:00:00 2001 From: Sciroccogti Date: Thu, 30 Apr 2020 11:59:19 +0800 Subject: [PATCH 2/4] display all parts of skin --- utils/recorder.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/utils/recorder.py b/utils/recorder.py index 9e0ec0f..46ad027 100644 --- a/utils/recorder.py +++ b/utils/recorder.py @@ -115,6 +115,14 @@ def onGameJoin(self, packet): self.logger.log('PCRC bot joined the server') self.online = True self.chat(self.translation('OnGameJoin')) + client_settings = serverbound.play.ClientSettingsPacket() + client_settings.locale = "en_US" + client_settings.view_distance = 16 + client_settings.chat_mode = client_settings.ChatMode.FULL + client_settings.chat_colors = False + client_settings.displayed_skin_parts = client_settings.SkinParts.ALL + client_settings.main_hand = client_settings.Hand.RIGHT + self.connection.write_packet(client_settings) def onDisconnect(self, packet): self.logger.log('PCRC disconnected from the server, reason = {}'.format(packet.json_data)) From a19d3bb3d47a2acc5b4df670a166cdf83a9184dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A0=E9=A3=8E=E5=BC=95=E6=BC=A9?= Date: Sat, 5 Dec 2020 22:40:28 +0800 Subject: [PATCH 3/4] add client_settings into conf --- config.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/config.json b/config.json index 8e70ef4..99567d8 100644 --- a/config.json +++ b/config.json @@ -30,6 +30,9 @@ "remove_items": true, "remove_bats": true, "remove_phantoms": true, + "view_distance": 16, + "chat_colors": false, + "right_main_hand": true, "__5__": "-------- PCRC Whitelist --------", "enabled": false, @@ -37,4 +40,4 @@ "Fallen_Breath", "Steve" ] -} \ No newline at end of file +} From f31c47130192ae04f7409b95bdae033b13050dd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=97=A0=E9=A3=8E=E5=BC=95=E6=BC=A9?= Date: Sat, 5 Dec 2020 22:40:46 +0800 Subject: [PATCH 4/4] read client_settings from conf --- utils/recorder.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/utils/recorder.py b/utils/recorder.py index f0ff10a..56e30a2 100644 --- a/utils/recorder.py +++ b/utils/recorder.py @@ -119,12 +119,15 @@ def onGameJoin(self, packet): self.online = True self.chat(self.translation('OnGameJoin')) client_settings = serverbound.play.ClientSettingsPacket() - client_settings.locale = "en_US" - client_settings.view_distance = 16 + client_settings.locale = self.config.get('language') + client_settings.view_distance = self.config.get('view_distance') client_settings.chat_mode = client_settings.ChatMode.FULL - client_settings.chat_colors = False + client_settings.chat_colors = self.config.get('chat_colors') client_settings.displayed_skin_parts = client_settings.SkinParts.ALL - client_settings.main_hand = client_settings.Hand.RIGHT + if self.config.get('right_main_hand'): + client_settings.main_hand = client_settings.Hand.RIGHT + else: + client_settings.main_hand = client_settings.Hand.LEFT self.connection.write_packet(client_settings) def onDisconnect(self, packet):