Source code for pyspades.master

# Copyright (c) Mathias Kaerlev 2011-2012.

# This file is part of pyspades.

# pyspades is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# pyspades is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with pyspades.  If not, see <http://www.gnu.org/licenses/>.

"""
Implementation of the 0,75 master server protocol
"""

from pyspades.loaders import Loader
from pyspades.protocol import BaseConnection
from pyspades.constants import MASTER_VERSION

from twisted.internet.defer import Deferred

PORT = 32886

MAX_SERVER_NAME_SIZE = 31
MAX_MAP_NAME_SIZE = 20
MAX_GAME_MODE_SIZE = 7

HOST = 'master.buildandshoot.com'


[docs]class AddServer(Loader): """The AddServer packet sent to the master server""" __slots__ = ['count', 'max_players', 'name', 'port', 'game_mode', 'map'] id = 4
[docs] def read(self, reader): if reader.dataLeft() == 1: self.count = reader.readByte(True) else: self.max_players = reader.readByte(True) self.port = reader.readShort(True, False) self.name = reader.readString() self.game_mode = reader.readString() self.map = reader.readString()
[docs] def write(self, writer): if self.count is None: writer.writeByte(self.max_players) writer.writeShort(self.port, True, False) writer.writeString(self.name) writer.writeString(self.game_mode) writer.writeString(self.map) else: writer.writeByte(self.count, True)
add_server = AddServer()
[docs]class MasterConnection(BaseConnection): disconnect_callback = None connected = False
[docs] def on_connect(self): self.connected = True self.send_server() if self.defer is not None: self.defer.callback(self) self.defer = None
[docs] def set_count(self, value): add_server.count = value self.send_contained(add_server)
[docs] def send_server(self): protocol = self.server_protocol add_server.count = None add_server.name = protocol.name[:MAX_SERVER_NAME_SIZE].encode() add_server.game_mode = protocol.get_mode_name()[:MAX_GAME_MODE_SIZE].encode() add_server.map = protocol.map_info.short_name[:MAX_MAP_NAME_SIZE].encode() add_server.port = protocol.host.address.port add_server.max_players = protocol.max_players self.send_contained(add_server)
[docs] def on_disconnect(self): if self.defer is not None: self.defer.errback(self) self.defer = None callback = self.disconnect_callback if callback is not None: callback() self.disconnect_callback = None
[docs]def get_master_connection(protocol): defer = Deferred() connection = protocol.connect(MasterConnection, HOST, PORT, MASTER_VERSION) connection.server_protocol = protocol connection.defer = defer return defer