This example shows how to mod a BombSquad server to add a ‘total kills’ stat which keeps a permanent record of kills for each account that plays on it, as well as a webpage for viewing top kill counts.
The example uses BombSquad version 1.4.143; your mileage may vary on older or newer versions.
Anyway, let’s do it:
- Grab the sample code from the bottom of this page, save it to a file called ‘mystats.py’ in the scripts directory of your bombsquad server
- change the ‘statsfile’ and ‘htmlfile’ paths at the top of the script to wherever you want your stats to go
- add the following few lines in bsGame.py in ScoreScreenActivity’s onBegin() method. (should be about line 1904 in the latest 1.4.143 builds)
That should do it. If you do this correctly, your server should print ‘Added X kill entries‘ to the terminal at the end of each round. You should also wind up with a json file containing a running tally of kills per account along with html snippets to display each account’s name. (the same name they show up on league lists as).
It also writes out an html file showing all names sorted by total kill-count.
..so if you wire up your server to dump this out somewhere world-accessible, you can then set your server’s stat button to point at that url so everyone can see who is the most awesomest dude on your server at any time. (see this post about the new stats button option)
Note that this code is pretty bare-bones; it could use some error-checking and of course more features, but I wanted to keep it simple and hopefully readable to use as a starting point. Have a look through it, see what its doing, and then feel free to modify it to do something fancier if you’d like.
Some ideas for improvements as an exercise for the reader:
- perhaps resetting the kill-count once per day or once per week
- capturing other stats besides just kills
- if your server gets a lot of players you may want to prune scores or only display the top 100 or something to that effect (or get really fancy and wire it up to a proper database instead of a json file)
- A not-ultra-ugly-looking top kills page
Anyway, I hope this is useful. Happy hacking!
""" mystats module for BombSquad version 1.4.143 Provides functionality for dumping player stats to disk between rounds. To use this, add the following 2 lines to bsGame.ScoreScreenActivity.onBegin(): import mystats mystats.update(self.scoreSet) """ import threading import json import os import urllib2 # where our stats file and pretty html output will go statsfile = '/path/to/my/stats.json' htmlfile = '/path/to/my/statspage.html' def update(score_set): """ Given a Session's ScoreSet, tallies per-account kills and passes them to a background thread to process and store. """ # look at score-set entries to tally per-account kills for this round account_kills = {} for p_entry in score_set.getValidPlayers().values(): account_id = p_entry.getPlayer().get_account_id() if account_id is not None: account_kills.setdefault(account_id, 0) # make sure exists account_kills[account_id] += p_entry.accumKillCount # Ok; now we've got a dict of account-ids and kills. # Now lets kick off a background thread to load existing scores # from disk, do display-string lookups for accounts that need them, # and write everything back to disk (along with a pretty html version) # We use a background thread so our server doesn't hitch while doing this. UpdateThread(account_kills).start() class UpdateThread(threading.Thread): def __init__(self, account_kills): threading.Thread.__init__(self) self._account_kills = account_kills def run(self): # pull our existing stats from disk if os.path.exists(statsfile): with open(statsfile) as f: stats = json.loads(f.read()) else: stats = {} # now add this batch of kills to our persistant stats for account_id, kill_count in self._account_kills.items(): # add a new entry for any accounts that dont have one if account_id not in stats: # also lets ask the master-server for their account-display-str. # (we only do this when first creating the entry to save time, # though it may be smart to refresh it periodically since # it may change) url = 'http://bombsquadgame.com/accountquery?id=' + account_id response = json.loads( urllib2.urlopen(urllib2.Request(url)).read()) name_html = response['name_html'] stats[account_id] = {'kills': 0, 'name_html': name_html} # now increment their kills whether they were already there or not stats[account_id]['kills'] += kill_count # dump our stats back to disk with open(statsfile, 'w') as f: f.write(json.dumps(stats)) # lastly, write a pretty html version. # our stats url could point at something like this... entries = [(a['kills'], a['name_html']) for a in stats.values()] # this gives us a list of kills/names sorted high-to-low entries.sort(reverse=True) with open(htmlfile, 'w') as f: f.write('<head><meta charset="UTF-8"></head><body>') for entry in entries: kills = str(entry[0]) name = entry[1].encode('utf-8') f.write(kills + ' kills : ' + name + '<br>') f.write('</body>') # aaand that's it! There IS no step 27! print 'Added', len(self._account_kills), 'kill entries.'