Skip to content

Instantly share code, notes, and snippets.

@hikari-no-yume
Created May 21, 2011 21:06
Show Gist options
  • Save hikari-no-yume/984901 to your computer and use it in GitHub Desktop.
Save hikari-no-yume/984901 to your computer and use it in GitHub Desktop.
Stub
from twisted.internet.protocol import Protocol
from bravo.location import Location
class ClassicServerProtocol(Protocol):
"""
The Minecraft Classic server protocol.
This class is mostly designed to be a skeleton for featureful clients. It
tries hard to not step on the toes of potential subclasses.
"""
state = STATE_UNAUTHENTICATED
buf = b""
player = None
username = None
def __init__(self):
self.location = Location()
self.handlers = {
0: self.login,
5: self.setblock,
8: self.position,
13: self.message
}
self._ping_loop = LoopingCall(self.update_ping)
def login(self, container):
"""
Hook for login packets.
Override this to customize how logins are handled. By default, this
method will only confirm that the negotiated wire protocol is the
correct version, and then it will run the ``authenticated()``
callback.
"""
self._ping_loop.start(5)
def setblock(self, container):
"""
Hook for set block packets.
"""
def position(self, container):
"""
Hook for position packets.
"""
def orientation(self, container):
"""
Hook for orientation packets.
"""
def location_packet(self, container):
"""
Hook for location packets.
"""
self.position(container)
self.orientation(container)
def message(self, container):
"""
Hook for message packets.
"""
# Twisted-level data handlers and methods
# Please don't override these needlessly, as they are pretty solid and
# shouldn't need to be touched.
def dataReceived(self, data):
self.buf += data
packets, self.buf = parse_packets(self.buf)
for header, payload in packets:
if header in self.handlers:
self.handlers[header](payload)
else:
log.err("Didn't handle parseable packet %d!" % header)
log.err(payload)
def connectionLost(self, reason):
if self._ping_loop.running:
self._ping_loop.stop()
# Event callbacks
# These are meant to be overriden.
def orientation_changed(self):
"""
Called when the client moves.
This callback is only for orientation, not position.
"""
pass
def position_changed(self):
"""
Called when the client moves.
This callback is only for position, not orientation.
"""
pass
# Convenience methods
def update_ping(self):
"""
Send a keepalive to the client.
"""
packet = make_packet("ping")
self.transport.write(packet)
def error(self, message):
"""
Error out.
This method sends ``message`` to the client as a descriptive error
message, then closes the connection.
"""
self.transport.write(make_error_packet(message))
self.transport.loseConnection()
class BannedProtocol(ClassicServerProtocol):
"""
A very simple Classic protocol that helps enforce IP bans.
This protocol disconnects people as soon as they connect, with a helpful
message.
"""
def connectionMade(self):
self.error("Sorry, but your IP address is banned.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment