Exemple #1
0
def server_status(address, server_port=None, debug=False):
    # Mapping engine map names to human-readable names
    map_names = {
        'MP_Abandoned': 'Zavod 311',
        'MP_Damage': 'Lancang Dam',
        'MP_Flooded': 'Flood Zone',
        'MP_Journey': 'Golmud Railway',
        'MP_Naval': 'Paracel Storm',
        'MP_Prison': 'Operation Locker',
        'MP_Resort': 'Hainan Resort',
        'MP_Siege': 'Siege of Shanghai',
        'MP_TheDish': 'Rogue Transmission',
        'MP_Tremors': 'Dawnbreaker',
        'XP1_001': 'Silk Road',
        'XP1_002': 'Altai Range',
        'XP1_003': 'Guilin Peaks',
        'XP1_004': 'Dragon Pass',
        'XP0_Caspian': 'Caspian Border',
        'XP0_Firestorm': 'Operation Firestorm',
        'XP0_Metro': 'Operation Metro',
        'XP0_Oman': 'Gulf of Oman',
        'XP2_001': 'Lost Islands',
        'XP2_002': 'Nansha strike',
        'XP2_003': 'WaveBreaker',
        'XP2_004': 'Operation Mortar',
        'XP3_MarketPl': 'Pearl Market',
        'XP3_Prpganda': 'Propaganda',
        'XP3_UrbanGdn': 'Lumphini Garden',
        'XP3_WtrFront': 'Sunken Dragon',
        'XP4_Arctic': 'Operation Whiteout',
        'XP4_SubBase': 'Hammerhead',
        'XP4_Titan': 'Hangar 21',
        'XP4_WlkrFtry': 'Giants of Karelia',
        'MP_Bank': 'Bank Job',
        'MP_Bloodout': 'The Block',
        'MP_Desert05': 'Dustbowl',
        'MP_Downtown': 'Downtown',
        'MP_Eastside': 'Derailed',
        'MP_Glades': 'Everglades',
        'MP_Growhouse': 'Growhouse',
        'MP_Hills': 'Hollywood Heights',
        'MP_OffShore': 'Riptide'
    }

    # Mapping engine map modes to human-readable names
    game_modes = {
        'AirSuperiority0': 'Air Superiority',
        'CaptureTheFlag0': 'Capture the Flag',
        'CarrierAssaultSmall0': 'Carrier Assault',
        'CarrierAssaultLarge0': 'Carrier Assault Large',
        'Chainlink0': 'Chain Link',
        'ConquestSmall0': 'Conquest Small',
        'ConquestLarge0': 'Conquest Large',
        'Elimination0': 'Defuse',
        'Domination0': 'Domination',
        'Obliteration': 'Obliteration',
        'RushLarge0': 'Rush',
        'SquadDeathMatch0': 'Squad DM',
        'TurfWarLarge0': 'Conquest Large',
        'TurfWarSmall0': 'Conquest Small',
        'Heist0': 'Heist',
        'Hotwire0': 'Hotwire',
        'BloodMoney0': 'Blood Money',
        'Hit0': 'Crosshair',
        'Hostage0': 'Rescue',
        'TeamDeathMatch0': 'Team DM',
        'GunMaster0': 'Gun Master'
    }

    def recv(sock):
        # Pull enough to get the int headers and instantiate a Packet
        out = sock.recv(12)
        p = Packet.from_buffer(out)
        packet_size = len(p)
        # Pull one character at a time until we've recv'd
        # up to the reported size
        while len(out) < packet_size:
            out += sock.recv(1)
        return out

    try:
        port = int(server_port)
    except TypeError:
        port = 47200

    server = address, port

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect(server)

    serverinfo = Packet(1, False, True, 'serverinfo')
    sock.sendall(serverinfo.to_buffer())

    response = Packet.from_buffer(recv(sock))
    serverinfo = response.words

    listplayers = Packet(2, False, True, 'listPlayers all')
    sock.sendall(listplayers.to_buffer())
    response = Packet.from_buffer(recv(sock))
    listplayers = response.words

    sock.close()

    # Need both of these to go on
    assert serverinfo[0] == 'OK'
    assert listplayers[0] == 'OK'

    # Chomp on the listplayers output and loop out some namedtuples
    num_fields, the_rest = int(listplayers[1]), listplayers[2:]
    fields, num_players, players = (the_rest[:num_fields],
                                    the_rest[num_fields],
                                    the_rest[num_fields + 1:])

    Player = namedtuple('Player', fields)

    player_list = list()
    while players:
        player_list.append(Player(*players[:num_fields]))
        players = players[num_fields:]

    # Print out pretty server name/players
    if debug:
        print 'server name: ' + serverinfo[1]
        print 'players : ' + serverinfo[2]
        print 'maxplayers : ' + serverinfo[3]
        print 'mode : ' + serverinfo[4]
        print 'map : ' + serverinfo[5]

    player_count = serverinfo[2] + '/' + serverinfo[3]
    current_map = map_names[serverinfo[5]]
    current_mode = game_modes[serverinfo[4]]
    server_name = serverinfo[1]
    return player_list, player_count, current_map, current_mode, server_name