9 Commits

Author SHA1 Message Date
Nathan Adams
2ed78fa7d8 Version to 2.2 2017-04-01 17:43:01 +02:00
Dinner Bone
88961d3b46 Merge pull request #43 from adilosa/master
Implement CLI using Click (fixes #36)
Made cli install with pip install
2017-04-01 17:39:58 +02:00
Nathan Adams
6ac2ead3cd Fixed travis config 2017-04-01 08:27:42 -07:00
Dinner Bone
1ac30d15fd Merge pull request #35 from zeroflow/connection
Implicitly close sockets in destructor methods
2017-04-01 17:19:13 +02:00
Dinner Bone
9c4596e807 Merge pull request #34 from winny-/useSetupTools
Use setuptools to enable dependency checking
2017-04-01 17:18:37 +02:00
Dinner Bone
ac92ee3388 Merge pull request #29 from pangeacake/patch-1
Fix to allow ports > 32767
2017-04-01 17:18:29 +02:00
Thomas Arthofer
3ceb1e1135 Implicitly close sockets in destructor methods 2015-05-17 17:08:03 +02:00
Winston Weinert
d0d0d159bb Use setuptools to enable dependency checking
It turns out distutils cannot easily check for installed packages and makes
no effort to install missing packages. Setuptools on the other hand will
gladly do this for use.

This way situations like #33 cannot arise.
2015-05-08 23:22:19 -05:00
PangeaCake
fff9b05389 Fix to allow ports > 32767 2015-01-26 16:15:27 -08:00
9 changed files with 162 additions and 13 deletions

View File

@@ -3,6 +3,6 @@ python:
- 3.3 - 3.3
- 2.7 - 2.7
install: install:
- if [[ $TRAVIS_PYTHON_VERSION == 2* ]]; then pip install -r requirements/python2.txt --use-mirrors; fi - if [[ $TRAVIS_PYTHON_VERSION == 2* ]]; then pip install -r requirements/python2.txt; fi
- if [[ $TRAVIS_PYTHON_VERSION == 3* ]]; then pip install -r requirements/python3.txt --use-mirrors; fi - if [[ $TRAVIS_PYTHON_VERSION == 3* ]]; then pip install -r requirements/python3.txt; fi
script: nosetests script: nosetests

View File

@@ -1,3 +1,9 @@
2.2
* Added new CLI
* Clean up sockets better
* Fixed connecting to ports greater than 32767
* Took a very very long time. :D
2.1 2.1
* Fixed the connections hanging when no data is received * Fixed the connections hanging when no data is received
* Sped up Query requests by caching DNS * Sped up Query requests by caching DNS
@@ -12,4 +18,4 @@
1.0 1.0
* Initial release. * Initial release.

View File

@@ -28,6 +28,44 @@ query = server.query()
print("The server has the following players online: {0}".format(", ".join(query.players.names))) print("The server has the following players online: {0}".format(", ".join(query.players.names)))
``` ```
Command Line Interface
```
$ mcstatus
Usage: mcstatus [OPTIONS] ADDRESS COMMAND [ARGS]...
mcstatus provides an easy way to query Minecraft servers for any
information they can expose. It provides three modes of access: query,
status, and ping.
Examples:
$ mcstatus example.org ping
21.120ms
$ mcstatus example.org:1234 ping
159.903ms
$ mcstatus example.org status
version: v1.8.8 (protocol 47)
description: "A Minecraft Server"
players: 1/20 ['Dinnerbone (61699b2e-d327-4a01-9f1e-0ea8c3f06bc6)']
$ mcstatus example.org query
host: 93.148.216.34:25565
software: v1.8.8 vanilla
plugins: []
motd: "A Minecraft Server"
players: 1/20 ['Dinnerbone (61699b2e-d327-4a01-9f1e-0ea8c3f06bc6)']
Options:
-h, --help Show this message and exit.
Commands:
ping prints server latency
query detailed server information
status basic server information
```
Installation Installation
------------ ------------

View File

@@ -21,7 +21,7 @@ class ServerPinger:
packet.write_varint(0) packet.write_varint(0)
packet.write_varint(self.version) packet.write_varint(self.version)
packet.write_utf(self.host) packet.write_utf(self.host)
packet.write_short(self.port) packet.write_ushort(self.port)
packet.write_varint(1) # Intention to query status packet.write_varint(1) # Intention to query status
self.connection.write_buffer(packet) self.connection.write_buffer(packet)
@@ -143,4 +143,4 @@ class PingResponse:
else: else:
self.favicon = None self.favicon = None
self.latency = None self.latency = None

View File

@@ -149,6 +149,9 @@ class TCPSocketConnection(Connection):
def write(self, data): def write(self, data):
self.socket.send(data) self.socket.send(data)
def __del__(self):
self.socket.close()
class UDPSocketConnection(Connection): class UDPSocketConnection(Connection):
def __init__(self, addr, timeout=3): def __init__(self, addr, timeout=3):
@@ -175,4 +178,7 @@ class UDPSocketConnection(Connection):
def write(self, data): def write(self, data):
if isinstance(data, Connection): if isinstance(data, Connection):
data = bytearray(data.flush()) data = bytearray(data.flush())
self.socket.sendto(data, self.addr) self.socket.sendto(data, self.addr)
def __del__(self):
self.socket.close()

View File

View File

@@ -0,0 +1,94 @@
import click
from .. import MinecraftServer
server = None
@click.group(context_settings=dict(help_option_names=['-h', '--help']))
@click.argument("address")
def cli(address):
"""
mcstatus provides an easy way to query Minecraft servers for
any information they can expose. It provides three modes of
access: query, status, and ping.
Examples:
\b
$ mcstatus example.org ping
21.120ms
\b
$ mcstatus example.org:1234 ping
159.903ms
\b
$ mcstatus example.org status
version: v1.8.8 (protocol 47)
description: "A Minecraft Server"
players: 1/20 ['Dinnerbone (61699b2e-d327-4a01-9f1e-0ea8c3f06bc6)']
\b
$ mcstatus example.org query
host: 93.148.216.34:25565
software: v1.8.8 vanilla
plugins: []
motd: "A Minecraft Server"
players: 1/20 ['Dinnerbone (61699b2e-d327-4a01-9f1e-0ea8c3f06bc6)']
"""
global server
server = MinecraftServer.lookup(address)
@cli.command(short_help="prints server latency")
def ping():
"""
Ping server for latency.
"""
click.echo("{}ms".format(server.ping()))
@cli.command(short_help="basic server information")
def status():
"""
Prints server status. Supported by all Minecraft
servers that are version 1.7 or higher.
"""
response = server.status()
click.echo("version: v{} (protocol {})".format(response.version.name, response.version.protocol))
click.echo("description: \"{}\"".format(response.description))
click.echo(
"players: {}/{} {}".format(
response.players.online,
response.players.max,
[
"{} ({})".format(player.name, player.id)
for player in response.players.sample
] if response.players.sample is not None else "No players online"
)
)
@cli.command(short_help="detailed server information")
def query():
"""
Prints detailed server information. Must be enabled in
servers' server.properties file.
"""
response = server.query()
click.echo("host: {}:{}".format(response.raw['hostip'], response.raw['hostport']))
click.echo("software: v{} {}".format(response.software.version, response.software.brand))
click.echo("plugins: {}".format(response.software.plugins))
click.echo("motd: \"{}\"".format(response.motd))
click.echo(
"players: {}/{} {}".format(
response.players.online,
response.players.max,
response.players.names,
)
)
if __name__ == "__main__":
cli()

View File

@@ -1,2 +1,3 @@
six==1.7.3 six==1.7.3
mock==1.0.1 mock==1.0.1
click==6.2

View File

@@ -1,9 +1,9 @@
from distutils.core import setup from setuptools import setup
import sys import sys
PY2 = sys.version_info[0] == 2 PY2 = sys.version_info[0] == 2
install_requires = [ install_requires = [
'six' 'six', 'Click'
] ]
if PY2: if PY2:
@@ -17,11 +17,11 @@ tests_require = [
setup( setup(
name='mcstatus', name='mcstatus',
version='2.1', version='2.2',
author='Nathan Adams', author='Nathan Adams',
author_email='dinnerbone@dinnerbone.com', author_email='dinnerbone@dinnerbone.com',
url='https://pypi.python.org/pypi/mcstatus', url='https://pypi.python.org/pypi/mcstatus',
packages=['mcstatus', 'mcstatus.protocol'], packages=['mcstatus', 'mcstatus.protocol', 'mcstatus.scripts'],
description='A library to query Minecraft Servers for their status and capabilities.', description='A library to query Minecraft Servers for their status and capabilities.',
install_requires=install_requires, install_requires=install_requires,
tests_require=tests_require, tests_require=tests_require,
@@ -35,4 +35,8 @@ setup(
'Operating System :: OS Independent', 'Operating System :: OS Independent',
'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: Software Development :: Libraries :: Python Modules',
], ],
) entry_points='''
[console_scripts]
mcstatus=mcstatus.scripts.mcstatus:cli
''',
)