diff --git a/game.py b/game.py index 45ae28b..5104226 100755 --- a/game.py +++ b/game.py @@ -96,6 +96,7 @@ class Manager: if now > self.last_beat + pulse: for game in list(self.games): game.heartbeat(now) + self.last_beat = now for event in self.timers: when, cb = event if now >= when: @@ -373,6 +374,7 @@ class TurnBasedGame(Game): Game.__init__(self, manager, players) def heartbeat(self, now=None): + print('heart', self) if now and (now - self.began > self.game_timeout): self.running = False diff --git a/points.py b/points.py index 10cadff..a88e7cd 100755 --- a/points.py +++ b/points.py @@ -88,7 +88,7 @@ def incdict(dict, key, amt=1): dict[key] = dict.get(key, 0) + amt class Storage: - def __init__(self, fn): + def __init__(self, fn='/var/lib/ctf/points.dat'): self.points_by_team = {} self.points_by_cat = {} self.points_by_cat_team = {} diff --git a/pointscli.py b/pointscli.py index c43a534..d32b0a1 100755 --- a/pointscli.py +++ b/pointscli.py @@ -13,7 +13,7 @@ def makesock(host): def submit(cat, team, score, sock=None): if not sock: - sock = makesock('cfl-sunray1') + sock = makesock('localhost') begin = time.time() mark = int(begin) req = points.encode_request(1, mark, cat, team, score) diff --git a/pointsd.py b/pointsd.py index 3ec0e63..bbb0878 100755 --- a/pointsd.py +++ b/pointsd.py @@ -13,7 +13,7 @@ class MyHandler(asyncore.dispatcher): asyncore.dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_DGRAM) self.bind(('', port)) - self.store = points.Storage('scores.dat') + self.store = points.Storage() self.acked = set() self.outq = [] diff --git a/puzzler.cgi b/puzzler.cgi index a228e0c..290d8d8 100755 --- a/puzzler.cgi +++ b/puzzler.cgi @@ -8,6 +8,7 @@ import re import sys import pointscli import teams +import http.cookies from urllib.parse import quote, unquote ## @@ -27,7 +28,7 @@ def dbg(*vals): points_by_cat = {} points_by_team = {} try: - for line in open('puzzler.dat'): + for line in open('/var/lib/ctf/puzzler.dat'): cat, team, pts = [unquote(v) for v in line.strip().split('\t')] pts = int(pts) points_by_cat[cat] = max(points_by_cat.get(cat, 0), pts) @@ -36,20 +37,33 @@ except IOError: pass -f = cgi.FieldStorage() +c = http.cookies.SimpleCookie(os.environ.get('HTTP_COOKIE', '')) +try: + team = c['team'].value + passwd = c['passwd'].value +except KeyError: + team, passwd = None, None +f = cgi.FieldStorage() cat = f.getfirst('c') points = f.getfirst('p') -team = f.getfirst('t') -passwd = f.getfirst('w') +team = f.getfirst('t', team) +passwd = f.getfirst('w', passwd) key = f.getfirst('k') verboten = ['key', 'index.html'] def start_html(title): - print('''Content-type: text/html - - + print('Content-type: text/html') + if team or passwd: + c = http.cookies.SimpleCookie() + if team: + c['team'] = team + if passwd: + c['passwd'] = passwd + print(c) + print() + print(''' @@ -111,9 +125,9 @@ def show_puzzles(cat, cat_dir): print('

None (someone is slacking)

') end_html() -def show_puzzle(cat, points, points_dir, team, passwd): +def show_puzzle(cat, points, points_dir, team='', passwd=''): # Show puzzle in cat for points - start_html('%s for %s' % (cat, points)) + start_html('%s for %s points' % (cat, points)) fn = os.path.join(points_dir, 'index.html') if os.path.exists(fn): print('
') @@ -139,10 +153,11 @@ def win(cat, team, points): start_html('Winner!') points = int(points) f = open('puzzler.dat', 'a') + pointscli.submit(cat, team, points) fcntl.lockf(f, fcntl.LOCK_EX) f.write('%s\t%s\t%d\n' % (quote(cat), quote(team), points)) - pointscli.submit(cat, team, points) - print('

%d points for %s.

' % (team, points)) + print('

%d points for %s.

' % (points, team)) + print('

Back to %s.

' % (cat, cat)) end_html() def main(): @@ -168,16 +183,24 @@ def main(): else: show_puzzle(cat, points, points_dir, team, passwd) else: - thekey = open('%s/key' % points_dir).read().strip() + try: + thekey = open('%s/key' % points_dir, encoding='utf-8').read().strip() + except IOError: + # If there's no key, this can never be solved. + thekey = False if not teams.chkpasswd(team, passwd): start_html('Wrong password') end_html() elif key != thekey: - show_puzzle(cat, points, points_dir) - elif points_by_team.get((team, cat)): + show_puzzle(cat, points, points_dir, team, passwd) + elif int(points) in points_by_team.get((team, cat), set()): start_html('Greedy greedy') end_html() else: win(cat, team, points) main() + +# Local Variables: +# mode: python +# End: diff --git a/puzzles/sequence/3/index.html b/puzzles/sequence/19/index.html similarity index 100% rename from puzzles/sequence/3/index.html rename to puzzles/sequence/19/index.html diff --git a/puzzles/sequence/3/key b/puzzles/sequence/19/key similarity index 100% rename from puzzles/sequence/3/key rename to puzzles/sequence/19/key diff --git a/puzzles/sequence/2/index.html b/puzzles/sequence/2/index.html index 4cca390..6f6fa3b 100644 --- a/puzzles/sequence/2/index.html +++ b/puzzles/sequence/2/index.html @@ -1 +1 @@ -2 4 6 8 10 _ +1 10 11 101 110 _ _ diff --git a/puzzles/sequence/2/key b/puzzles/sequence/2/key index 48082f7..9c657f0 100644 --- a/puzzles/sequence/2/key +++ b/puzzles/sequence/2/key @@ -1 +1 @@ -12 +111 1000 diff --git a/puzzles/sequence/4/index.html b/puzzles/sequence/25/index.html similarity index 100% rename from puzzles/sequence/4/index.html rename to puzzles/sequence/25/index.html diff --git a/puzzles/sequence/4/key b/puzzles/sequence/25/key similarity index 100% rename from puzzles/sequence/4/key rename to puzzles/sequence/25/key diff --git a/puzzles/sequence/300/key b/puzzles/sequence/300/key index 0b8e449..4e818df 100644 --- a/puzzles/sequence/300/key +++ b/puzzles/sequence/300/key @@ -1 +1 @@ -┴ +┤ diff --git a/puzzles/sequence/5/index.html b/puzzles/sequence/35/index.html similarity index 100% rename from puzzles/sequence/5/index.html rename to puzzles/sequence/35/index.html diff --git a/puzzles/sequence/5/key b/puzzles/sequence/35/key similarity index 100% rename from puzzles/sequence/5/key rename to puzzles/sequence/35/key diff --git a/puzzles/sequence/500/index.html b/puzzles/sequence/500/index.html new file mode 100644 index 0000000..0164660 --- /dev/null +++ b/puzzles/sequence/500/index.html @@ -0,0 +1,7 @@ +
+C: 00 f1 00 b4 0b 68 65 6c 6c 6f 20 77 6f 72 6c 64
+S: 00 bf 00 f1 02 68 69
+C: 00 f3 00 bf 0b 68 6f 77 20 61 72 65 20 79 6f 75
+S: 00 ca 00 f3 0d 6e 6f 74 20 62 61 64 2c 20 79 6f 75 3f
+C: __ __ __ __ __ 62 65 65 6e 20 77 6f 72 73 65
+
diff --git a/puzzles/sequence/500/key b/puzzles/sequence/500/key new file mode 100644 index 0000000..b26eb5a --- /dev/null +++ b/puzzles/sequence/500/key @@ -0,0 +1 @@ +01 00 00 ca 0a \ No newline at end of file diff --git a/puzzles/sequence/8/index.html b/puzzles/sequence/8/index.html index ca5618d..87de0c6 100644 --- a/puzzles/sequence/8/index.html +++ b/puzzles/sequence/8/index.html @@ -1 +1 @@ -66 70 72 74 76 _ +66 67 70 71 72 73 74 75 76 77 _ diff --git a/roshambocli.py b/roshambocli.py index 7ded7ac..d67168f 100755 --- a/roshambocli.py +++ b/roshambocli.py @@ -51,7 +51,7 @@ class IdiotBot(threading.Thread): return self.move def run(self): - c = Client(('localhost', 5388)) + c = Client(('cfl', 5388)) c.debug = False #print('lobby', c.command('^', 'lobby')) c.command('login', self.team, 'furble') @@ -60,7 +60,7 @@ class IdiotBot(threading.Thread): ret = c.command(move) if ret == ['WIN']: print('%s wins' % self.team) - amt = random.uniform(0.1, 1.2) + amt = random.uniform(0.1, 2.6) if c.debug: print(c, 'sleep %f' % amt) time.sleep(amt) diff --git a/teams.py b/teams.py index f27b7a2..be6dbb1 100755 --- a/teams.py +++ b/teams.py @@ -1,27 +1,36 @@ #! /usr/bin/env python3 import fcntl +import time +import os from urllib.parse import quote, unquote house = 'dirtbags' +passwdfn = '/var/lib/ctf/passwd' + teams = None +built = 0 def build_teams(): - global teams + global teams, built + + modt = os.path.getmtime(passwdfn) + if modt <= built: + return teams = {} try: - f = open('passwd') + f = open(passwdfn) for line in f: line = line.strip() team, passwd = [unquote(v) for v in line.strip().split('\t')] teams[team] = passwd except IOError: pass + built = time.time() def validate(team): - if teams is None: - build_teams() + build_teams() def chkpasswd(team, passwd): validate(team)