Scripts:MM MapAutoSizer

From BF2 Technical Information Wiki
Revision as of 15:32, 22 June 2018 by Pireax (talk | contribs) (Created page with "__TOC__ == Introduction == After trying out Scripts:AutoMap and finding that it didn't do exactly what I wanted (and didn't seem to work with BF2 1.12),...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Introduction

After trying out Scripts:AutoMap and finding that it didn't do exactly what I wanted (and didn't seem to work with BF2 1.12), I decided to write a plugin for the popular ModManager package that comes with BF2CC. The idea is based on Scripts:AutoMap, but there are some important differences:

  • no randomizer
  • the map rotation is read directly out of the BF2 server and not from maplist.con. This allows you to use this script even when you're changing your map rotation on the fly, without messing things up. It also allows map voting to work properly.
  • map size thresholds are configurable through the modmanager configuration file

Downloading

You can always find the most current version at the GloryHoundz Code Repository. As of this writing, the latest version is 1.0 to be found here: mm_mapautosizer.py.

Prerequisites

ModManager or BF2CC

Install

  • copy the file to admin/modules in your Battlefield 2 server install.
  • change your modmanager.con and include the following line:
''modmanager.loadModule "mm_mapautosizer"''
  • The default threshold for 32-size maps is 16 players and for 64-size maps it's 32 players. You can set your own thresholds by adding two configuration lines to modmanager.con:
''mm_mapautosizer.threshold_64 40''
''mm_mapautosizer.threshold_32 20''

Bugs/Comments

If you encounter any problems, stop by the GloryHoundz Forums and post about it.

The Code

# vim: ts=4 sw=4 noexpandtab
"""MapAutoSizer module

===== About =====
 This ModManager script was created by GloryHoundz.com to allow for auto
 sizing of maps in rotation based on the number of people on a server.

 Inspired and partially based on the DontCamp.com dc_automap.py script from
 http://bf2.fun-o-matic.org/index.php/Scripts:AutoMap

===== Config =====
 # 64 Player map threshold. End of map number of players to trigger 64-size map
 mm_mapautosizer.threshold_64 32

 # 32 Player map threshold. End of map number of players to trigger 32-size map
 mm_mapautosizer.threshold_32 16

===== History =====
 v1.0 - 1/15/2006:
 Initial public release: fixed map voting support

 v0.9 - 1/08/2006:
 Internal GloryHoundz.com release
"""

import bf2
import host
import mm_utils
import re

# Set the version of your module here
__version__ = 1.0

# Set the required module versions here
__required_modules__ = {
    'modmanager': 1.0
}

# Does this module support reload ( are all its reference closed on shutdown? )
__supports_reload__ = True

# Set the description of your module here
__description__ = "MapAutoSizer v%s" % __version__

# Add all your configuration options here
configDefaults = {
    'threshold_64': 32,
    'threshold_32': 16
}

class MapAutoSizer( object ):

    def __init__( self, modManager ):
        # ModManager reference
        self.mm = modManager

        # Internal shutdown state
        self.__state = 0

        # Add any static initialisation here.
        # Note: Handler registration should not be done here
        # but instead in the init() method

    def onGameStatusChanged(self, status):
        """Control Map rotation."""

        threshold64 = self.__config['threshold_64']
        threshold32 = self.__config['threshold_32']
        if 1 != self.__state:
            return 0

        if status == bf2.GameStatus.EndGame:
            host.rcon_invoke('echo "MapAutoSizer Initializing"')

            rawMapRotation = host.rcon_invoke('maplist.list').split("\n")

            mapRotation = []
            for mapLine in rawMapRotation:
                if mapLine:
                    mapParts = mapLine.split(" ")
                    if mapParts[1]:
                        mapRotation.append(mapParts[1])

            nextMapIndex = int(host.rcon_invoke('admin.nextLevel'))
            if nextMapIndex >= len(mapRotation):
                nextMapIndex = 0
            host.rcon_invoke('echo "MapAutoSizer next map index: %s"' % (nextMapIndex))

            nextMap = mapRotation[nextMapIndex]
            host.rcon_invoke('echo "MapAutoSizer next map: %s"' % (nextMap))

            numPlayers = 0

            for p in bf2.playerManager.getPlayers():
                numPlayers += 1

            host.rcon_invoke('echo "MapAutoSizer number of players: %s"' % (numPlayers))

            if numPlayers >= threshold64:
                mapSize = 64
            if numPlayers < threshold64:
                mapSize = 32
            if numPlayers < threshold32:
                mapSize = 16

            host.rcon_invoke('echo "Changing map entry (index,name,size): (%s,%s,%s)"' % (nextMapIndex, nextMap, mapSize))
            host.rcon_invoke('maplist.insert %s %s gpm_cq %d' % (nextMapIndex, nextMap, mapSize))
            host.rcon_invoke('maplist.remove %s' % (nextMapIndex+1))
            host.rcon_invoke('admin.setnextlevel %s' % (nextMapIndex))
            host.rcon_invoke('echo "MapAutoSizer finished"')

    def init( self ):
        """Provides default initialisation."""

        # Load the configuration
        self.__config = self.mm.getModuleConfig( configDefaults )

        if 0 == self.__state:
            # Register GameStatus event handler
            host.registerGameStatusHandler(self.onGameStatusChanged)

        # Update to the running state
        self.__state = 1

    def shutdown( self ):
        """Shutdown and stop processing."""

        # Flag as shutdown as there is currently way to:
        # host.unregisterHandler
        self.__state = 2

        # Unregister GameStatus event handler
        host.unregisterGameStatusHandler(self.onGameStatusChanged)

    def update( self ):
        """Process and update.
        Note: This is called VERY often processing in here should
        be kept to an absolute minimum.
        """
        pass

def mm_load( modManager ):
    """Creates and returns the MapAutoSizer object."""
    return MapAutoSizer( modManager )

Changelog

v1.0 - 1/15/2006:
Initial public release: fixed map voting support
v0.9 - 1/08/2006:
Internal GloryHoundz.com release