Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support authlib-injector and display all part of skin #8

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,14 @@
"remove_items": true,
"remove_bats": true,
"remove_phantoms": true,
"view_distance": 16,
"chat_colors": false,
"right_main_hand": true,

"__5__": "-------- PCRC Whitelist --------",
"enabled": false,
"whitelist": [
"Fallen_Breath",
"Steve"
]
}
}
3 changes: 3 additions & 0 deletions utils/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

"__2__": "-------- Account and Server --------",
"online_mode": false,
"yggdrasil_server": "",
"username": "bot_PCRC",
"password": "secret",
"address": "localhost",
Expand Down Expand Up @@ -46,6 +47,7 @@

SettableOptions = [
'language',
'yggdrasil_server',
'server_name',
'minimal_packets',
'daytime',
Expand Down Expand Up @@ -120,6 +122,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')}")
Expand Down
64 changes: 47 additions & 17 deletions utils/pycraft/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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`.
Expand All @@ -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
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -186,16 +216,16 @@ 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
if res.status_code == 204:
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`.
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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)
Expand Down
18 changes: 17 additions & 1 deletion utils/recorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,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)
Expand Down Expand Up @@ -113,6 +118,17 @@ 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 = 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 = self.config.get('chat_colors')
client_settings.displayed_skin_parts = client_settings.SkinParts.ALL
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):
self.logger.log('PCRC disconnected from the server, reason = {}'.format(packet.json_data))
Expand Down