commit
e1aa021896
@ -0,0 +1 @@ |
|||||||
|
config.json |
@ -0,0 +1,16 @@ |
|||||||
|
[[source]] |
||||||
|
url = "https://pypi.org/simple" |
||||||
|
verify_ssl = true |
||||||
|
name = "pypi" |
||||||
|
|
||||||
|
[dev-packages] |
||||||
|
|
||||||
|
[packages] |
||||||
|
pycraft = {git = "https://github.com/ammaraskar/pyCraft.git"} |
||||||
|
minecraft = {git = "https://github.com/ammaraskar/pyCraft.git"} |
||||||
|
requests = "*" |
||||||
|
cryptography = "*" |
||||||
|
future = "*" |
||||||
|
|
||||||
|
[requires] |
||||||
|
python_version = "3.6" |
@ -0,0 +1,157 @@ |
|||||||
|
{ |
||||||
|
"_meta": { |
||||||
|
"hash": { |
||||||
|
"sha256": "c36c9f342620f87cb95fb3b03c8315938b7170acf71d107c43e1840d5dd70aa7" |
||||||
|
}, |
||||||
|
"pipfile-spec": 6, |
||||||
|
"requires": { |
||||||
|
"python_version": "3.6" |
||||||
|
}, |
||||||
|
"sources": [ |
||||||
|
{ |
||||||
|
"name": "pypi", |
||||||
|
"url": "https://pypi.org/simple", |
||||||
|
"verify_ssl": true |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"default": { |
||||||
|
"asn1crypto": { |
||||||
|
"hashes": [ |
||||||
|
"sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87", |
||||||
|
"sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49" |
||||||
|
], |
||||||
|
"version": "==0.24.0" |
||||||
|
}, |
||||||
|
"certifi": { |
||||||
|
"hashes": [ |
||||||
|
"sha256:376690d6f16d32f9d1fe8932551d80b23e9d393a8578c5633a2ed39a64861638", |
||||||
|
"sha256:456048c7e371c089d0a77a5212fb37a2c2dce1e24146e3b7e0261736aaeaa22a" |
||||||
|
], |
||||||
|
"version": "==2018.8.24" |
||||||
|
}, |
||||||
|
"cffi": { |
||||||
|
"hashes": [ |
||||||
|
"sha256:151b7eefd035c56b2b2e1eb9963c90c6302dc15fbd8c1c0a83a163ff2c7d7743", |
||||||
|
"sha256:1553d1e99f035ace1c0544050622b7bc963374a00c467edafac50ad7bd276aef", |
||||||
|
"sha256:1b0493c091a1898f1136e3f4f991a784437fac3673780ff9de3bcf46c80b6b50", |
||||||
|
"sha256:2ba8a45822b7aee805ab49abfe7eec16b90587f7f26df20c71dd89e45a97076f", |
||||||
|
"sha256:3bb6bd7266598f318063e584378b8e27c67de998a43362e8fce664c54ee52d30", |
||||||
|
"sha256:3c85641778460581c42924384f5e68076d724ceac0f267d66c757f7535069c93", |
||||||
|
"sha256:3eb6434197633b7748cea30bf0ba9f66727cdce45117a712b29a443943733257", |
||||||
|
"sha256:495c5c2d43bf6cebe0178eb3e88f9c4aa48d8934aa6e3cddb865c058da76756b", |
||||||
|
"sha256:4c91af6e967c2015729d3e69c2e51d92f9898c330d6a851bf8f121236f3defd3", |
||||||
|
"sha256:57b2533356cb2d8fac1555815929f7f5f14d68ac77b085d2326b571310f34f6e", |
||||||
|
"sha256:770f3782b31f50b68627e22f91cb182c48c47c02eb405fd689472aa7b7aa16dc", |
||||||
|
"sha256:79f9b6f7c46ae1f8ded75f68cf8ad50e5729ed4d590c74840471fc2823457d04", |
||||||
|
"sha256:7a33145e04d44ce95bcd71e522b478d282ad0eafaf34fe1ec5bbd73e662f22b6", |
||||||
|
"sha256:857959354ae3a6fa3da6651b966d13b0a8bed6bbc87a0de7b38a549db1d2a359", |
||||||
|
"sha256:87f37fe5130574ff76c17cab61e7d2538a16f843bb7bca8ebbc4b12de3078596", |
||||||
|
"sha256:95d5251e4b5ca00061f9d9f3d6fe537247e145a8524ae9fd30a2f8fbce993b5b", |
||||||
|
"sha256:9d1d3e63a4afdc29bd76ce6aa9d58c771cd1599fbba8cf5057e7860b203710dd", |
||||||
|
"sha256:a36c5c154f9d42ec176e6e620cb0dd275744aa1d804786a71ac37dc3661a5e95", |
||||||
|
"sha256:a6a5cb8809091ec9ac03edde9304b3ad82ad4466333432b16d78ef40e0cce0d5", |
||||||
|
"sha256:ae5e35a2c189d397b91034642cb0eab0e346f776ec2eb44a49a459e6615d6e2e", |
||||||
|
"sha256:b0f7d4a3df8f06cf49f9f121bead236e328074de6449866515cea4907bbc63d6", |
||||||
|
"sha256:b75110fb114fa366b29a027d0c9be3709579602ae111ff61674d28c93606acca", |
||||||
|
"sha256:ba5e697569f84b13640c9e193170e89c13c6244c24400fc57e88724ef610cd31", |
||||||
|
"sha256:be2a9b390f77fd7676d80bc3cdc4f8edb940d8c198ed2d8c0be1319018c778e1", |
||||||
|
"sha256:ca1bd81f40adc59011f58159e4aa6445fc585a32bb8ac9badf7a2c1aa23822f2", |
||||||
|
"sha256:d5d8555d9bfc3f02385c1c37e9f998e2011f0db4f90e250e5bc0c0a85a813085", |
||||||
|
"sha256:e55e22ac0a30023426564b1059b035973ec82186ddddbac867078435801c7801", |
||||||
|
"sha256:e90f17980e6ab0f3c2f3730e56d1fe9bcba1891eeea58966e89d352492cc74f4", |
||||||
|
"sha256:ecbb7b01409e9b782df5ded849c178a0aa7c906cf8c5a67368047daab282b184", |
||||||
|
"sha256:ed01918d545a38998bfa5902c7c00e0fee90e957ce036a4000a88e3fe2264917", |
||||||
|
"sha256:edabd457cd23a02965166026fd9bfd196f4324fe6032e866d0f3bd0301cd486f", |
||||||
|
"sha256:fdf1c1dc5bafc32bc5d08b054f94d659422b05aba244d6be4ddc1c72d9aa70fb" |
||||||
|
], |
||||||
|
"markers": "python_version != '3.1.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.0.*' and python_version >= '2.7'", |
||||||
|
"version": "==1.11.5" |
||||||
|
}, |
||||||
|
"chardet": { |
||||||
|
"hashes": [ |
||||||
|
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", |
||||||
|
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" |
||||||
|
], |
||||||
|
"version": "==3.0.4" |
||||||
|
}, |
||||||
|
"cryptography": { |
||||||
|
"hashes": [ |
||||||
|
"sha256:02602e1672b62e803e08617ec286041cc453e8d43f093a5f4162095506bc0beb", |
||||||
|
"sha256:10b48e848e1edb93c1d3b797c83c72b4c387ab0eb4330aaa26da8049a6cbede0", |
||||||
|
"sha256:17db09db9d7c5de130023657be42689d1a5f60502a14f6f745f6f65a6b8195c0", |
||||||
|
"sha256:227da3a896df1106b1a69b1e319dce218fa04395e8cc78be7e31ca94c21254bc", |
||||||
|
"sha256:2cbaa03ac677db6c821dac3f4cdfd1461a32d0615847eedbb0df54bb7802e1f7", |
||||||
|
"sha256:31db8febfc768e4b4bd826750a70c79c99ea423f4697d1dab764eb9f9f849519", |
||||||
|
"sha256:4a510d268e55e2e067715d728e4ca6cd26a8e9f1f3d174faf88e6f2cb6b6c395", |
||||||
|
"sha256:6a88d9004310a198c474d8a822ee96a6dd6c01efe66facdf17cb692512ae5bc0", |
||||||
|
"sha256:76936ec70a9b72eb8c58314c38c55a0336a2b36de0c7ee8fb874a4547cadbd39", |
||||||
|
"sha256:7e3b4aecc4040928efa8a7cdaf074e868af32c58ffc9bb77e7bf2c1a16783286", |
||||||
|
"sha256:8168bcb08403ef144ff1fb880d416f49e2728101d02aaadfe9645883222c0aa5", |
||||||
|
"sha256:8229ceb79a1792823d87779959184a1bf95768e9248c93ae9f97c7a2f60376a1", |
||||||
|
"sha256:8a19e9f2fe69f6a44a5c156968d9fc8df56d09798d0c6a34ccc373bb186cee86", |
||||||
|
"sha256:8d10113ca826a4c29d5b85b2c4e045ffa8bad74fb525ee0eceb1d38d4c70dfd6", |
||||||
|
"sha256:be495b8ec5a939a7605274b6e59fbc35e76f5ad814ae010eb679529671c9e119", |
||||||
|
"sha256:dc2d3f3b1548f4d11786616cf0f4415e25b0fbecb8a1d2cd8c07568f13fdde38", |
||||||
|
"sha256:e4aecdd9d5a3d06c337894c9a6e2961898d3f64fe54ca920a72234a3de0f9cb3", |
||||||
|
"sha256:e79ab4485b99eacb2166f3212218dd858258f374855e1568f728462b0e6ee0d9", |
||||||
|
"sha256:f995d3667301e1754c57b04e0bae6f0fa9d710697a9f8d6712e8cca02550910f" |
||||||
|
], |
||||||
|
"index": "pypi", |
||||||
|
"version": "==2.3.1" |
||||||
|
}, |
||||||
|
"future": { |
||||||
|
"hashes": [ |
||||||
|
"sha256:e39ced1ab767b5936646cedba8bcce582398233d6a627067d4c6a454c90cfedb" |
||||||
|
], |
||||||
|
"index": "pypi", |
||||||
|
"version": "==0.16.0" |
||||||
|
}, |
||||||
|
"idna": { |
||||||
|
"hashes": [ |
||||||
|
"sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e", |
||||||
|
"sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16" |
||||||
|
], |
||||||
|
"version": "==2.7" |
||||||
|
}, |
||||||
|
"minecraft": { |
||||||
|
"git": "https://github.com/ammaraskar/pyCraft.git", |
||||||
|
"ref": "eb302094aa7357141e5f6b9f0cc252204890fbd3" |
||||||
|
}, |
||||||
|
"pycparser": { |
||||||
|
"hashes": [ |
||||||
|
"sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3" |
||||||
|
], |
||||||
|
"markers": "python_version != '3.1.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.0.*' and python_version >= '2.7'", |
||||||
|
"version": "==2.19" |
||||||
|
}, |
||||||
|
"pycraft": { |
||||||
|
"git": "https://github.com/ammaraskar/pyCraft.git", |
||||||
|
"ref": "eb302094aa7357141e5f6b9f0cc252204890fbd3" |
||||||
|
}, |
||||||
|
"requests": { |
||||||
|
"hashes": [ |
||||||
|
"sha256:63b52e3c866428a224f97cab011de738c36aec0185aa91cfacd418b5d58911d1", |
||||||
|
"sha256:ec22d826a36ed72a7358ff3fe56cbd4ba69dd7a6718ffd450ff0e9df7a47ce6a" |
||||||
|
], |
||||||
|
"index": "pypi", |
||||||
|
"version": "==2.19.1" |
||||||
|
}, |
||||||
|
"six": { |
||||||
|
"hashes": [ |
||||||
|
"sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9", |
||||||
|
"sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb" |
||||||
|
], |
||||||
|
"version": "==1.11.0" |
||||||
|
}, |
||||||
|
"urllib3": { |
||||||
|
"hashes": [ |
||||||
|
"sha256:a68ac5e15e76e7e5dd2b8f94007233e01effe3e50e8daddf69acfd81cb686baf", |
||||||
|
"sha256:b5725a0bd4ba422ab0e66e89e030c806576753ea3ee08554382c14e685d117b5" |
||||||
|
], |
||||||
|
"markers": "python_version != '3.0.*' and python_version != '3.1.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version >= '2.6' and python_version < '4'", |
||||||
|
"version": "==1.23" |
||||||
|
} |
||||||
|
}, |
||||||
|
"develop": {} |
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
{ |
||||||
|
"MAIN": { |
||||||
|
"WEBHOOK_URL": "" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,159 @@ |
|||||||
|
#!/usr/bin/env python |
||||||
|
|
||||||
|
from __future__ import print_function |
||||||
|
|
||||||
|
import getpass |
||||||
|
import sys |
||||||
|
import re |
||||||
|
import requests |
||||||
|
import json |
||||||
|
from optparse import OptionParser |
||||||
|
|
||||||
|
from minecraft import authentication |
||||||
|
from minecraft.exceptions import YggdrasilError |
||||||
|
from minecraft.networking.connection import Connection |
||||||
|
from minecraft.networking.packets import Packet, clientbound, serverbound |
||||||
|
from minecraft.compat import input |
||||||
|
|
||||||
|
UUID_CACHE = {} |
||||||
|
|
||||||
|
def get_options(): |
||||||
|
parser = OptionParser() |
||||||
|
|
||||||
|
parser.add_option("-u", "--username", dest="username", default=None, |
||||||
|
help="username to log in with") |
||||||
|
|
||||||
|
parser.add_option("-p", "--password", dest="password", default=None, |
||||||
|
help="password to log in with") |
||||||
|
|
||||||
|
parser.add_option("-s", "--server", dest="server", default=None, |
||||||
|
help="server host or host:port " |
||||||
|
"(enclose IPv6 addresses in square brackets)") |
||||||
|
|
||||||
|
parser.add_option("-o", "--offline", dest="offline", action="store_true", |
||||||
|
help="connect to a server in offline mode " |
||||||
|
"(no password required)") |
||||||
|
|
||||||
|
(options, args) = parser.parse_args() |
||||||
|
|
||||||
|
if not options.username: |
||||||
|
options.username = input("Enter your username: ") |
||||||
|
|
||||||
|
if not options.password and not options.offline: |
||||||
|
options.password = getpass.getpass("Enter your password (leave " |
||||||
|
"blank for offline mode): ") |
||||||
|
options.offline = options.offline or (options.password == "") |
||||||
|
|
||||||
|
if not options.server: |
||||||
|
options.server = input("Enter server host or host:port " |
||||||
|
"(enclose IPv6 addresses in square brackets): ") |
||||||
|
# Try to split out port and address |
||||||
|
match = re.match(r"((?P<host>[^\[\]:]+)|\[(?P<addr>[^\[\]]+)\])" |
||||||
|
r"(:(?P<port>\d+))?$", options.server) |
||||||
|
if match is None: |
||||||
|
raise ValueError("Invalid server address: '%s'." % options.server) |
||||||
|
options.address = match.group("host") or match.group("addr") |
||||||
|
options.port = int(match.group("port") or 25565) |
||||||
|
|
||||||
|
return options |
||||||
|
|
||||||
|
|
||||||
|
def main(): |
||||||
|
options = get_options() |
||||||
|
|
||||||
|
with open('config.json', 'r') as f: |
||||||
|
_config = json.load(f) |
||||||
|
|
||||||
|
WEBHOOK_URL = _config["MAIN"]["WEBHOOK_URL"] |
||||||
|
|
||||||
|
if options.offline: |
||||||
|
print("Connecting in offline mode...") |
||||||
|
connection = Connection( |
||||||
|
options.address, options.port, username=options.username) |
||||||
|
else: |
||||||
|
auth_token = authentication.AuthenticationToken() |
||||||
|
try: |
||||||
|
auth_token.authenticate(options.username, options.password) |
||||||
|
except YggdrasilError as e: |
||||||
|
print(e) |
||||||
|
sys.exit() |
||||||
|
print("Logged in as %s..." % auth_token.username) |
||||||
|
connection = Connection( |
||||||
|
options.address, options.port, auth_token=auth_token) |
||||||
|
|
||||||
|
def handle_join_game(join_game_packet): |
||||||
|
print('Connected.') |
||||||
|
|
||||||
|
connection.register_packet_listener( |
||||||
|
handle_join_game, clientbound.play.JoinGamePacket) |
||||||
|
|
||||||
|
def print_chat(chat_packet): |
||||||
|
|
||||||
|
json_data = json.loads(chat_packet.json_data) |
||||||
|
if "extra" not in json_data: |
||||||
|
return |
||||||
|
chat_string = "" |
||||||
|
for chat_component in json_data["extra"]: |
||||||
|
chat_string += chat_component["text"] |
||||||
|
|
||||||
|
# Handle join/leave |
||||||
|
regexp_match = re.match("^(.*) (joined|left) the game", chat_string, re.M|re.I) |
||||||
|
if regexp_match: |
||||||
|
print("Username: {} Status: {} the game".format(regexp_match.group(1), regexp_match.group(2))) |
||||||
|
username = regexp_match.group(1) |
||||||
|
status = regexp_match.group(2) |
||||||
|
if username not in UUID_CACHE: |
||||||
|
player_uuid = requests.get("https://api.mojang.com/users/profiles/minecraft/{}".format(username)).json()["id"] |
||||||
|
UUID_CACHE[username] = player_uuid |
||||||
|
else: |
||||||
|
player_uuid = UUID_CACHE[username] |
||||||
|
if status == "joined": |
||||||
|
webhook_payload = {'username': username, 'avatar_url': "https://visage.surgeplay.com/face/160/{}".format(player_uuid), |
||||||
|
'content': '', 'embeds': [{'color': 65280, 'title': '**Joined the game**'}]} |
||||||
|
elif status == "left": |
||||||
|
webhook_payload = {'username': username, 'avatar_url': "https://visage.surgeplay.com/face/160/{}".format(player_uuid), |
||||||
|
'content': '', 'embeds': [{'color': 16711680, 'title': '**Left the game**'}]} |
||||||
|
else: |
||||||
|
return |
||||||
|
post = requests.post(WEBHOOK_URL,json=webhook_payload) |
||||||
|
|
||||||
|
|
||||||
|
# Handle chat message |
||||||
|
regexp_match = re.match("<(.*?)> (.*)", chat_string, re.M|re.I) |
||||||
|
if regexp_match: |
||||||
|
username = regexp_match.group(1) |
||||||
|
message = regexp_match.group(2) |
||||||
|
if username not in UUID_CACHE: |
||||||
|
player_uuid = requests.get("https://api.mojang.com/users/profiles/minecraft/{}".format(username)).json()["id"] |
||||||
|
UUID_CACHE[username] = player_uuid |
||||||
|
else: |
||||||
|
player_uuid = UUID_CACHE[username] |
||||||
|
print("Username: {} Message: {}".format(username, message)) |
||||||
|
webhook_payload = {'username': username, 'avatar_url': "https://visage.surgeplay.com/face/160/{}".format(player_uuid), |
||||||
|
'content': '{}'.format(message)} |
||||||
|
post = requests.post(WEBHOOK_URL,json=webhook_payload) |
||||||
|
|
||||||
|
connection.register_packet_listener( |
||||||
|
print_chat, clientbound.play.ChatMessagePacket) |
||||||
|
|
||||||
|
connection.connect() |
||||||
|
|
||||||
|
while True: |
||||||
|
try: |
||||||
|
text = input() |
||||||
|
if text == "/respawn": |
||||||
|
print("respawning...") |
||||||
|
packet = serverbound.play.ClientStatusPacket() |
||||||
|
packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN |
||||||
|
connection.write_packet(packet) |
||||||
|
else: |
||||||
|
packet = serverbound.play.ChatPacket() |
||||||
|
packet.message = text |
||||||
|
connection.write_packet(packet) |
||||||
|
except KeyboardInterrupt: |
||||||
|
print("Bye!") |
||||||
|
sys.exit() |
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__": |
||||||
|
main() |
Loading…
Reference in new issue