++update
This commit is contained in:
parent
f51b5f4c73
commit
f3bc819367
2 changed files with 70 additions and 44 deletions
|
@ -84,3 +84,6 @@ The base for building games is:
|
||||||
* Enhance the Challenge class - abstract away writing information?
|
* Enhance the Challenge class - abstract away writing information?
|
||||||
* Implement dependencies / providers for challenges
|
* Implement dependencies / providers for challenges
|
||||||
* Add an easy to use CLI (Steven might like click)
|
* Add an easy to use CLI (Steven might like click)
|
||||||
|
* Write nice code to easily retrieve points per user
|
||||||
|
* Sort high score
|
||||||
|
* Maybe store all user information in one JSON object?
|
||||||
|
|
111
server.py
111
server.py
|
@ -6,7 +6,6 @@ import ipaddress
|
||||||
import random
|
import random
|
||||||
import sys
|
import sys
|
||||||
import etcd
|
import etcd
|
||||||
import ungleichapi
|
|
||||||
import json
|
import json
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
@ -28,6 +27,7 @@ class Challenge(object):
|
||||||
points = 0
|
points = 0
|
||||||
provides = []
|
provides = []
|
||||||
requires = []
|
requires = []
|
||||||
|
description = None
|
||||||
|
|
||||||
def __init__(self, etcdclient):
|
def __init__(self, etcdclient):
|
||||||
self.client = etcdclient
|
self.client = etcdclient
|
||||||
|
@ -38,14 +38,24 @@ class Challenge(object):
|
||||||
parser.add_argument(arg, required=True)
|
parser.add_argument(arg, required=True)
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
def game(self):
|
||||||
|
if request.method == 'GET':
|
||||||
|
return self.describe()
|
||||||
|
if request.method == 'POST':
|
||||||
|
return self.solve()
|
||||||
|
|
||||||
def describe(self):
|
def describe(self):
|
||||||
return self.description
|
return self.description
|
||||||
|
|
||||||
def save_points(self, user):
|
def save_points(self, user):
|
||||||
""" should be called when the challenge was solved successfully"""
|
""" should be called when the challenge was solved successfully"""
|
||||||
|
|
||||||
path = "/ungleichgame/v1/{}/challenges/{}/points".format(user, self.__name__)
|
key = "points/{}".format(user, type(self).__name__)
|
||||||
self.client.write(path, self.points)
|
self.set_user_key(user, key, self.points)
|
||||||
|
|
||||||
|
def set_user_key(self, user, key, value):
|
||||||
|
path = "/ungleichgame/v1/user/{}/{}".format(user, key)
|
||||||
|
self.client.write(path, value)
|
||||||
|
|
||||||
def solve(self):
|
def solve(self):
|
||||||
""" Needs to be implemented per challenge """
|
""" Needs to be implemented per challenge """
|
||||||
|
@ -64,11 +74,12 @@ and to setup services listening on these IPv6 addresses.
|
||||||
Submit your network with the "network" parameter.
|
Submit your network with the "network" parameter.
|
||||||
"""
|
"""
|
||||||
def solve(self):
|
def solve(self):
|
||||||
self.require_args("user", "network")
|
args = self.require_args("user", "network")
|
||||||
|
network = args['network']
|
||||||
|
user = args['user']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
net = ipaddress.IPv6Network(args['network'])
|
net = ipaddress.IPv6Network(network)
|
||||||
network = args['network']
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return Response(status=400, response="Cannot register network {}: {}".format(network, e))
|
return Response(status=400, response="Cannot register network {}: {}".format(network, e))
|
||||||
|
|
||||||
|
@ -76,11 +87,10 @@ Submit your network with the "network" parameter.
|
||||||
return Response(status=400, response="{} mask is not /64 - please use a /64 network".format(net))
|
return Response(status=400, response="{} mask is not /64 - please use a /64 network".format(net))
|
||||||
|
|
||||||
# Save network
|
# Save network
|
||||||
self.client.write("/ungleichgame/v1/{}/network".format(user), network)
|
self.set_user_key(user, "network", network)
|
||||||
self.save_points(args['user'])
|
self.save_points(user)
|
||||||
|
|
||||||
return json.dumps("All good, go to /level/1 to start with level 1! - {}".format(data.value))
|
|
||||||
|
|
||||||
|
return "Network {} registered, have fun with the next challenge!".format(network)
|
||||||
|
|
||||||
|
|
||||||
class Game(object):
|
class Game(object):
|
||||||
|
@ -88,8 +98,8 @@ class Game(object):
|
||||||
self.client = etcdclient
|
self.client = etcdclient
|
||||||
self.app = Flask(name)
|
self.app = Flask(name)
|
||||||
|
|
||||||
self.app.add_url_rule('/', 'highscore', self.highscore)
|
self.app.add_url_rule('/', 'index', self.index)
|
||||||
self.app.add_url_rule('/highscore', 'highscore', self.highscore)
|
self.app.add_url_rule('/points', 'points', self.points)
|
||||||
|
|
||||||
# etcd paths are below here
|
# etcd paths are below here
|
||||||
self.etcbase = etcbase
|
self.etcbase = etcbase
|
||||||
|
@ -98,13 +108,23 @@ class Game(object):
|
||||||
# Automate this
|
# Automate this
|
||||||
challenges = [ RegisterNet ]
|
challenges = [ RegisterNet ]
|
||||||
|
|
||||||
|
self.app.add_url_rule('/challenge', 'list_of_challenges', self.list_of_challenges)
|
||||||
|
self.app.add_url_rule('/challenge/', 'list_of_challenges', self.list_of_challenges)
|
||||||
|
|
||||||
|
self.challenge_names = []
|
||||||
for challenge in challenges:
|
for challenge in challenges:
|
||||||
c = challenge(self.client)
|
c = challenge(self.client)
|
||||||
name = c.__name__
|
name = type(c).__name__
|
||||||
|
self.challenge_names.append(name)
|
||||||
path = "/challenge/{}".format(name)
|
path = "/challenge/{}".format(name)
|
||||||
|
|
||||||
self.app.add_url_rule(path, name, c.describe, methods=['GET'])
|
self.app.add_url_rule(path, name, c.game, methods=['GET', 'POST'])
|
||||||
self.app.add_url_rule(path, name, c.solve, methods=['POST'])
|
|
||||||
|
|
||||||
|
def list_of_challenges(self):
|
||||||
|
return """The following challenges are available on this server:
|
||||||
|
{}
|
||||||
|
""".format("\n".join(self.challenge_names))
|
||||||
|
|
||||||
|
|
||||||
def read_etcd(self, path, recursive=False):
|
def read_etcd(self, path, recursive=False):
|
||||||
|
@ -117,48 +137,51 @@ class Game(object):
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def get_highscore(self, username=None):
|
def get_points(self):
|
||||||
""" Returns a dict['username'] = points """
|
""" Returns a dict['username'] = points """
|
||||||
|
|
||||||
all_users = {}
|
user_points = {}
|
||||||
highscore = {}
|
|
||||||
|
|
||||||
print("getting high")
|
path = "{}/".format(self.userbase)
|
||||||
|
users = self.client.get(path)
|
||||||
|
|
||||||
if username:
|
if users:
|
||||||
path = "{}/{}".format(self.userbase, username)
|
print(users)
|
||||||
user = self.read_etcd(path)
|
for user in users.children:
|
||||||
if user:
|
username= user.key # needs to be FIXED
|
||||||
all_users[username] = user
|
user_points[username] = 0
|
||||||
else:
|
|
||||||
path = "{}/".format(self.userbase)
|
|
||||||
users = self.read_etcd(path, recursive=True)
|
|
||||||
print("reading from {}".format(path))
|
|
||||||
if users:
|
|
||||||
for child in users.children:
|
|
||||||
print("adding user {} {} = {}".format(child, child.key, child.value))
|
|
||||||
all_users[child.key] = child.value
|
|
||||||
|
|
||||||
for k, v in all_users.items():
|
point_path = "{}/points".format(user.key)
|
||||||
# Ignore all kind of errors - just add the ones that work
|
points = self.read_etcd(point_path, recursive=True)
|
||||||
try:
|
|
||||||
highscore[k] = json.loads(v)['points']
|
|
||||||
print("f?")
|
|
||||||
except Exception as e:
|
|
||||||
print(e)
|
|
||||||
|
|
||||||
return highscore
|
for challenge in points.children:
|
||||||
|
user_points[username] += int(challenge.value)
|
||||||
|
|
||||||
def highscore(self):
|
return user_points
|
||||||
point_list = self.get_highscore()
|
|
||||||
|
def index(self):
|
||||||
|
points = self.points()
|
||||||
|
|
||||||
|
return """Welcome to the game server!
|
||||||
|
|
||||||
|
Current point list is:
|
||||||
|
{}
|
||||||
|
|
||||||
|
For more information visit
|
||||||
|
|
||||||
|
https://code.ungleich.ch/nico/ungleich-game
|
||||||
|
""".format(points)
|
||||||
|
|
||||||
|
def points(self):
|
||||||
|
point_list = self.get_points()
|
||||||
res = []
|
res = []
|
||||||
if not point_list:
|
if not point_list:
|
||||||
return Response("No winners yet!")
|
return Response("No winners yet!")
|
||||||
|
|
||||||
for k, v in point_list.items():
|
for k, v in point_list.items():
|
||||||
res.append("<p>{} has {} points</p>".format(k, v))
|
res.append("{} has {} points".format(k, v))
|
||||||
|
|
||||||
return Response("\n".join(res))
|
return "\n".join(res)
|
||||||
|
|
||||||
|
|
||||||
# def get_ip_address():
|
# def get_ip_address():
|
||||||
|
|
Loading…
Reference in a new issue