- #
- # Custom Playlist Plugin for BigBrotherBot(B3) (www.bigbrotherbot.net)
- # Copyright (C) 2011 Phyxious
- #
- # This program 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 2 of the License, or
- # (at your option) any later version.
- # This program 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 this program; if not, write to the Free Software
- # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- #
- # Changelog:
- #
- # 1.0.0 - Initial realease
- __version__ = '1.0.0'
- __author__ = 'Phyxious'
- import threading
- import b3
- import b3.plugin
- import b3.events
- class CustomplaylistPlugin(b3.plugin.Plugin):
- _play_lists = {18: {
- 0: {'tdm':1, 'dm':2, 'ctf':3, 'sd':4, 'koth':5, 'dom':6, 'sab':7, 'dem':8}, # softcore
- 1: {'tdm':9, 'dm':10, 'ctf':11, 'sd':12, 'koth':13, 'dom':14, 'sab':15, 'dem':16}, # hardcore
- 2: {'tdm':17, 'dm':18, 'ctf':19, 'sd':20, 'koth':21, 'dom':22, 'sab':23, 'dem':24}, # barebones
- },
- 12: {
- 0: {'tdm':32, 'dm':33, 'ctf':34, 'sd':35, 'koth':36, 'dom':37, 'sab':38, 'dem':39}, # softcore
- 1: {'tdm':41, 'dm':42, 'ctf':43, 'sd':44, 'koth':45, 'dom':46, 'sab':47, 'dem':48}, # hardcore
- 2: {'tdm':50, 'dm':51, 'ctf':52, 'sd':53, 'koth':54, 'dom':55, 'sab':56}, # barebones
- }
- }
- _map_list = {
- 'mp_array' : 'array',
- 'mp_cracked' : 'cracked',
- 'mp_crisis' : 'crisis',
- 'mp_firingrange' : 'firing range',
- 'mp_duga' : 'grid',
- 'mp_hanoi' : 'hanoi',
- 'mp_cairo' : 'havana',
- 'mp_havoc' : 'jungle',
- 'mp_cosmodrome' : 'launch',
- 'mp_nuked' : 'nuketown',
- 'mp_radiation' : 'radiation',
- 'mp_mountain' : 'summit',
- 'mp_villa' : 'villa',
- 'mp_russianbase' : 'wmd',
- 'mp_berlinwall2' : 'berlin wall',
- 'mp_discovery' : 'discovery',
- 'mp_kowloon' : 'kowloon',
- 'mp_stadium' : 'stadium',
- 'mp_gridlock' : 'convoy',
- 'mp_hotel' : 'hotel',
- 'mp_outskirts' : 'stockpile',
- 'mp_zoo' : 'zoo',
- 'mp_area51' : 'hangar 18',
- 'mp_drivein' : 'drive-in',
- 'mp_silo' : 'silo',
- 'mp_golfcourse' : 'hazard'
- }
- _custom_playlist = {}
- _slot_num = 18
- _game_mode = 0
- _default_playlist = None
- _next_gametype = None
- _next_map = None
- _list_counter = 1
- _rotation = None
- def onStartup(self):
- """\
- Initialize plugin settings
- """
- # get the admin plugin so we can register commands
- self._adminPlugin = self.console.getPlugin('admin')
- if not self._adminPlugin:
- # something is wrong, can't start without admin plugin
- self.error('Could not find admin plugin')
- return false
- # Register commands
- if 'commands' in self.config.sections():
- for cmd in self.config.options('commands'):
- level = self.config.getint('commands', cmd)
- sp = cmd.split('-')
- alias = None
- if len(sp) == 2:
- cmd, alias = sp
- func = self.getCmd(cmd)
- if func:
- self.debug('CUSTOMPLAYLIST: Registering cmd %s' % cmd)
- self._adminPlugin.registerCommand(self, cmd, level, func, alias)
- # Register events
- self.verbose('Registering events')
- self.registerEvent(b3.events.EVT_GAME_MAP_CHANGE)
- # Deugging purposes
- self.debug('Started')
- def onLoadConfig(self):
- self.verbose('Loading config')
- # Get command levels
- self.cmd_change_rotation_minlevel = self.config.getint('commands', 'changerotation')
- self.debug('CUSTOMPLAYLIST: Change rotation min level is: %d' % self.cmd_change_rotation_minlevel)
- self.cmd_get_rotation_minlevel = self.config.getint('commands', 'getrotation')
- self.debug('CUSTOMPLAYLIST: Get Rotation min level is: %d' % self.cmd_get_rotation_minlevel)
- # Get slot number for game server
- self._slot_num = self.config.getint('config_settings', 'slot_num')
- if self._slot_num not in (12, 18):
- self.error('CUSTOMPLAYLIST: Incorrect number of slots %d, set to default of 18.' % self._slot_num)
- self._slot_num = 18
- # Get game mode for server
- self._game_mode = self.config.getint('config_settings', 'game_mode')
- if self._game_mode not in (0, 1, 2):
- self.error('CUSTOMPLAYLIST: Incorrect game mode %d, set to default of softcore.' % self._game_mode)
- self._game_mode = 0
- # Get default playlist
- self._default_playlist = self.config.get('config_settings', 'default_playlist')
- # Get custom playlist order from config file
- if self._default_playlist in self.config.sections():
- for customList in self.config.options(self._default_playlist):
- self._custom_playlist[int(customList)] = self.config.get(self._default_playlist, customList)
- # Debugging purposes
- self.debug('CUSTOMPLAYLIST: %s' % self._custom_playlist)
- def onEvent(self, event):
- """\
- Handle intercepted events
- """
- if event.type == b3.events.EVT_GAME_MAP_CHANGE:
- self.debug('CUSTOMPLAYLIST: Game Map Change Event Fired...')
- # wait 30 sec and set the next map
- timer = threading.Timer(30, self.setRotation)
- timer.start()
- def getCmd(self, cmd):
- cmd = 'cmd_%s' % cmd
- if hasattr(self, cmd):
- func = getattr(self, cmd)
- return func
- return None
- # Rotate through custom playlist to get gametype and map
- def nextRotation(self):
- # Make sure the count is within the playlist number, if not reset to 1
- if self._list_counter not in self._custom_playlist.keys():
- self._list_counter = 1
- self._rotation = self._custom_playlist[self._list_counter].split(',')
- # Check to make sure there is a vaild gametype/map
- if self._rotation[0] in self._play_lists[self._slot_num][self._game_mode] \
- and self._rotation[1] in self._map_list.keys():
- self.debug('CUSTOMPLAYLIST: The selected playlist gametype/map of %s,%s, is valid' % (self._rotation[0], self._rotation[1]))
- self._next_gametype = self._play_lists[self._slot_num][self._game_mode][self._rotation[0]]
- self._next_map = self._rotation[1]
- self.getRotation()
- # Move counter up for next gametype/map
- self._list_counter += 1
- else:
- self.error('CUSTOMPLAYLIST: There was an error in the playlist config file, gametype is: %s and map is: %s.' % (rotation[0], rotation[1]))
- # update counter to move on to next in the playlist and recall nextRotation function
- self._list_counter += 1
- self.nextRotation()
- def setRotation(self):
- # Call nextRotation to get the next gametype/map in the rotation
- self.nextRotation()
- # Set playlist on server to change the gametype
- self.debug('CUSTOMPLAYLIST: setadmindvar playlist %s' % self._next_gametype)
- self.console.write('setadmindvar playlist %s' % self._next_gametype)
- # Exclude all maps except for the next one
- exclude = self._map_list.keys()
- exclude.remove(self._next_map)
- self.debug('CUSTOMPLAYLIST: setadmindvar playlist_excludeMap %s' % ' '.join(exclude))
- self.console.write('setadmindvar playlist_excludeMap %s' % ' '.join(exclude))
- self.debug('CUSTOMPLAYLIST: setadmindvar playlist_excludeGametypeMap ""')
- self.console.write ('setadmindvar playlist_excludeGametypeMap ""')
- def cmd_changerotation(self, data, client=None, cmd=None):
- """\
- Change current rotation
- """
- self.debug('CUSTOMPLAYLIST: Calling cmd_changerotation')
- # Check to make sure its an int
- if data != int(data):
- data = int(data)
- # Make sure within the range of the current playlist
- if data in self._custom_playlist.keys():
- self._list_counter = data
- self.setRotation()
- else:
- client.message('ERROR: %d is not a number in the current playlist' % data)
- def cmd_getrotation(self, data=None, client=None, cmd=None):
- """\
- Get next rotation and print to console
- """
- self.getRotation()
- def getRotation(self):
- if self._rotation[0] == 'koth':
- gt = 'HQ'
- else:
- gt = self._rotation[0].swapcase()
- self.console.say('^1Nextmap ^7is: ^3%s' % (gt, self._map_list[self._next_map].capitalize()))