def setUp(self): # create a Iourt41 parser self.parser_conf = XmlConfigParser() self.parser_conf.loadFromString("""<configuration><settings name="server"><set name="game_log"></set></settings></configuration>""") self.console = Iourt41Parser(self.parser_conf) self.console.write = Mock(name="write", side_effect=write) self.console.startup() # load the admin plugin self.adminPlugin = AdminPlugin(self.console, '@b3/conf/plugin_admin.ini') self.adminPlugin.onLoadConfig() self.adminPlugin.onStartup() # make sure the admin plugin obtained by other plugins is our admin plugin when(self.console).getPlugin('admin').thenReturn(self.adminPlugin)
def setUp(self): self.parser_conf = XmlConfigParser() self.parser_conf.loadFromString("""<configuration> <settings name="server"> <set name="game_log"/> </settings> </configuration>""") self.console = Iourt41Parser(self.parser_conf) self.console.PunkBuster = None # no Punkbuster support in that game self.output_mock = mock() # simulate game server actions def write(*args, **kwargs): pretty_args = map(repr, args) + ["%s=%s" % (k, v) for k, v in kwargs.iteritems()] log.info("write(%s)" % ', '.join(pretty_args)) return self.output_mock.write(*args, **kwargs) self.console.write = write
def __new__(cls, *args, **kwargs): Iourt42Parser.patch_Clients() return Iourt41Parser.__new__(cls)
def setUp(self): with logging_disabled(): # create a Iourt41 parser self.parser_conf = XmlConfigParser() self.parser_conf.loadFromString( """<configuration><settings name="server"><set name="game_log"></set></settings></configuration>""" ) self.console = Iourt41Parser(self.parser_conf) self.console.startup() # load the admin plugin if B3version(b3_version) >= B3version("1.10dev"): admin_plugin_conf_file = '@b3/conf/plugin_admin.ini' else: admin_plugin_conf_file = '@b3/conf/plugin_admin.xml' with logging_disabled(): self.adminPlugin = AdminPlugin(self.console, admin_plugin_conf_file) self.adminPlugin.onLoadConfig() self.adminPlugin.onStartup() # make sure the admin plugin obtained by other plugins is our admin plugin when(self.console).getPlugin('admin').thenReturn(self.adminPlugin) # prepare a few players from b3.fake import FakeClient self.joe = FakeClient(self.console, name="Joe", exactName="Joe", guid="zaerezarezar", groupBits=1, team=TEAM_UNKNOWN, teamId=0, squad=0) self.simon = FakeClient(self.console, name="Simon", exactName="Simon", guid="qsdfdsqfdsqf", groupBits=0, team=TEAM_UNKNOWN, teamId=0, squad=0) self.reg = FakeClient(self.console, name="Reg", exactName="Reg", guid="qsdfdsqfdsqf33", groupBits=4, team=TEAM_UNKNOWN, teamId=0, squad=0) self.moderator = FakeClient(self.console, name="Moderator", exactName="Moderator", guid="sdf455ezr", groupBits=8, team=TEAM_UNKNOWN, teamId=0, squad=0) self.admin = FakeClient(self.console, name="Level-40-Admin", exactName="Level-40-Admin", guid="875sasda", groupBits=16, team=TEAM_UNKNOWN, teamId=0, squad=0) self.superadmin = FakeClient(self.console, name="God", exactName="God", guid="f4qfer654r", groupBits=128, team=TEAM_UNKNOWN, teamId=0, squad=0)
class Iourt42Parser(Iourt41Parser): gameName = 'iourt42' _commands = { 'broadcast': '%(prefix)s^7 %(message)s', 'message': 'tell %(cid)s %(prefix)s ^3[pm]^7 %(message)s', 'deadsay': 'tell %(cid)s %(prefix)s [DEAD]^7 %(message)s', 'say': 'say %(prefix)s %(message)s', 'saybig': 'bigtext "%(prefix)s %(message)s"', 'set': 'set %(name)s "%(value)s"', 'kick': 'kick %(cid)s "%(reason)s"', 'ban': 'addip %(cid)s', 'tempban': 'kick %(cid)s "%(reason)s"', 'banByIp': 'addip %(ip)s', 'unbanByIp': 'removeip %(ip)s', 'auth-permban': 'auth-ban %(cid)s 0 0 0', 'auth-tempban': 'auth-ban %(cid)s %(days)s %(hours)s %(minutes)s', 'slap': 'slap %(cid)s', 'nuke': 'nuke %(cid)s', 'mute': 'mute %(cid)s %(seconds)s', 'kill': 'smite %(cid)s', } _eventMap = { #'warmup' : b3.events.EVT_GAME_HOTPOTATO, #'shutdowngame' : b3.events.EVT_GAME_ROUND_END } # remove the time off of the line _lineClear = re.compile(r'^(?:[0-9:]+\s?)?') #0:00 ClientUserinfo: 0: _lineFormats = ( #Radio: 0 - 7 - 2 - "New Alley" - "I'm going for the flag" re.compile( r'''^(?P<action>Radio): (?P<data>(?P<cid>[0-9]+) - (?P<msg_group>[0-9]+) - (?P<msg_id>[0-9]+) - "(?P<location>.+)" - "(?P<text>.*)")$''' ), #Radio: 0 - 7 - 2 - "New Alley" - "I'm going for the flag" re.compile( r'''^(?P<action>Radio): (?P<data>(?P<cid>[0-9]+) - (?P<msg_group>[0-9]+) - (?P<msg_id>[0-9]+) - "(?P<location>.+)" - "(?P<text>.*)")$''' ), #Callvote: 1 - "map dressingroom" re.compile( r'''^(?P<action>Callvote): (?P<data>(?P<cid>[0-9]+) - "(?P<vote_string>.*)")$''' ), #Vote: 0 - 2 re.compile( r'''^(?P<action>Vote): (?P<data>(?P<cid>[0-9]+) - (?P<value>.*))$''' ), #13:34 ClientJumpTimerStarted: 0 - way: 2 (Easy Way) re.compile( r'^(?P<action>ClientJumpTimerStarted):\s(?P<cid>\d+)\s-\s(?P<data>way: (?P<way_id>\d+)(?:\s\((?P<way_label>.+)\))?)$', re.IGNORECASE), #13:34 ClientJumpTimerStopped: 0 - 5 seconds - way: 1 (Hard Way) re.compile( r'^(?P<action>ClientJumpTimerStopped):\s(?P<cid>\d+)\s-\s(?P<data>(?P<duration>.+)\s-\sway: (?P<way_id>\d+)(?:\s\((?P<way_label>.+)\))?)$', re.IGNORECASE), #13:34 ClientSavePosition: 0 - 335.384887 - 67.469154 - -23.875000 - "unknown" #13:34 ClientLoadPosition: 0 - 335.384887 - 67.469154 - -23.875000 - "unknown" re.compile( r'^(?P<action>Client(Save|Load)Position):\s(?P<cid>\d+)\s-\s(?P<data>(?P<x>-?\d+(?:\.\d+)?)\s-\s(?P<y>-?\d+(?:\.\d+)?)\s-\s(?P<z>-?\d+(?:\.\d+)?)\s-\s"(?P<name>.*)")$', re.IGNORECASE), #Generated with ioUrbanTerror v4.1: #Hit: 12 7 1 19: BSTHanzo[FR] hit ercan in the Helmet #Hit: 13 10 0 8: Grover hit jacobdk92 in the Head re.compile( r'^(?P<action>Hit):\s(?P<data>(?P<cid>[0-9]+)\s(?P<acid>[0-9]+)\s(?P<hitloc>[0-9]+)\s(?P<aweap>[0-9]+):\s+(?P<text>.*))$', re.IGNORECASE), #re.compile(r'^(?P<action>[a-z]+):\s(?P<data>(?P<cid>[0-9]+)\s(?P<acid>[0-9]+)\s(?P<hitloc>[0-9]+)\s(?P<aweap>[0-9]+):\s+(?P<text>(?P<aname>[^:])\shit\s(?P<name>[^:])\sin\sthe(?P<locname>.*)))$', re.IGNORECASE), #6:37 Kill: 0 1 16: XLR8or killed =lvl1=Cheetah by UT_MOD_SPAS #2:56 Kill: 14 4 21: Qst killed Leftovercrack by UT_MOD_PSG1 re.compile( r'^(?P<action>[a-z]+):\s(?P<data>(?P<acid>[0-9]+)\s(?P<cid>[0-9]+)\s(?P<aweap>[0-9]+):\s+(?P<text>.*))$', re.IGNORECASE), #re.compile(r'^(?P<action>[a-z]+):\s(?P<data>(?P<acid>[0-9]+)\s(?P<cid>[0-9]+)\s(?P<aweap>[0-9]+):\s+(?P<text>(?P<aname>[^:])\skilled\s(?P<name>[^:])\sby\s(?P<modname>.*)))$', re.IGNORECASE), #Processing chats and tell events... #5:39 saytell: 15 16 repelSteeltje: nno #5:39 saytell: 15 15 repelSteeltje: nno re.compile( r'^(?P<action>[a-z]+):\s(?P<data>(?P<cid>[0-9]+)\s(?P<acid>[0-9]+)\s(?P<name>.+?):\s+(?P<text>.*))$', re.IGNORECASE), # We're not using tell in this form so this one is disabled #5:39 tell: repelSteeltje to B!K!n1: nno #re.compile(r'^(?P<action>[a-z]+):\s+(?P<data>(?P<name>[^:]+)\s+to\s+(?P<aname>[^:]+):\s+(?P<text>.*))$', re.IGNORECASE), #3:53 say: 8 denzel: lol #15:37 say: 9 .:MS-T:.BstPL: this name is quite a challenge #2:28 sayteam: 12 New_UrT_Player_v4.1: woekele #16:33 Flag: 2 0: team_CTF_redflag #re.compile(r'^(?P<action>[a-z]+):\s(?P<data>(?P<cid>[0-9]+)\s(?P<name>[^ ]+):\s+(?P<text>.*))$', re.IGNORECASE), # SGT: fix issue with OnSay when something like this come and the match could'nt find the name group # say: 7 -crespino-: # say: 6 ^5Marcel ^2[^6CZARMY^2]: !help re.compile( r'^(?P<action>[a-z]+):\s(?P<data>(?P<cid>[0-9]+)\s(?P<name>.+?):\s*(?P<text>.*))$', re.IGNORECASE), #15:42 Flag Return: RED #15:42 Flag Return: BLUE re.compile(r'^(?P<action>Flag Return):\s(?P<data>(?P<color>.+))$', re.IGNORECASE), #Bombmode actions: #3:06 Bombholder is 2 re.compile(r'^(?P<action>Bombholder)(?P<data>\sis\s(?P<cid>[0-9]))$', re.IGNORECASE), #was planted, was defused, was tossed, has been collected (doh, how gramatically correct!) #2:13 Bomb was tossed by 2 #2:32 Bomb was planted by 2 #3:01 Bomb was defused by 3! #2:17 Bomb has been collected by 2 re.compile( r'^(?P<action>Bomb)\s(?P<data>(was|has been)\s(?P<subaction>[a-z]+)\sby\s(?P<cid>[0-9]+).*)$', re.IGNORECASE), #Falling thru? Item stuff and so forth re.compile(r'^(?P<action>[a-z]+):\s(?P<data>.*)$', re.IGNORECASE), #Shutdowngame and Warmup... the one word lines re.compile(r'^(?P<action>[a-z]+):$', re.IGNORECASE)) # map: ut4_casa # num score ping name lastmsg address qport rate # --- ----- ---- --------------- ------- --------------------- ----- ----- # 2 0 19 ^1XLR^78^8^9or^7 0 145.99.135.227:27960 41893 8000 # player with a live ping # 4 0 CNCT Dz!k^7 450 83.175.191.27:64459 50308 20000 # connecting player (or inbetween rounds) # 9 0 ZMBI ^7 1900 81.178.80.68:27960 10801 8000 # zombies (need to be disconnected!) _regPlayer = re.compile( r'^(?P<slot>[0-9]+)\s+(?P<score>[0-9-]+)\s+(?P<ping>[0-9]+|CNCT|ZMBI)\s+(?P<name>.*?)\s+(?P<last>[0-9]+)\s+(?P<ip>[0-9.]+):(?P<port>[0-9-]+)\s+(?P<qport>[0-9]+)\s+(?P<rate>[0-9]+)$', re.I) _reColor = re.compile(r'(\^.)|[\x00-\x20]|[\x7E-\xff]') # Map: ut4_algiers # Players: 8 # Scores: R:97 B:98 # 0: FREE k:0 d:0 ping:0 # 4: yene RED k:16 d:8 ping:50 92.104.110.192:63496 _reTeamScores = re.compile( r'^Scores:\s+R:(?P<RedScore>.+)\s+B:(?P<BlueScore>.+)$', re.I) _rePlayerScore = re.compile( r'^(?P<slot>[0-9]+): (?P<name>.*) (?P<team>RED|BLUE|SPECTATOR|FREE) k:(?P<kill>[0-9]+) d:(?P<death>[0-9]+) ping:(?P<ping>[0-9]+|CNCT|ZMBI)( (?P<ip>[0-9.]+):(?P<port>[0-9-]+))?$', re.I ) # NOTE: this won't work properly if the server has private slots. see http://forums.urbanterror.net/index.php/topic,9356.0.html # /rcon auth-whois replies patterns _re_authwhois = re.compile( r"""^auth: id: (?P<cid>\d+) - name: \^7(?P<name>.+?) - login: (?P<login>.*?) - notoriety: (?P<notoriety>.+?) - level: (?P<level>-?\d+?)(?:\s+- (?P<extra>.*))?$""", re.MULTILINE) _permban_with_frozensand = False _tempban_with_frozensand = False ## kill modes MOD_WATER = '1' MOD_LAVA = '3' MOD_TELEFRAG = '5' MOD_FALLING = '6' MOD_SUICIDE = '7' MOD_TRIGGER_HURT = '9' MOD_CHANGE_TEAM = '10' UT_MOD_KNIFE = '12' UT_MOD_KNIFE_THROWN = '13' UT_MOD_BERETTA = '14' UT_MOD_DEAGLE = '15' UT_MOD_SPAS = '******' UT_MOD_UMP45 = '17' UT_MOD_MP5K = '18' UT_MOD_LR300 = '19' UT_MOD_G36 = '20' UT_MOD_PSG1 = '21' UT_MOD_HK69 = '22' UT_MOD_BLED = '23' UT_MOD_KICKED = '24' # not exising in 4.2 ? UT_MOD_HEGRENADE = '25' UT_MOD_SR8 = '27' UT_MOD_AK103 = '29' UT_MOD_SPLODED = '30' UT_MOD_SLAPPED = '31' UT_MOD_SMITED = '32' UT_MOD_BOMBED = '33' UT_MOD_NUKED = '34' UT_MOD_NEGEV = '35' UT_MOD_HK69_HIT = '36' UT_MOD_M4 = '37' UT_MOD_GLOCK = '38' UT_MOD_FLAG = '39' UT_MOD_GOOMBA = '40' ## weapons id on Hit: lines are different than the one ## on the Kill: lines. Here the translation table hitweapon2killweapon = { 1: UT_MOD_KNIFE, 2: UT_MOD_BERETTA, 3: UT_MOD_DEAGLE, 4: UT_MOD_SPAS, 5: UT_MOD_MP5K, 6: UT_MOD_UMP45, 8: UT_MOD_LR300, 9: UT_MOD_G36, 10: UT_MOD_PSG1, 14: UT_MOD_SR8, 15: UT_MOD_AK103, 17: UT_MOD_NEGEV, 19: UT_MOD_M4, 20: UT_MOD_GLOCK, 23: UT_MOD_KNIFE_THROWN, } def __new__(cls, *args, **kwargs): Iourt42Parser.patch_Clients() return Iourt41Parser.__new__(cls) def startup(self): try: gamename = self.getCvar('gamename').getString() if gamename != 'q3urt42': self.error( "the iourt42 B3 parser cannot be used with a game server other than Urban Terror 4.2" ) raise SystemExit(220) except Exception, e: self.warning("Could not query server for gamename.", exc_info=e) Iourt41Parser.startup(self) # add UrT 4.2 specific events self.EVT_CLIENT_RADIO = self.Events.createEvent( 'EVT_CLIENT_RADIO', 'Event client radio') self.EVT_GAME_FLAG_HOTPOTATO = self.Events.createEvent( 'EVT_GAME_FLAG_HOTPOTATO', 'Event game hotpotato') self._eventMap['hotpotato'] = self.EVT_GAME_FLAG_HOTPOTATO self.EVT_CLIENT_CALLVOTE = self.Events.createEvent( 'EVT_CLIENT_CALLVOTE', 'Event client call vote') self.EVT_CLIENT_VOTE = self.Events.createEvent('EVT_CLIENT_VOTE', 'Event client vote') self.EVT_CLIENT_JUMP_TIMER_START = self.Events.createEvent( 'EVT_CLIENT_JUMP_TIMER_START', 'Event client jump timer started') self.EVT_CLIENT_JUMP_TIMER_STOP = self.Events.createEvent( 'EVT_CLIENT_JUMP_TIMER_STOP', 'Event client jump timer stopped') self.EVT_CLIENT_POS_SAVE = self.Events.createEvent( 'EVT_CLIENT_POS_SAVE', 'Event client position saved') self.EVT_CLIENT_POS_LOAD = self.Events.createEvent( 'EVT_CLIENT_POS_LOAD', 'Event client position loaded') self.EVT_CLIENT_SURVIVOR_WINNER = self.Events.createEvent( 'EVT_CLIENT_SURVIVOR_WINNER', 'Event client survivor winner') self.load_conf_frozensand_ban_settings()
class Iourt42Parser(Iourt41Parser): gameName = 'iourt42' _commands = { 'broadcast': '%(prefix)s^7 %(message)s', 'message': 'tell %(cid)s %(prefix)s ^3[pm]^7 %(message)s', 'deadsay': 'tell %(cid)s %(prefix)s [DEAD]^7 %(message)s', 'say': 'say %(prefix)s %(message)s', 'saybig': 'bigtext "%(prefix)s %(message)s"', 'set': 'set %(name)s "%(value)s"', 'kick': 'kick %(cid)s "%(reason)s"', 'ban': 'addip %(cid)s', 'tempban': 'kick %(cid)s "%(reason)s"', 'banByIp': 'addip %(ip)s', 'unbanByIp': 'removeip %(ip)s', 'slap': 'slap %(cid)s', 'nuke': 'nuke %(cid)s', 'mute': 'mute %(cid)s %(seconds)s', 'kill': 'smite %(cid)s', } _eventMap = { #'warmup' : b3.events.EVT_GAME_HOTPOTATO, #'shutdowngame' : b3.events.EVT_GAME_ROUND_END } # remove the time off of the line _lineClear = re.compile(r'^(?:[0-9:]+\s?)?') #0:00 ClientUserinfo: 0: _lineFormats = ( #Radio: 0 - 7 - 2 - "New Alley" - "I'm going for the flag" re.compile( r'''^(?P<action>Radio): (?P<data>(?P<cid>[0-9]+) - (?P<msg_group>[0-9]+) - (?P<msg_id>[0-9]+) - "(?P<location>.+)" - "(?P<text>.*)")$''' ), #Radio: 0 - 7 - 2 - "New Alley" - "I'm going for the flag" re.compile( r'''^(?P<action>Radio): (?P<data>(?P<cid>[0-9]+) - (?P<msg_group>[0-9]+) - (?P<msg_id>[0-9]+) - "(?P<location>.+)" - "(?P<text>.*)")$''' ), #Callvote: 1 - "map dressingroom" re.compile( r'''^(?P<action>Callvote): (?P<data>(?P<cid>[0-9]+) - "(?P<vote_string>.*)")$''' ), #Vote: 0 - 2 re.compile( r'''^(?P<action>Vote): (?P<data>(?P<cid>[0-9]+) - (?P<value>.*))$''' ), #Generated with ioUrbanTerror v4.1: #Hit: 12 7 1 19: BSTHanzo[FR] hit ercan in the Helmet #Hit: 13 10 0 8: Grover hit jacobdk92 in the Head re.compile( r'^(?P<action>Hit):\s(?P<data>(?P<cid>[0-9]+)\s(?P<acid>[0-9]+)\s(?P<hitloc>[0-9]+)\s(?P<aweap>[0-9]+):\s+(?P<text>.*))$', re.IGNORECASE), #re.compile(r'^(?P<action>[a-z]+):\s(?P<data>(?P<cid>[0-9]+)\s(?P<acid>[0-9]+)\s(?P<hitloc>[0-9]+)\s(?P<aweap>[0-9]+):\s+(?P<text>(?P<aname>[^:])\shit\s(?P<name>[^:])\sin\sthe(?P<locname>.*)))$', re.IGNORECASE), #6:37 Kill: 0 1 16: XLR8or killed =lvl1=Cheetah by UT_MOD_SPAS #2:56 Kill: 14 4 21: Qst killed Leftovercrack by UT_MOD_PSG1 re.compile( r'^(?P<action>[a-z]+):\s(?P<data>(?P<acid>[0-9]+)\s(?P<cid>[0-9]+)\s(?P<aweap>[0-9]+):\s+(?P<text>.*))$', re.IGNORECASE), #re.compile(r'^(?P<action>[a-z]+):\s(?P<data>(?P<acid>[0-9]+)\s(?P<cid>[0-9]+)\s(?P<aweap>[0-9]+):\s+(?P<text>(?P<aname>[^:])\skilled\s(?P<name>[^:])\sby\s(?P<modname>.*)))$', re.IGNORECASE), #Processing chats and tell events... #5:39 saytell: 15 16 repelSteeltje: nno #5:39 saytell: 15 15 repelSteeltje: nno re.compile( r'^(?P<action>[a-z]+):\s(?P<data>(?P<cid>[0-9]+)\s(?P<acid>[0-9]+)\s(?P<name>[^ ]+):\s+(?P<text>.*))$', re.IGNORECASE), # We're not using tell in this form so this one is disabled #5:39 tell: repelSteeltje to B!K!n1: nno #re.compile(r'^(?P<action>[a-z]+):\s+(?P<data>(?P<name>[^:]+)\s+to\s+(?P<aname>[^:]+):\s+(?P<text>.*))$', re.IGNORECASE), #3:53 say: 8 denzel: lol #15:37 say: 9 .:MS-T:.BstPL: this name is quite a challenge #2:28 sayteam: 12 New_UrT_Player_v4.1: woekele #16:33 Flag: 2 0: team_CTF_redflag #re.compile(r'^(?P<action>[a-z]+):\s(?P<data>(?P<cid>[0-9]+)\s(?P<name>[^ ]+):\s+(?P<text>.*))$', re.IGNORECASE), # SGT: fix issue with OnSay when something like this come and the match could'nt find the name group # say: 7 -crespino-: re.compile( r'^(?P<action>[a-z]+):\s(?P<data>(?P<cid>[0-9]+)\s(?P<name>[^ ]+):\s*(?P<text>.*))$', re.IGNORECASE), #15:42 Flag Return: RED #15:42 Flag Return: BLUE re.compile(r'^(?P<action>Flag Return):\s(?P<data>(?P<color>.+))$', re.IGNORECASE), #Bombmode actions: #3:06 Bombholder is 2 re.compile(r'^(?P<action>Bombholder)(?P<data>\sis\s(?P<cid>[0-9]))$', re.IGNORECASE), #was planted, was defused, was tossed, has been collected (doh, how gramatically correct!) #2:13 Bomb was tossed by 2 #2:32 Bomb was planted by 2 #3:01 Bomb was defused by 3! #2:17 Bomb has been collected by 2 re.compile( r'^(?P<action>Bomb)\s(?P<data>(was|has been)\s(?P<subaction>[a-z]+)\sby\s(?P<cid>[0-9]+).*)$', re.IGNORECASE), #Falling thru? Item stuff and so forth re.compile(r'^(?P<action>[a-z]+):\s(?P<data>.*)$', re.IGNORECASE), #Shutdowngame and Warmup... the one word lines re.compile(r'^(?P<action>[a-z]+):$', re.IGNORECASE)) # map: ut4_casa # num score ping name lastmsg address qport rate # --- ----- ---- --------------- ------- --------------------- ----- ----- # 2 0 19 ^1XLR^78^8^9or^7 0 145.99.135.227:27960 41893 8000 # player with a live ping # 4 0 CNCT Dz!k^7 450 83.175.191.27:64459 50308 20000 # connecting player (or inbetween rounds) # 9 0 ZMBI ^7 1900 81.178.80.68:27960 10801 8000 # zombies (need to be disconnected!) _regPlayer = re.compile( r'^(?P<slot>[0-9]+)\s+(?P<score>[0-9-]+)\s+(?P<ping>[0-9]+|CNCT|ZMBI)\s+(?P<name>.*?)\s+(?P<last>[0-9]+)\s+(?P<ip>[0-9.]+):(?P<port>[0-9-]+)\s+(?P<qport>[0-9]+)\s+(?P<rate>[0-9]+)$', re.I) _reColor = re.compile(r'(\^.)|[\x00-\x20]|[\x7E-\xff]') # Map: ut4_algiers # Players: 8 # Scores: R:97 B:98 # 0: FREE k:0 d:0 ping:0 # 4: yene RED k:16 d:8 ping:50 92.104.110.192:63496 _reTeamScores = re.compile( r'^Scores:\s+R:(?P<RedScore>.+)\s+B:(?P<BlueScore>.+)$', re.I) _rePlayerScore = re.compile( r'^(?P<slot>[0-9]+): (?P<name>.*) (?P<team>RED|BLUE|SPECTATOR|FREE) k:(?P<kill>[0-9]+) d:(?P<death>[0-9]+) ping:(?P<ping>[0-9]+|CNCT|ZMBI)( (?P<ip>[0-9.]+):(?P<port>[0-9-]+))?$', re.I ) # NOTE: this won't work properly if the server has private slots. see http://forums.urbanterror.net/index.php/topic,9356.0.html # /rcon auth-whois replies patterns _re_authwhois = re.compile( r"""^auth: id: (?P<cid>\d+) - name: \^7(?P<name>.+?) - login: (?P<login>.*?) - notoriety: (?P<notoriety>.+?) - level: (?P<level>-?\d+?)(?:\s+- (?P<extra>.*))?$""", re.MULTILINE) def __new__(cls, *args, **kwargs): Iourt42Parser.patch_Clients() return Iourt41Parser.__new__(cls) def startup(self): try: gamename = self.getCvar('gamename').getString() if gamename != 'q3urt42': self.error( "the iourt42 B3 parser cannot be used with a game server other than Urban Terror 4.2" ) raise SystemExit(220) except Exception, e: self.warning("Could not query server for gamename.", exc_info=e) Iourt41Parser.startup(self) # add UrT 4.2 specific events self.EVT_CLIENT_RADIO = self.Events.createEvent( 'EVT_CLIENT_RADIO', 'Event client radio') self.EVT_GAME_FLAG_HOTPOTATO = self.Events.createEvent( 'EVT_GAME_FLAG_HOTPOTATO', 'Event game hotpotato') self._eventMap['hotpotato'] = self.EVT_GAME_FLAG_HOTPOTATO self.EVT_CLIENT_CALLVOTE = self.Events.createEvent( 'EVT_CLIENT_CALLVOTE', 'Event client call vote') self.EVT_CLIENT_VOTE = self.Events.createEvent('EVT_CLIENT_VOTE', 'Event client vote')
def setUp(self): with logging_disabled(): # create a Iourt41 parser self.parser_conf = XmlConfigParser() self.parser_conf.loadFromString( """<configuration><settings name="server"><set name="game_log"></set></settings></configuration>""" ) self.console = Iourt41Parser(self.parser_conf) self.console.startup() # load the admin plugin if B3version(b3_version) >= B3version("1.10dev"): admin_plugin_conf_file = '@b3/conf/plugin_admin.ini' else: admin_plugin_conf_file = '@b3/conf/plugin_admin.xml' with logging_disabled(): self.adminPlugin = AdminPlugin(self.console, admin_plugin_conf_file) self.adminPlugin.onStartup() # make sure the admin plugin obtained by other plugins is our admin plugin when(self.console).getPlugin('admin').thenReturn(self.adminPlugin) # when starting the PoweradminurtPlugin expects the game server to provide a few cvar values when(self.console).getCvar('timelimit').thenReturn( Cvar('timelimit', value=20)) when(self.console).getCvar('g_maxGameClients').thenReturn( Cvar('g_maxGameClients', value=16)) when(self.console).getCvar('sv_maxclients').thenReturn( Cvar('sv_maxclients', value=16)) when(self.console).getCvar('sv_privateClients').thenReturn( Cvar('sv_privateClients', value=0)) when(self.console).getCvar('g_allowvote').thenReturn( Cvar('g_allowvote', value=0)) # prepare a few players self.joe = FakeClient(self.console, name="Joe", exactName="Joe", guid="zaerezarezar", groupBits=1, team=TEAM_UNKNOWN, teamId=0, squad=0) self.simon = FakeClient(self.console, name="Simon", exactName="Simon", guid="qsdfdsqfdsqf", groupBits=0, team=TEAM_UNKNOWN, teamId=0, squad=0) self.reg = FakeClient(self.console, name="Reg", exactName="Reg", guid="qsdfdsqfdsqf33", groupBits=4, team=TEAM_UNKNOWN, teamId=0, squad=0) self.moderator = FakeClient(self.console, name="Moderator", exactName="Moderator", guid="sdf455ezr", groupBits=8, team=TEAM_UNKNOWN, teamId=0, squad=0) self.admin = FakeClient(self.console, name="Level-40-Admin", exactName="Level-40-Admin", guid="875sasda", groupBits=16, team=TEAM_UNKNOWN, teamId=0, squad=0) self.superadmin = FakeClient(self.console, name="God", exactName="God", guid="f4qfer654r", groupBits=128, team=TEAM_UNKNOWN, teamId=0, squad=0)