From 34d0154f7a18eb2baa308f999fc9bd0b188bb4db Mon Sep 17 00:00:00 2001 From: Nathan Adams Date: Tue, 2 Sep 2014 17:18:28 +0200 Subject: [PATCH] Removed everything; we're starting from scratch. --- .gitignore | 103 +++++++++++++++++++++++++ cli.py | 44 ----------- mcstatus/__init__.py | 0 minecraft_query/__init__.py | 2 - minecraft_query/query.py | 146 ------------------------------------ 5 files changed, 103 insertions(+), 192 deletions(-) delete mode 100755 cli.py create mode 100644 mcstatus/__init__.py delete mode 100644 minecraft_query/__init__.py delete mode 100644 minecraft_query/query.py diff --git a/.gitignore b/.gitignore index 72eb226..7023855 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,105 @@ +# Created by http://www.gitignore.io + +### Python ### # Byte-compiled / optimized / DLL files +__pycache__/ *.py[cod] + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.cache +nosetests.xml +coverage.xml + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + + +### PyCharm ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm + +## Directory-based project format +.idea/ +/*.iml +# if you remove the above rule, at least ignore user-specific stuff: +# .idea/workspace.xml +# .idea/tasks.xml +# .idea/dictionaries +# and these sensitive or high-churn files: +# .idea/dataSources.ids +# .idea/dataSources.xml +# .idea/sqlDataSources.xml +# .idea/dynamic.xml +# and, if using gradle:: +# .idea/gradle.xml +# .idea/libraries + +## File-based project format +*.ipr +*.iws + +## Additional for IntelliJ +out/ + +# generated by mpeltonen/sbt-idea plugin +.idea_modules/ + +# generated by JIRA plugin +atlassian-ide-plugin.xml + +# generated by Crashlytics plugin (for Android Studio and Intellij) +com_crashlytics_export_strings.xml + + +### SublimeText ### +# workspace files are user-specific +*.sublime-workspace + +# project files should be checked into the repository, unless a significant +# proportion of contributors will probably not be using SublimeText +# *.sublime-project + +#sftp configuration file +sftp-config.json + diff --git a/cli.py b/cli.py deleted file mode 100755 index 71bd605..0000000 --- a/cli.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python - -import socket -import sys -from pprint import pprint -from argparse import ArgumentParser - -from minecraft_query import MinecraftQuery - -def main(): - parser = ArgumentParser(description="Query status of Minecraft multiplayer server", - epilog="Exit status: 0 if the server can be reached, otherwise nonzero." - ) - parser.add_argument("host", help="target hostname") - parser.add_argument("-q", "--quiet", action='store_true', default=False, - help='don\'t print anything, just check if the server is running') - parser.add_argument("-p", "--port", type=int, default=25565, - help='UDP port of server\'s "query" service [25565]') - parser.add_argument("-r", "--retries", type=int, default=3, - help='retry query at most this number of times [3]') - parser.add_argument("-t", "--timeout", type=int, default=10, - help='retry timeout in seconds [10]') - - options = parser.parse_args() - - try: - query = MinecraftQuery(options.host, options.port, - timeout=options.timeout, - retries=options.retries) - server_data = query.get_rules() - except socket.error as e: - if not options.quiet: - print "socket exception caught:", e.message - print "Server is down or unreachable." - sys.exit(1) - - if not options.quiet: - print "Server response data:" - pprint(server_data) - sys.exit(0) - - -if __name__=="__main__": - main() diff --git a/mcstatus/__init__.py b/mcstatus/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/minecraft_query/__init__.py b/minecraft_query/__init__.py deleted file mode 100644 index 3fba862..0000000 --- a/minecraft_query/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# Backwards-compatibility -from query import * \ No newline at end of file diff --git a/minecraft_query/query.py b/minecraft_query/query.py deleted file mode 100644 index 1d75042..0000000 --- a/minecraft_query/query.py +++ /dev/null @@ -1,146 +0,0 @@ -import socket -import struct - -class MinecraftQuery: - MAGIC_PREFIX = '\xFE\xFD' - PACKET_TYPE_CHALLENGE = 9 - PACKET_TYPE_QUERY = 0 - HUMAN_READABLE_NAMES = dict( - game_id = "Game Name", - gametype = "Game Type", - motd = "Message of the Day", - hostname = "Server Address", - hostport = "Server Port", - map = "Main World Name", - maxplayers = "Maximum Players", - numplayers = "Players Online", - players = "List of Players", - plugins = "List of Plugins", - raw_plugins = "Raw Plugin Info", - software = "Server Software", - version = "Game Version", - ) - - def __init__(self, host, port, timeout=10, id=0, retries=2): - self.addr = (host, port) - self.id = id - self.id_packed = struct.pack('>l', id) - self.challenge_packed = struct.pack('>l', 0) - self.retries = 0 - self.max_retries = retries - - self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - self.socket.settimeout(timeout) - - def send_raw(self, data): - self.socket.sendto(self.MAGIC_PREFIX + data, self.addr) - - def send_packet(self, type, data=''): - self.send_raw(struct.pack('>B', type) + self.id_packed + self.challenge_packed + data) - - def read_packet(self): - buff = self.socket.recvfrom(1460)[0] - type = struct.unpack('>B', buff[0])[0] - id = struct.unpack('>l', buff[1:5])[0] - return type, id, buff[5:] - - def handshake(self, bypass_retries=False): - self.send_packet(self.PACKET_TYPE_CHALLENGE) - - try: - type, id, buff = self.read_packet() - except: - if not bypass_retries: - self.retries += 1 - - if self.retries < self.max_retries: - self.handshake(bypass_retries=bypass_retries) - return - else: - raise - - self.challenge = int(buff[:-1]) - self.challenge_packed = struct.pack('>l', self.challenge) - - def get_status(self): - if not hasattr(self, 'challenge'): - self.handshake() - - self.send_packet(self.PACKET_TYPE_QUERY) - - try: - type, id, buff = self.read_packet() - except: - self.handshake() - return self.get_status() - - data = {} - - data['motd'], data['gametype'], data['map'], data['numplayers'], data['maxplayers'], buff = buff.split('\x00', 5) - data['hostport'] = struct.unpack('