Thomas

Founder
  • Content count

    301
  • Joined

  • Last visited

Community Reputation

179 Godlike

About Thomas

  • Rank
    A Founder of Raid-Gaming

Profile Information

  • Gender
    Not Telling

Recent Profile Visitors

17666 profile views
  1. Sad to see you go iMtroll, you had a good run. I am lucky to have worked with you, thank you for saving Raid when it was going to be shut down. To the new managers, I wish you good luck, as the position is not an easy one. If you ever need me, always feel free to PM me. Thank you for your dedication and service to Raid. -Thomas
  2. Source: http://www.dorkly.com/post/75301/videogame-jobs-expectation-vs-reality
  3. BigBrotherBot is able to manage the rotation of the maps by setting dvars. This plugin manages the frequency of the map by setting map_rotation by player count: rotationmanager.py # # Plugin for BigBrotherBot(B3) (www.bigbrotherbot.net) # Copyright (C) 2005 www.xlr8or.com # # 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 - 1.1.0: Added MapDelay and smart/random creation of rotations # 1.0.0 - 1.1.1: Added fallbackrotation and some errorchecking # 1.1.1 - 1.1.2: Added some more debugging. # 1.1.2 - 1.1.3: Introduced copy.deepcopy() # 1.1.3 - 1.1.4: Added CoD1/CoD2 restartcompatibility # Fixed a bug where B3 was unresponsive while in restart-countdown # 1.1.4 - 1.1.5: Few Bugfixes. # 1.1.5 - 1.1.6: Stripped space at end of rotation. # 1.1.6 - 1.2.0: Added hysteresis, added some comments, added caching of roundstartrotation # 1.2.0 - 1.2.1: Fixed a bug where the cached rotation would remain 'None' # 1.2.1 - 1.2.2: Added another safety .strip() when storing _roundstart_mapRotationCurrent # 1.2.2 - 1.2.3: Introduced version 11 for UO; generate rotations with all gametypes # 1.2.3 - 1.2.4: Added check for limitation of the maximum stringlength (capped at 980) # 1.3.0 : Added support for CoD4 # 1.3.1 : fixed a bug where on slower boxes the rotation wasn't stored on time # 1.3.2 : only add maps that have not been added in the last 4 passes, no more double maps # 1.3.3 : ... # 1.3.4 : bugfix in maphistory # 1.3.5 : Added gametypehistory, changed maphistory: both are now configurable for each # rotation size individually - Just a baka # 1.3.6 : Added cod7 support, beautified code - Just a baka # 1.3.7 : Reworked adjustrotation, fixed bugs that were causing unnecessary # setrotation() calls - Just a baka # 1.3.8 : Implemented proper cod6 support, optimized first saveroundstartrotation - Just a baka # 1.3.9 : Added map, maps and nextmap commands for ranked cod7 - 82ndab-Bravo17 # 1.3.9a : Added Names translation for COD7 maps - 82ndab-Bravo17 # 1.3.9b : Added DLC2 Maps # 1.3.9c : Added DLC3 Maps # 1.4.0 : Correct hysteresis logic and add second hysteresis value, now have one for snall-medium and one for medium-high __version__ = '1.4.0' __author__ = 'xlr8or, Just a baka, 82ndab-Bravo17' import copy import threading import time import random import b3 import b3.events import string #-------------------------------------------------------------------------------------------------- class RotationmanagerPlugin(b3.plugin.Plugin): _rotation_small = {} _rotation_medium = {} _rotation_large = {} _currentrotation = 0 _immediate = 0 _switchcount1 = 0 _switchcount2 = 0 _hysteresis1 = 0 _hysteresis2 = 0 _playercount = -1 _oldplayercount = None _mapDelay = 0 _version = 0 _restartCmd = '' _countDown = 0 _donotadjustnow = False _randomizerotation = 0 _roundstart_mapRotation = None _roundstart_mapRotationCurrent = '' _roundstart_currentrotation = 0 _fallbackrotation = '' _needfallbackrotation = False _initialrecount = False _rotation_size = 1 # 1 - small, 2 - medium, 3 - large _recentmaps = [] # The Maphistory _recentgts = [] # The Gametype history _hmm = [0,0,0] # HowManyMaps to keep as a maphistory _hmgt = [0,0,0] # HowManyGameTypes to keep as a gametype history _cod7MapRotation = [] _cod7MapRotationFixed = [] _nextmap7 = [] _outofrotation = False _cod7Maps = ['mp_array','mp_cairo','mp_cosmodrome','mp_cracked','mp_crisis','mp_duga','mp_firingrange','mp_hanoi', 'mp_havoc','mp_nuked','mp_mountain','mp_radiation','mp_russianbase','mp_villa','mp_berlinwall2', 'mp_kowloon','mp_stadium','mp_discovery','mp_gridlock','mp_hotel','mp_outskirts','mp_zoo','mp_area51','mp_drivein','mp_silo','mp_golfcourse'] _cod7Mapeasynames = ['Array','Havanna','Launch','Cracked','Crisis','Grid','Firing Range','Hanoi', 'Jungle','Nuketown','Summit','Radiation','WMD','Villa','Berlin Wall', 'Kowloon','Stadium','Discovery','Gridlock','Hotel','Outskirts','Zoo','Hanger 18','Drive-in','Silo','Hazard'] _cod7Mapeasynameslower = ['array','havanna','launch','cracked','crisis','grid','firing range','hanoi', 'jungle','nuketown','summit','radiation','wmd','villa','berlin wall', 'kowloon','stadium','discovery','gridlock','hotel','outskirts','zoo','hanger 18','drive-in','silo','hazard'] _cod7Playlists = {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 (yes, no dem) } } _slot_num = 18 _game_mode = 0 _cod7Gametypes = ['tdm', 'dm', 'ctf', 'sd', 'hq', 'koth', 'dom', 'sab', 'dem'] 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 our commands if 'commands' in self.config.sections() and self._version == 7: for cmd in self.config.options('commands'): level = self.config.get('commands', cmd) sp = cmd.split('-') alias = None if len(sp) == 2: cmd, alias = sp func = self.getCmd(cmd) if func: self._adminPlugin.registerCommand(self, cmd, level, func, alias) # Register our events self.verbose('Registering events') self.registerEvent(b3.events.EVT_CLIENT_CONNECT) self.registerEvent(b3.events.EVT_CLIENT_DISCONNECT) self.registerEvent(b3.events.EVT_GAME_EXIT) # don't adjust the rotation just yet self._donotadjustnow = True if self._version != 7: self._needfallbackrotation = True self._initialrecount = True # we'll store the initial rotation self.retrievefallback() # wait half a minute after pluginstart to do an initial playercount t1 = threading.Timer(30, self.recountplayers) t1.start() self.debug('Started') def onLoadConfig(self): # load our settings self.verbose('Loading config') self._switchcount1 = self.config.getint('settings', 'switchcount1') self._switchcount2 = self.config.getint('settings', 'switchcount2') self._hysteresis1 = self.config.getint('settings', 'hysteresis1') self._hysteresis2 = self.config.getint('settings', 'hysteresis2') self._immediate = self.config.getboolean('settings', 'immediate') self._mapDelay = self.config.getint('settings', 'mapdelay') self._version = self.config.getint('settings', 'version') self._randomizerotation = self.config.getboolean('settings', 'randomizerotation') self._hmm[0] = abs(self.config.getint('histories', 'maphistory_small')) self._hmm[1] = abs(self.config.getint('histories', 'maphistory_medium')) self._hmm[2] = abs(self.config.getint('histories', 'maphistory_large')) self.debug('MapHistory is set to: %s' % self._hmm) self._hmgt[0] = abs(self.config.getint('histories', 'gthistory_small')) self._hmgt[1] = abs(self.config.getint('histories', 'gthistory_medium')) self._hmgt[2] = abs(self.config.getint('histories', 'gthistory_large')) self.debug('GTHistory is set to: %s' % self._hmgt) if self._version == 7: self._slot_num = self.config.getint('cod7', 'slot_num') if self._slot_num not in (12, 18): self.error ('Incorrect number of slots (%d), assuming you meant 18.' % self._slot_num) self._slot_num = 18 self._game_mode = self.config.getint('cod7', 'game_mode') if self._game_mode not in (0, 1, 2): self.error ('Incorrect game mode (%d), assuming you meant softcore.' % self._game_mode) self._game_mode = 0 for gametype in self.config.options('rotation_small'): maps = self.config.get('rotation_small', gametype) maps = maps.split(' ') self._rotation_small[gametype] = maps self.debug('Small %s: %s' %(gametype, maps)) for gametype in self.config.options('rotation_medium'): maps = self.config.get('rotation_medium', gametype) maps = maps.split(' ') self._rotation_medium[gametype] = maps self.debug('Medium %s: %s' % (gametype, maps)) for gametype in self.config.options('rotation_large'): maps = self.config.get('rotation_large', gametype) maps = maps.split(' ') self._rotation_large[gametype] = maps self.debug('Large %s: %s' % (gametype, maps)) if self._version in (1, 11): # 1: CoD1 or 11: CoD UO self._restartCmd = 'map_restart' elif self._version in (2, 4, 5, 6): # CoD2, CoD4, CoD5 or CoD6 self._restartCmd = 'fast_restart' else: self._mapDelay = 0 def getCmd(self, cmd): cmd = 'cmd_%s' % cmd if hasattr(self, cmd): func = getattr(self, cmd) return func return None def onEvent(self, event): """\ Handle intercepted events """ if event.type == b3.events.EVT_CLIENT_CONNECT: self._playercount += 1 self.debug('PlayerCount +1: %s' % self._playercount) # we're going up, pass a positive 1 to the adjustmentfunction self.adjustrotation(+1) elif event.type == b3.events.EVT_CLIENT_DISCONNECT: self._playercount -= 1 self.debug('PlayerCount -1: %s' % self._playercount) # we're going down, pass a negative 1 to the adjustmentfunction self.adjustrotation(-1) elif event.type == b3.events.EVT_GAME_EXIT: self._donotadjustnow = True # wait 2 mins and cache the current rotation cvars if self._version != 7: t3 = threading.Timer(120, self.saveroundstartrotation) t3.start() # wait 3 mins and do a recount t4 = threading.Timer(180, self.recountplayers) t4.start() # should we fast_restart? if self._mapDelay != 0 and self._version != 7: t5 = threading.Thread(target=self.fastrestart) t5.start() # cod7 map change support if self._version == 7: # wait 2 minutes and set the next map self.debug ('Map change detected, Will push the new map to the server after 2 minutes.') self.cod7getnextmap() t6 = threading.Timer(120, self.cod7maprotate) t6.start() def adjustrotation(self, delta): if self._donotadjustnow: return None new_rotation = 0 # size: from 1 (small) to 3 (large) if delta == +1: if self._rotation_size == 3 or self._playercount > (self._switchcount2 + self._hysteresis2): new_rotation = 3 elif self._rotation_size == 2 or self._playercount > (self._switchcount1 + self._hysteresis1): new_rotation = 2 else: new_rotation = 1 elif delta == -1: if self._rotation_size == 1 or self._playercount < (self._switchcount1 - self._hysteresis1): new_rotation = 1 elif self._rotation_size == 2 or self._playercount < (self._switchcount2 - self._hysteresis2): new_rotation = 2 else: new_rotation = 3 elif delta == 0: if self._playercount < self._switchcount1: new_rotation = 1 elif self._playercount < self._switchcount2: new_rotation = 2 else: new_rotation = 3 if new_rotation != 0 and (new_rotation != self._rotation_size or\ (self._version == 7 and len(self._cod7MapRotation) == 0) or\ self._initialrecount): self.setrotation (new_rotation) elif new_rotation == 0: self.debug ('Invalid delta has been passed to adjustrotation, aborting.') else: self.debug ('Rotation size has not changed, will not update rotation.') return None def setrotation(self, newrotation): if newrotation == self._currentrotation and self._version != 7: return None # restore the rotation if the new one is the same as the one at round/map start if newrotation == self._roundstart_currentrotation and self._roundstart_mapRotation is not None and self._version != 7: self.debug('Restoring Cached Roundstart Rotations') if self._version != 6: if self._roundstart_mapRotation != '': self.console.setCvar('sv_mapRotation', self._roundstart_mapRotation) if self._roundstart_mapRotationCurrent != '': self.console.setCvar('sv_mapRotationCurrent', self._roundstart_mapRotationCurrent) else: if self._roundstart_mapRotation != '': self.console.write('sv_mapRotation %s' % self._roundstart_mapRotation) if self._roundstart_mapRotationCurrent != '': self.console.write('sv_mapRotationCurrent %s' % self._roundstart_mapRotationCurrent) self._currentrotation = newrotation return None if newrotation == 1: rotname = "small" rotation = self._rotation_small elif newrotation == 2: rotname = "medium" rotation = self._rotation_medium elif newrotation == 3: rotname = "large" rotation = self._rotation_large else: self.error('Error: Invalid newrotation passed to setrotation.') return None self._rotation_size = newrotation self.debug('Adjusting to %s mapRotation' % rotname) self._rotation = self.generaterotation(rotation) if self._version != 7: if self._version != 6: self.console.setCvar('sv_mapRotation', self._rotation) else: self.console.write('sv_mapRotation %s' % self._rotation) if self._immediate and self._version != 6: self.console.setCvar('sv_mapRotationCurrent', '') elif self._immediate: self.console.write('reset sv_mapRotationCurrent') self._currentrotation = newrotation if self._initialrecount: self.saveroundstartrotation(self._rotation) else: self.cod7getnextmap() self.cod7maprotate() def generaterotation(self, rotation): #self.debug('Generate from: %s @ size: %s' % (rotation, self._rotation_size)) rotation_size = self._rotation_size - 1 # We'll be using it as an index for _hmgt r = '' self._cod7MapRotation = [] if self._randomizerotation: self.debug('Creating randomized rotation...') rot = copy.deepcopy(rotation) count = 0 lastgametype = '' for gametype,maplist in rot.items(): count += len(maplist) self.debug('MapCount: %s' % count) while count > 0: c = random.randint(1,count) #self.debug('Random: %s' % c) for gametype,maplist in rot.items(): if c > len(maplist): #self.debug('Length this maplist: %s' % (len(maplist))) c -= len(maplist) else: # Check if this mode was recently added if gametype in self._recentgts: self.debug('Gametype %s skipped, already added in the last %s items' % (gametype, self._hmgt[rotation_size]) ) continue # skip to the next map in queue # Check if this map was recently added elif maplist[c-1] in self._recentmaps: self.debug('Map %s skipped, already added in the last %s items' % (maplist[c-1], self._hmm[rotation_size]) ) continue # skip to the next map in queue # cod7 - check if this gametype exists for the chosen game mode and a number of slots elif self._version == 7 and gametype not in self._cod7Playlists[self._slot_num][self._game_mode]: self.warning('Gametype %s cannot be played in current playlist (game_mode=%d, slot_num=%d)' % (gametype, self._slot_num, self._game_mode)) continue # skip to the next map in queue if self._version != 7: addition = '' if gametype != lastgametype or self._version in (4, 6, 11): #UO, CoD4 and CoD6 need every gametype pre map addition = 'gametype ' + gametype + ' ' addingmap = maplist.pop(c-1) if self._version != 7: addition = addition + 'map ' + addingmap + ' ' if self._version != 7 and (len(r) + len(addition)) > 960: self.debug('Maximum sv_rotation stringlength reached... Aborting adding maps to rotation!') count = 0 # Make sure we break out of the while loop break # Break out of the for loop if self._version != 7: r += addition else: self._cod7MapRotation.append ([gametype,addingmap]) #self.debug('Building: %s' % r) rot[gametype] = maplist lastgametype = gametype if self._hmm[rotation_size] != 0: self._recentmaps.append(addingmap) self._recentmaps = self._recentmaps[-self._hmm[rotation_size]:] # Slice the last _hmm nr. of maps if self._hmgt[rotation_size] != 0: self._recentgts.append(gametype) self._recentgts = self._recentgts[-self._hmgt[rotation_size]:] # Slice the last _hmgt nr. of gametypes break count -= 1 else: self.debug('Creating non-randomized rotation...') stringmax = 0 # UO, CoD6 and CoD4 needs every gametype pre map if self._version in (4, 6, 11): for gametype,maplist in rotation.items(): for map in maplist: addition = 'gametype ' + gametype + ' ' + 'map ' + map + ' ' if (len(r) + len(addition)) > 980: self.debug('Maximum sv_rotation stringlength reached... Aborting adding maps to rotation!') stringmax = 1 # Make sure we break out of the first for loop break # Break out of the nested for loop r += addition if stringmax == 1: break # Break out of the first for loop elif self._version == 7: addition = [] for gametype,maplist in rotation.items(): for map in maplist: addition = [gametype, map] self._cod7MapRotation.append (addition) self._cod7MapRotationFixed = self._cod7MapRotation else: for gametype,maplist in rotation.items(): r2 = r # Backup r r = r + 'gametype ' + gametype + ' ' for map in maplist: r = r + 'map ' + map + ' ' if len(r) > 980 and self._version != 7: self.debug('Maximum sv_rotation stringlength reached... Aborting adding maps to rotation!') r = r2 # Restore r and break out stringmax = 1 break r2 = r # Backup r if stringmax == 1: break # Break out completely if self._version != 7: self.debug('NewRotation: %s' % r) else: self.debug('NewBlackOpsRotation: %s' % self._cod7MapRotation) if self._version != 7 and r.strip() == '': r = self._fallbackrotation self.error('Error: Generation failed! Reverting to original rotation!') # Strip excessive spaces from the new rotation r = r.strip() return r def recountplayers(self): if self._version != 7: # do we still need the original rotation if self._needfallbackrotation: self.retrievefallback() # if we still didnt get it we'll wait for the next round/map if self._needfallbackrotation: self.error('Error: Still not able to retrieve initial rotation!') return None # reset, recount and set a rotation self._oldplayercount = self._playercount self._playercount = 0 self._donotadjustnow = False self._playercount = len (self.console.clients.getList()) self.debug('PlayerCount recount players: %s' % self._playercount) if self._oldplayercount == -1: self.adjustrotation(0) elif self._playercount > self._oldplayercount: self.adjustrotation(+1) elif self._playercount < self._oldplayercount: self.adjustrotation(-1) else: pass def retrievefallback(self): self._fallbackrotation = self.console.getCvar('sv_mapRotation').getString() time.sleep(0.5) # Give us plenty time to store the rotation if self._fallbackrotation is not None: self.debug('Fallbackrotation: %s' % self._fallbackrotation) # this is the only place where _needfallbackrotation is set to False! self._needfallbackrotation = False else: self.error('Could not save original rotation... Waiting for next pass') def saveroundstartrotation(self, rotation=''): if self._initialrecount and self._version != 7: self.debug('Saving the first generated rotation as the cached roundstart rotation') self._roundstart_mapRotation = rotation self._roundstart_mapRotationCurrent = '' self._initialrecount = False elif self._version != 7: self.debug('Getting current Rotation') self._roundstart_mapRotation = self.console.getCvar('sv_mapRotation') if self._roundstart_mapRotation is not None and self._roundstart_mapRotation != '': self._roundstart_mapRotation = self._roundstart_mapRotation.getString() self.debug('Cached Rotation: %s' % self._roundstart_mapRotation) else: self._roundstart_mapRotation = None self._roundstart_mapRotationCurrent = self.console.getCvar('sv_mapRotationCurrent') if self._roundstart_mapRotationCurrent is not None and self._roundstart_mapRotationCurrent != '': self._roundstart_mapRotationCurrent = self._roundstart_mapRotationCurrent.getString() # Removing extra spaces just in case... self._roundstart_mapRotationCurrent = self._roundstart_mapRotationCurrent.strip() self.debug('Cached RotationCurrent: %s' % self._roundstart_mapRotationCurrent) else: self._roundstart_mapRotationCurrent = '' self._roundstart_currentrotation = self._currentrotation else: pass def cod7getnextmap(self): if len(self._cod7MapRotation) == 0: self._donotadjustnow = False self.debug ('Nothing to rotate, re-adjusting rotation...') self.adjustrotation(0) # Get the next [gametype,map] and remove it from _cod7MapRotation if not self._outofrotation: self._nextrotationmap = self._cod7MapRotation.pop(0) self._nextmap7 = self._nextrotationmap self._outofrotation = False def cod7maprotate(self): self.debug('COD7MAPROTATE: next map will be %s at %s' % (self._nextmap7[0], self._nextmap7[1])) # Set the playlist thus changing the gametype self.console.write('setadmindvar playlist %s' % self._cod7Playlists[self._slot_num][self._game_mode][self._nextmap7[0]]) # Build a map exclusion rule then apply it. Will exclude every map except the next one. exclusion = copy.copy (self._cod7Maps) exclusion.remove (self._nextmap7[1]) self.console.write ('setadmindvar playlist_excludeMap "%s"' % ' '.join(exclusion)) # Keep playlist_excludeGametypeMap empty, I'm in charge here! # If next map is in this dvar, server will keep not changing maps until it recieves something that's not restricted self.console.write ('setadmindvar playlist_excludeGametypeMap ""') def fastrestart(self): self._countDown = int(self._mapDelay)/10 while self._countDown > 0: self.console.say('^1*** MATCH STARTING IN ^7%s^1 SECONDS ***' % (self._countDown*10) ) self._countDown -= 1 time.sleep(10) self.console.say('^7*** ^1MATCH ^7*** ^1STARTING ^7***') time.sleep(3) self.console.write(self._restartCmd) def cmd_maps(self, data, client=None, cmd=None): """\ - list the server's map rotation for cod7, optionally limit the number in the list """ if not self._adminPlugin.aquireCmdLock(cmd, client, 60, True): client.message('^7Do not spam commands') return m = self._adminPlugin.parseUserCmd(data) if m: try: limitno = int(m[0]) except: limitno = 1000 else: limitno = 1000 if self._randomizerotation: rotation = self._cod7MapRotation[0:limitno] else: if limitno == 1000: rotation = self._cod7MapRotationFixed else: rotation = self._cod7MapRotation[0:limitno] maplist = '' for maps in rotation: mapeasyname = self.getcod7mapeasyname(maps[1]) maplist = maplist + mapeasyname + '^7-^3' + maps[0] + ' ^2' if len(maplist) > 0: cmd.sayLoudOrPM(client, '^7Map Rotation: ^2%s' % maplist) else: client.message('^7Error: could not get map list') def cmd_nextmap(self, data, client=None, cmd=None): """\ - list the next map in rotation for cod7 """ if not self._adminPlugin.aquireCmdLock(cmd, client, 60, True): client.message('^7Do not spam commands') return map = self._nextmap7 if map: mapeasyname = self.getcod7mapeasyname(map[1]) if map[0] == 'koth': gt = 'hq' else: gt = map[0] cmd.sayLoudOrPM(client, '^7Next Map: ^2%s with ^3%s^2 gametype' % (mapeasyname, gt)) else: client.message('^7Error: could not get map name') def cmd_map(self, data, client=None, cmd=None): """\ - switch what the next map and gametype is for cod7 """ #m = self._adminPlugin.parseUserCmd(data) m = data.split(' ') self.debug(m) gt = m[-1] map = string.join(m[0:-1]) self.debug('Result is map %s gametype %s' % (map, gt)) map = map.lower() if (map not in self._cod7Maps) and (map not in self._cod7Mapeasynameslower): client.message('^7You must supply a map and valid gametype to change to.') return if map in self._cod7Mapeasynameslower: maphardname = self.getcod7maphardname(map) if not gt or gt not in self._cod7Gametypes or gt not in self._cod7Playlists[self._slot_num][self._game_mode]: client.message('^7You must supply a valid gametype to change to.') return # Set the playlist thus changing the gametype if gt == 'hq': gt = 'koth' self._outofrotation = True self._nextmap7 = [gt, maphardname] if gt == 'koth': gt = 'hq' client.message('^7Next map changed to ^2%s with ^3%s^2 gametype' % (map, gt)) self.cod7maprotate() def aquireCmdLock(self, cmd, client, delay, all=True): if client.maxLevel >= 20: return True elif cmd.time + delay <= self.console.time(): return True else: return False def getcod7mapeasyname(self, map): if map in self._cod7Maps: ix = self._cod7Maps.index(map) self.debug(map) return self._cod7Mapeasynames[ix] else: return 'Error' def getcod7maphardname(self, map): map = map.lower() if map in self._cod7Mapeasynameslower: ix = self._cod7Mapeasynameslower.index(map) return self._cod7Maps[ix] else: return 'Error' if __name__ == '__main__': print ('\nThis is version '+__version__+' by '+__author__+' for BigBrotherBot.\n')
  4. Glad to see that this community is still alive and strong. Can't wait to see it grow bigger! Also, I really like the new theme, it fits the essence of the community well.
  5. WUUUUUB WUUUB WUUUUUB
  6. Answer: y(x) = c_1 e^(Ei(2 log(x)))
  7. Not sure what you're trying to accomplish, but good luck with it. Couple of comments based on what I've seen so far: Following code may be a bit messy since I'm a nub: The way you've declared your class is wrong, and b3 will throw an error class PartychatPlugin(b3.plugin.Plugin): _adminPlugin = None This code is unnecessary, as you can just declare these as global variables in the beginning of the class. return int(self.value) _command = partykick _commandexec = adm kick:&&1 return: _command _commandexec import I'd remove all but the following based on what I've seen so far: import b3, re import b3.events import time Add this to your first line of the code, otherwise none of your commands will work def startup(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 our commands if 'commands' in self.config.sections(): for cmd in self.config.options('commands'): level = self.config.get('commands', cmd) sp = cmd.split('-') alias = None if len(sp) == 2: cmd, alias = sp func = self.getCmd(cmd) if func: self._adminPlugin.registerCommand(self, cmd, level, func, alias) self.debug('Started') Add this as your second function, as you can add commands by defining a function def getCmd(self, cmd): cmd = 'cmd_%s' % cmd if hasattr(self, cmd): func = getattr(self, cmd) return func return None Add this as well, this allows for interception of events called via gamelog def onEvent(self, event): """\ Handle intercepted events """ This is an example of my code from previous project: if event.type == b3.events.EVT_GAME_MAP_PREV: self.Prevmap = event.data self.Prevmapscore = self.console.getCvar('dr_info_%s' % (event.data)) self.stripscoredata(self.Prevmapscore) self.verbose("[MapSave]: Saving Scores For %s" % (str(self.Prevmap))) self.verbose("[MapSave]: Score for %s is '%s'" % (str(self.Prevmap),str(self.Prevmapscore))) if self.Prevmapscore != None: con = mdb.connect(self.Hostname,self.Username,self.Password,self.Database) cur = con.cursor() cur.execute("SELECT * FROM mapsave WHERE mapname = '%s'" % (str(self.Prevmap))); if (cur.rowcount == 0): try: cur.execute("INSERT INTO mapsave (mapname,score) VALUES ('%s','%s')" % (str(self.Prevmap),str(self.Prevmapscore))) time.sleep(10) self.console.say("[MapSave]: Successfully inserted new scores!") except: self.error('[MapSave]: Error Inserting New Scores For %s' % (str(self.Prevmap))) time.sleep(10) self.console.say("[MapSave] Encountered an error inserting new scores!") else: try: cur.execute("UPDATE mapsave SET score = '%s' WHERE mapname = '%s'" % (str(self.Prevmap),str(self.Prevmapscore))) time.sleep(10) self.console.say("[MapSave]: Successfully updated scores!") except: self.error('[MapSave]: Error Updating New Scores For %s' % (str(self.Prevmap))) time.sleep(10) self.console.say("[MapSave]: Encountered an error updating scores!") else: time.sleep(10) self.console.say("[MapSave]: There was no previous map to save or an error has occurred!") elif event.type == b3.events.b3.events.EVT_GAME_MAP_CURR: self.Currmap = event.data con = mdb.connect(self.Hostname,self.Username,self.Password,self.Database) cur = con.cursor() cur.execute("SELECT * FROM mapsave WHERE mapname = '%s'" % (str(self.Currmap))); if (cur.rowcount == 0): self.console.say("[MapSave]: No Scores For This Map. Can You Beat The Scores?") self.verbose("[MapSave]: Map %s Has No Scores" % (str(self.Currmap))) else: try: row = cur.fetchone() cmapname = str((row[1])) ckillval = str((row[2])) ckillguid = str((row[3])) ckillplayer = str((row[4])) cdeathsval = str((row[5])) cdeathsguid = str((row[6])) cdeathsplayer = str((row[7])) cheadshotsval = str((row[8])) cheadshotsguid = str((row[9])) cheadshotsplayer = str((row[10])) cscoreval = str((row[11])) cscoreguid = str((row[12])) cscoreplayer = str((row[13])) cknifesval = str((row[14])) cknifesguid = str((row[15])) cknifesplayer = str((row[16])) ctimeval = str((row[17])) ctimeguid = str((row[18])) ctimeplayer = str((row[19])) ctotal = ';kills,%s,%s,%s;deaths,%s,%s,%s;headshots,%s,%s,%s;score,%s,%s,%s;knifes,%s,%s,%s;time,%s,%s,%s' % ((killval),(killguid),(killplayer),(deathsval),(deathsguid),(deathsplayer),(headshotsval),(headshotsguid),(headshotsplayer),(scoreval),(scoreguid),(scoreplayer)(knifesval),(knifesguid),(knifesplayer),(timeval),(timeguid),(timeplayer)) self.console.write("set dr_info_%s %s" % (str(self.cmapname),str(self.ctotal))) self.verbose("[MapSave]: Map %s Has Has Scores, Getting Default Scores Ready For Map End" % (cmapname)) time.sleep(10) self.console.say("[MapSave]: Type !mapscore To View The Scores. Can You Beat The Scores?") except: self.error("[MapSave]: Something Unexpected Has Happened! Mapname:%s Scores:%s" % ((self.cmapname),(ctotal))) Add commands using the following: def cmd_site(self, data, client, cmd=None): """\ !site - What is our website """ cmd.sayLoudOrPM(client, 'Our website is www.raid-gaming.net') return True Good luck finishing the plugin!
  8. I have moved this topic to the correct location, this is mainly our fault for neglect in allowing users to post in news board.
  9. I'm coming online
  10. Best of luck guys
  11. By all means, we don't have anything against this. Hosting these servers was not for greed, as you saw we refunded everything and donated the rest to the humble bundle. This was a decision because we don't have the time or resources to keep Raid going. If you need anything email me at [email protected]
    1. Anti

      Anti

      Nub, make the !pa commands available in deathrun, need to make all burn D:

    2. Lossy
  12. Server Managers+, please check email