PDA

View Full Version : [Tutorial] [B3] Simple and Easy Command Adding!



kung foo man
21st March 2013, 17:04
Hey all,

here and then ppl want to extend B3, but there mind is blown away by all the classes and regular expressions and shit. So this will be EASY!

The most important files for us:
/home/k_basetdm_b3/b3/parsers/cod2.py is inheriting from /home/k_basetdm_b3/b3/parsers/cod.py
/home/k_basetdm_b3/b3/parsers/cod.py is inheriting from /home/k_basetdm_b3/b3/parsers/q3a/abstractParser.py

So when we open the parser for CoD2, we will just see:



__author__ = 'ThorN, ttlogic, xlr8or'
__version__ = '1.3.0'

import b3.parsers.cod
import re

class Cod2Parser(b3.parsers.cod.CodParser):
gameName = 'cod2'
IpsOnly = False
_logSync = 1 # Value for unbuffered game logging


# set exceptions for this specific version of cod2
def setVersionExceptions(self):
# this shouldn't be inherited by later parsers, so restrict to this game only
if self.gameName == 'cod2':
if self.game.shortversion == '1.0' and not self.IpsOnly:
self.warning('CoD2 version 1.0 has known limitations on Authentication! B3 will not work properly!')
if self.game.shortversion == '1.2':
# cod2 v1.2 has a bug so PBid's are 31 characters long, instead of 32, override the regexp for testing PBid's
self.debug('Overriding pbid length for cod2 v1.2 with PB!')
self._pbRegExp = re.compile(r'^[0-9a-f]{30,32}$', re.IGNORECASE) # RegExp to match a PunkBuster ID
else:
pass
else:
pass




We dont see much, huh? Because CoD2 is inhereting everything but ONE method from CoD1! So if we copy a method from CoD1-Parser to CoD2, we can easily overwrite a method. We will overwrite the method, which is PARSING THE LOGFILE. So we are at the root of B3! Lets go:

Write this in cod2.py:
You can copy it also from /home/k_basetdm_b3/b3/parsers/q3a/abstractParser.py



def getLineParts(self, line):

# this will be in b3.log:
#130321 17:13:29 INFO "STDOUT '#####BEFORE##### 1895:31 D;1350862;2;axis;Jeplaa!;;-1;world;;none;6;MOD_FALLING;none'"
#130321 17:13:29 INFO "STDOUT '\\n'"
#130321 17:13:29 INFO "STDOUT '#####AFTER##### D;1350862;2;axis;Jeplaa!;;-1;world;;none;6;MOD_FALLING;none'"

#print "#####BEFORE##### " + line
line = re.sub(self._lineClear, '', line, 1)
#print "#####AFTER##### " + line

parts = line.split(";");
self.write("say GOT B3 COMMAND! command=" + parts[0])
if parts[0] == "QUIT":
#self.write("set b3_quit 1") # this would work also, but thats not "game engine independent"
self.setCvar("b3_quit", "1")

for f in self._lineFormats:
m = re.match(f, line)
if m:
#self.debug('line matched %s' % f.pattern)
break

if m:
client = None
target = None
return (m, m.group('action').lower(), m.group('data').strip(), client, target)
elif '------' not in line:
self.verbose('line did not match format: %s' % line)


I've just added a few lines to it, so we have an example of what that method can actually do:

200

So here we saw, how easily we can write something based on a command. So what is this about?



if parts[0] == "QUIT":
#self.write("set b3_quit 1") # this would work also, but thats not "game engine independent"
self.setCvar("b3_quit", "1")


I just wanted to set a cvar, when this function is called in CoDScript:



logPrint("QUIT;\n");


So have fun extending B3 :)

Regards,
kung foo man