Fix medusa bugs

This commit is contained in:
Neale Pickett 2009-09-01 09:34:15 -06:00
parent c2d685005b
commit f3f5e797b3
5 changed files with 112 additions and 89 deletions

View File

@ -34,7 +34,6 @@ class Submitter(asyncore.dispatcher):
self.unacked[id] = q self.unacked[id] = q
def writable(self): def writable(self):
print('writable?')
now = int(time.time()) now = int(time.time())
if now >= self.lastupdate + 60: if now >= self.lastupdate + 60:
for cat, team in self.flags.items(): for cat, team in self.flags.items():
@ -45,7 +44,6 @@ class Submitter(asyncore.dispatcher):
self.pending.append(q) self.pending.append(q)
self.lastretrans = now self.lastretrans = now
ret = bool(self.pending) ret = bool(self.pending)
print(ret)
return ret return ret
def handle_write(self): def handle_write(self):
@ -71,6 +69,7 @@ class Submitter(asyncore.dispatcher):
team = team or points.house team = team or points.house
if self.flags.get(cat) != team:
self.flags[cat] = team self.flags[cat] = team
self.submit(now, cat, team, 1) self.submit(now, cat, team, 1)
@ -132,6 +131,7 @@ class FlagServer(asynchat.async_chat):
def handle_close(self): def handle_close(self):
self.set_flag(None) self.set_flag(None)
self.close()
def start(): def start():

View File

@ -3,19 +3,25 @@
import points import points
import time import time
import os import os
import tempfile
teamfiles = {} def main(s=None):
scores = {} scores = {}
now = 0 now = 0
if not s:
s = points.Storage('scores.dat') s = points.Storage('scores.dat')
plotparts = [] plotparts = []
teams = s.teams() teams = s.teams()
teamcolors = points.colors(teams) teamcolors = points.colors(teams)
fn = 'scores.hist' catscores = {}
scoresfile = open(fn, 'w') for cat in s.categories():
catscores[cat] = s.cat_points(cat)
scoresfile = tempfile.NamedTemporaryFile('w')
fn = scoresfile.name
i = 2 i = 2
for team in teams: for team in teams:
plotparts.append('"%s" using 1:%d with lines linewidth 2 linetype rgb "#%s"' % (fn, i, teamcolors[team])) plotparts.append('"%s" using 1:%d with lines linewidth 2 linetype rgb "#%s"' % (fn, i, teamcolors[team]))
@ -25,23 +31,22 @@ for team in teams:
def write_scores(t): def write_scores(t):
scoresfile.write('%d' % t) scoresfile.write('%d' % t)
for team in teams: for team in teams:
scoresfile.write('\t%d' % (scores[team])) scoresfile.write('\t%f' % (scores[team]))
scoresfile.write('\n') scoresfile.write('\n')
for when, cat, team, points in s.log: for when, cat, team, score in s.log:
if when > now: if when > now:
if now: if now:
write_scores(now) write_scores(now)
now = when now = when
scores[team] += points pct = score / catscores[cat]
scores[team] += pct
#print('%d [%s] [%s] %d' % (when, cat, team, points)) #print('%d [%s] [%s] %d' % (when, cat, team, points))
write_scores(when) write_scores(when)
scoresfile.flush()
for f in teamfiles.values(): gp = os.popen('gnuplot 2> /dev/null', 'w')
f.close()
gp = os.popen('gnuplot > /dev/null', 'w')
gp.write('set style data lines\n') gp.write('set style data lines\n')
gp.write('set xdata time\n') gp.write('set xdata time\n')
gp.write('set timefmt "%s"\n') gp.write('set timefmt "%s"\n')
@ -53,4 +58,7 @@ gp.write('set nokey\n')
gp.write('set terminal png transparent size 640,200 x000000 xffffff\n') gp.write('set terminal png transparent size 640,200 x000000 xffffff\n')
gp.write('set output "histogram.png"\n') gp.write('set output "histogram.png"\n')
gp.write('plot %s\n' % ','.join(plotparts)) gp.write('plot %s\n' % ','.join(plotparts))
gp.flush() gp.close()
if __name__ == '__main__':
main()

View File

@ -5,6 +5,8 @@ import hmac
import struct import struct
import io import io
## Name of the house team
house = 'dirtbags'
## ##
## Authentication ## Authentication
@ -48,8 +50,8 @@ def unpackstr(b):
## ##
## Request ## Request
## ##
def encode_request(when, cat, team, score): def encode_request(id, when, cat, team, score):
base = (struct.pack('!I', when) + base = (struct.pack('!II', id, when) +
packstr(cat) + packstr(cat) +
packstr(team) + packstr(team) +
struct.pack('!i', score)) struct.pack('!i', score))
@ -57,36 +59,35 @@ def encode_request(when, cat, team, score):
def decode_request(b): def decode_request(b):
base = check_sig(b) base = check_sig(b)
when, base = unpack('!I', base) id, when, base = unpack('!II', base)
cat, base = unpackstr(base) cat, base = unpackstr(base)
team, base = unpackstr(base) team, base = unpackstr(base)
score, base = unpack('!i', base) score, base = unpack('!i', base)
assert not base assert not base
return (when, cat, team, score) return (id, when, cat, team, score)
## ##
## Response ## Response
## ##
def encode_response(when, txt): def encode_response(id, txt):
base = (struct.pack('!I', when) + base = (struct.pack('!I', id) +
packstr(txt)) packstr(txt))
return sign(base) return sign(base)
def decode_response(b): def decode_response(b):
base = check_sig(b) base = check_sig(b)
when, base = unpack('!I', base) id, base = unpack('!I', base)
txt, base = unpackstr(base) txt, base = unpackstr(base)
assert not base assert not base
return (when, txt) return (id, txt)
## ##
## Storage ## Storage
## ##
def incdict(dict, key, amt=1): def incdict(dict, key, amt=1):
dict.setdefault(key, 0) dict[key] = dict.get(key, 0) + amt
dict[key] += amt
class Storage: class Storage:
def __init__(self, fn): def __init__(self, fn):
@ -94,7 +95,6 @@ class Storage:
self.points_by_cat = {} self.points_by_cat = {}
self.points_by_cat_team = {} self.points_by_cat_team = {}
self.log = [] self.log = []
self.events = set()
self.f = io.BytesIO() self.f = io.BytesIO()
# Read stored scores # Read stored scores
@ -106,8 +106,11 @@ class Storage:
break break
(l,) = struct.unpack('!I', l) (l,) = struct.unpack('!I', l)
b = f.read(l) b = f.read(l)
req = decode_request(b) when, score, catlen, teamlen, b = unpack('!IiHH', b)
self.add(req) cat = b[:catlen].decode('utf-8')
team = b[catlen:].decode('utf-8')
req = (when, cat, team, score)
self.add(req, False)
f.close() f.close()
except IOError: except IOError:
pass pass
@ -117,24 +120,25 @@ class Storage:
except IOError: except IOError:
self.f = None self.f = None
def __contains__(self, req): def __len__(self):
return req in self.events return len(self.log)
def add(self, req):
if req in self.events:
return
def add(self, req, write=True):
when, cat, team, score = req when, cat, team, score = req
incdict(self.points_by_team, team, score) incdict(self.points_by_team, team, score)
incdict(self.points_by_cat, cat, score) incdict(self.points_by_cat, cat, score)
incdict(self.points_by_cat_team, (cat, team), score) incdict(self.points_by_cat_team, (cat, team), score)
self.log.append(req) self.log.append(req)
self.events.add(req)
b = encode_request(*req) if write:
lb = struct.pack('!I', len(b)) + b cat = cat.encode('utf-8')
team = team.encode('utf-8')
b = (struct.pack('!IiHH', when, score, len(cat), len(team)) +
cat + team)
lb = struct.pack('!I', len(b))
self.f.write(lb) self.f.write(lb)
self.f.write(b)
self.f.flush() self.f.flush()
def categories(self): def categories(self):
@ -179,7 +183,7 @@ def test():
req = (now, 'category 5', 'foobers in heat', 43) req = (now, 'category 5', 'foobers in heat', 43)
assert decode_request(encode_request(*req)) == req assert decode_request(encode_request(*req)) == req
rsp = (now, 'hello world') rsp = (now, 'cat6', 'hello world')
assert decode_response(encode_response(*rsp)) == rsp assert decode_response(encode_response(*rsp)) == rsp

View File

@ -6,12 +6,15 @@ import struct
import points import points
import time import time
house = 'dirtbags'
class MyHandler(asyncore.dispatcher): class MyHandler(asyncore.dispatcher):
def __init__(self, port): def __init__(self, port=6667):
asyncore.dispatcher.__init__(self) asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_DGRAM) self.create_socket(socket.AF_INET, socket.SOCK_DGRAM)
self.bind(('', port)) self.bind(('', port))
self.acked = points.Storage('scores.dat') self.store = points.Storage('scores.dat')
self.acked = set()
self.outq = [] self.outq = []
def writable(self): def writable(self):
@ -22,30 +25,31 @@ class MyHandler(asyncore.dispatcher):
self.socket.sendto(dgram, peer) self.socket.sendto(dgram, peer)
def handle_read(self): def handle_read(self):
dgram, peer = self.socket.recvfrom(4096)
now = int(time.time()) now = int(time.time())
dgram, peer = self.socket.recvfrom(4096)
try: try:
req = points.decode_request(dgram) id, when, cat, team, score = points.decode_request(dgram)
except ValueError as e: except ValueError as e:
return self.respond(now, str(e)) return self.respond(peer, now, str(e))
when, cat, team, score = req team = team or house
# Replays can happen legitimately. # Replays can happen legitimately.
if not req in self.acked: if not (id in self.acked):
if not (now - 2 < when <= now): if not (now - 2 < when <= now):
resp = points.encode_response(when, 'Your clock is off') return self.respond(peer, id, 'Your clock is off')
self.outq.append((resp, peer)) self.store.add((when, cat, team, score))
return self.acked.add(id)
self.acked.add(req)
resp = points.encode_response(when, 'OK') self.respond(peer, id, 'OK')
def respond(self, peer, id, txt):
resp = points.encode_response(id, txt)
self.outq.append((resp, peer)) self.outq.append((resp, peer))
def respond(self, peer, when, txt):
resp = points.encode_response(when, txt)
self.outq.append((resp, peer))
def start():
return MyHandler()
if __name__ == "__main__": if __name__ == "__main__":
h = MyHandler(6667) h = start()
asyncore.loop() asyncore.loop()

View File

@ -3,10 +3,17 @@
import asyncore import asyncore
import pointsd import pointsd
import flagd import flagd
import histogram
def main(): def main():
pointsd.start() pointsrv = pointsd.start()
flagd.start() flagsrv = flagd.start()
asyncore.loop(timeout=30, use_poll=True) s = pointsrv.store
slen = 0
while True:
asyncore.loop(timeout=30, use_poll=True, count=1)
if len(s) > slen:
slen = len(s)
histogram.main(s)
main() main()