2 many templates
This commit is contained in:
parent
06b86d706e
commit
00cc143d6e
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -133,5 +133,5 @@ dmypy.json
|
|||
# jetbrains folder
|
||||
.idea/
|
||||
qbBuzzer.iml
|
||||
.env
|
||||
test/
|
||||
|
||||
|
|
150
src/app.py
150
src/app.py
|
@ -2,43 +2,38 @@ from flask import *
|
|||
from random import randint as rint
|
||||
from src.config import Config
|
||||
from src.host import HostForm
|
||||
from src.sec import gencode, dohash
|
||||
from src.join import JoinForm
|
||||
from src.sec import gencode, dohash, whitelist
|
||||
from logging.config import dictConfig
|
||||
import logging
|
||||
from flask_socketio import SocketIO
|
||||
from flask_socketio import SocketIO, emit, join_room, leave_room
|
||||
import json
|
||||
|
||||
dictConfig({
|
||||
'version': 1,
|
||||
'formatters': {'default': {
|
||||
'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
|
||||
}},
|
||||
'handlers': {'wsgi': {
|
||||
'class': 'logging.StreamHandler',
|
||||
'stream': 'ext://flask.logging.wsgi_errors_stream',
|
||||
'formatter': 'default'
|
||||
}},
|
||||
'root': {
|
||||
'level': 'INFO',
|
||||
'handlers': ['wsgi']
|
||||
}
|
||||
})
|
||||
# Loading logging preferences
|
||||
with open("logger.json", "r") as f:
|
||||
dconf = json.load(f)
|
||||
|
||||
# Establishing logger
|
||||
dictConfig(dconf)
|
||||
|
||||
# Loading flask app
|
||||
app = Flask(__name__)
|
||||
app.logger.info("Flask app loaded at " + __name__)
|
||||
app.config.from_object(Config)
|
||||
|
||||
app.logger.setLevel(logging.DEBUG)
|
||||
|
||||
# Version allows css / js to load instead of taking hours to update even on run smh
|
||||
version = rint(0, 300000000)
|
||||
|
||||
# games
|
||||
games = {}
|
||||
|
||||
|
||||
# home
|
||||
@app.route('/')
|
||||
def home():
|
||||
return render_template('index.html', version=str(version))
|
||||
|
||||
|
||||
# creating a room for players to join
|
||||
@app.route("/host", methods=["GET", "POST"])
|
||||
def host():
|
||||
form = HostForm()
|
||||
|
@ -46,7 +41,7 @@ def host():
|
|||
hostcode = gencode(64)
|
||||
hash = dohash(hostcode)
|
||||
resp = redirect(url_for("play", hash=hash))
|
||||
resp.set_cookie("_gid", str(hostcode), httponly=True, secure=True)
|
||||
resp.set_cookie("_gid", str(hostcode))
|
||||
with open("src/templates/games.json", "r") as f:
|
||||
tmp = json.load(f)
|
||||
games[hash] = tmp
|
||||
|
@ -55,7 +50,6 @@ def host():
|
|||
games[hash]["bonus"] = form.bonus.data
|
||||
games[hash]["power"] = form.power.data
|
||||
games[hash]["negs"] = form.negs.data
|
||||
games[hash]["teams"] = form.teams.data
|
||||
app.logger.debug("Game host at %s", hostcode)
|
||||
app.logger.info("Game created at %s", hash)
|
||||
return resp
|
||||
|
@ -63,32 +57,136 @@ def host():
|
|||
return render_template('host.html', title="Host Game", version=str(version), form=form, default=default)
|
||||
|
||||
|
||||
# Inside the room itself
|
||||
@app.route("/play/<hash>")
|
||||
def play(hash):
|
||||
if hash in games.keys():
|
||||
return render_template('play.html', version=str(version))
|
||||
if dohash(request.cookies.get('_gid')) == hash:
|
||||
return render_template('gamehost.html', version=str(version), gamecode=hash)
|
||||
else:
|
||||
if "name" in request.cookies:
|
||||
name = request.cookies.get("name")
|
||||
return render_template('play.html', version=str(version), gamecode=hash, username=name)
|
||||
else:
|
||||
return render_template('please.html', version=str(version))
|
||||
else:
|
||||
abort(404)
|
||||
|
||||
|
||||
@app.route("/join")
|
||||
@app.route("/kick")
|
||||
def kick():
|
||||
return render_template('kick.html', version=str(version))
|
||||
|
||||
|
||||
# When players attempt to join a room
|
||||
@app.route("/join", methods=["GET", "POST"])
|
||||
def join():
|
||||
return "In progress!"
|
||||
form = JoinForm()
|
||||
if form.validate_on_submit():
|
||||
wlist = whitelist()
|
||||
if not all([a in wlist for a in form.name.data]):
|
||||
return render_template('badname.html', title='Join Game', version=str(version))
|
||||
hash = form.roomcode.data
|
||||
if hash in games.keys():
|
||||
if form.name.data in games[hash]["players"].keys():
|
||||
return render_template('nametaken.html', title='Join Game', version=str(version))
|
||||
games[hash]["players"][form.name.data] = 0
|
||||
resp = redirect(url_for("play", hash=hash))
|
||||
resp.set_cookie("_gid", "")
|
||||
resp.set_cookie("name", form.name.data)
|
||||
return resp
|
||||
else:
|
||||
return render_template('gamenotfound.html', title="Join Game", version=str(version))
|
||||
return render_template('join.html', title="Join Game", version=str(version), form=form)
|
||||
|
||||
|
||||
# If someone visits somethin stupid
|
||||
@app.errorhandler(404)
|
||||
def page_not_found(e):
|
||||
return render_template('404.html'), 404
|
||||
|
||||
|
||||
# Connecting socketio for all socketio functions below
|
||||
socketio = SocketIO(app)
|
||||
|
||||
|
||||
# |
|
||||
# V
|
||||
|
||||
|
||||
@socketio.on('json')
|
||||
def handle_json(json):
|
||||
print('received message: ' + str(json))
|
||||
emit('json', json)
|
||||
|
||||
|
||||
# Checks when a player / host joins the room
|
||||
@socketio.on('join')
|
||||
def on_join(data):
|
||||
room = data['room']
|
||||
username = ""
|
||||
if "username" in data.keys():
|
||||
username = data['username']
|
||||
else:
|
||||
gid = data["_gid"]
|
||||
if dohash(gid) == room:
|
||||
username = "host"
|
||||
join_room(str(room))
|
||||
emit('player_join_event', games[room]["players"], room=room)
|
||||
|
||||
|
||||
# When the host sends data to server
|
||||
@socketio.on('host')
|
||||
def host_msg(data):
|
||||
room = data["room"]
|
||||
gid = data["_gid"]
|
||||
if dohash(gid) != room: # Check if the host is really the host
|
||||
return
|
||||
msg = data["data"]
|
||||
if "lock" in msg.keys():
|
||||
pass # lock buzzers
|
||||
elif "kick" in msg.keys():
|
||||
msg["url"] = url_for('kick')
|
||||
username = msg["kick"]
|
||||
del games[room]["players"][username]
|
||||
emit("player_kick_event", msg, room=room)
|
||||
elif "tossup" in msg.keys():
|
||||
pass # give player points
|
||||
elif "bonus" in msg.keys():
|
||||
pass # give player points
|
||||
elif "power" in msg.keys():
|
||||
pass # give player points
|
||||
elif "negs" in msg.keys():
|
||||
pass # give player points
|
||||
elif "amount" in msg.keys():
|
||||
pass # give player points
|
||||
|
||||
|
||||
# When the player buzzes
|
||||
@socketio.on('buzz')
|
||||
def buzz(data):
|
||||
room = data["room"]
|
||||
emit("buzz", data, room=room) # Just send it back
|
||||
|
||||
|
||||
# When a player / host leaves
|
||||
@socketio.on('leave')
|
||||
def on_leave(data):
|
||||
print("player leave")
|
||||
room = data['room']
|
||||
username = ""
|
||||
if "username" in data.keys():
|
||||
username = data['username']
|
||||
else:
|
||||
gid = data["_gid"]
|
||||
if dohash(gid) == room:
|
||||
username = "host"
|
||||
del games[room]["players"][username]
|
||||
leave_room(room)
|
||||
emit('player_leave_event', {"player": username}, room=room)
|
||||
|
||||
|
||||
# Run the thing lol
|
||||
if __name__ == "__main__":
|
||||
socketio.run(app)
|
||||
socketio.run(app, host="0.0.0.0", port=25565)
|
||||
# app.run(host="127.0.0.1", port=25565)
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
from flask_wtf import FlaskForm
|
||||
from wtforms import IntegerField, SubmitField, BooleanField
|
||||
from wtforms import IntegerField, SubmitField
|
||||
from wtforms.validators import DataRequired
|
||||
class HostForm(FlaskForm):
|
||||
tossup = IntegerField('Tossup Points', validators=[DataRequired()])
|
||||
bonus = IntegerField('Bonus Points', validators=[DataRequired()])
|
||||
power = IntegerField('Power Points', validators=[DataRequired()])
|
||||
negs = IntegerField('Neg Points [Positive]', validators=[DataRequired()])
|
||||
teams = BooleanField('Teams? ')
|
||||
create = SubmitField('Create Room')
|
|
@ -1,6 +1,7 @@
|
|||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, SubmitField, BooleanField
|
||||
from wtforms import StringField, SubmitField
|
||||
from wtforms.validators import DataRequired
|
||||
class JoinForm(FlaskForm):
|
||||
roomcode = StringField('Room Code', validators=[DataRequired()])
|
||||
name = StringField('Name', validators=[DataRequired()])
|
||||
create = SubmitField('Join Room')
|
15
src/logger.json
Normal file
15
src/logger.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"version": 1,
|
||||
"formatters": {"default": {
|
||||
"format": "[%(asctime)s] %(levelname)s in %(module)s: %(message)s"
|
||||
}},
|
||||
"handlers": {"wsgi": {
|
||||
"class": "logging.StreamHandler",
|
||||
"stream": "ext://flask.logging.wsgi_errors_stream",
|
||||
"formatter": "default"
|
||||
}},
|
||||
"root": {
|
||||
"level": "DEBUG",
|
||||
"handlers": ["wsgi"]
|
||||
}
|
||||
}
|
|
@ -20,6 +20,10 @@ def sha3256(val):
|
|||
return ho.digest()
|
||||
|
||||
|
||||
def whitelist():
|
||||
return list(ascii_letters + digits)
|
||||
|
||||
|
||||
def hexdigest(val):
|
||||
return hexlify(val).decode('utf-8')
|
||||
|
||||
|
|
BIN
src/static/buzz.mp3
Normal file
BIN
src/static/buzz.mp3
Normal file
Binary file not shown.
|
@ -1,7 +1,74 @@
|
|||
var socket = io();
|
||||
test = function() {
|
||||
console.log("h");
|
||||
socket.emit('json', {data: 'I\'m connected!'});
|
||||
|
||||
code = document.getElementById("code").value;
|
||||
name = document.getElementById("name").value;
|
||||
kickurl = document.getElementById("kick").value;
|
||||
|
||||
function removeAllChildren(e) {
|
||||
var child = e.lastElementChild;
|
||||
while (child) {
|
||||
e.removeChild(child);
|
||||
child = e.lastElementChild;
|
||||
}
|
||||
}
|
||||
|
||||
socket.on("connect", function() {
|
||||
// when client first connects to a game
|
||||
socket.emit("join", {"username": name, "room": code, "_gid": ""});
|
||||
})
|
||||
|
||||
socket.on("player_join_event", function(data) {
|
||||
div = document.getElementById("sidebar");
|
||||
removeAllChildren(div);
|
||||
if (Object.keys(data).length == 0) {
|
||||
var keepSidebarOpen = document.createElement("input");
|
||||
keepSidebarOpen.setAttribute("type", "hidden");
|
||||
div.appendChild(keepSidebarOpen);
|
||||
return
|
||||
}
|
||||
var keys = Object.keys(data);
|
||||
for (var key in keys) {
|
||||
var playerDisplay = document.createElement("div");
|
||||
playerDisplay.setAttribute("id", keys[key]);
|
||||
playerDisplay.setAttribute("class", "playertag");
|
||||
var playerLink = document.createElement("p");
|
||||
playerLink.appendChild(document.createTextNode(keys[key]));
|
||||
playerDisplay.appendChild(playerLink);
|
||||
playerDisplay.appendChild(document.createElement("br"));
|
||||
div.appendChild(playerDisplay);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on("player_leave_event", function(data) {
|
||||
var element = document.getElementById(data["player"]);
|
||||
element.parentNode.removeChild(element);
|
||||
});
|
||||
|
||||
socket.on("player_kick_event", function(data) {
|
||||
if (data["kick"] == name) {
|
||||
window.location = kickurl;
|
||||
} else {
|
||||
var element = document.getElementById(data["kick"]);
|
||||
element.parentNode.removeChild(element);
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
function buzz() {
|
||||
// when client hits buzz
|
||||
socket.emit("buzz", {"username": name, "room": code, "_gid": ""});
|
||||
}
|
||||
|
||||
$(document).on('keypress', function(e) {
|
||||
if (e.key === ' ' || e.key === 'Spacebar') {
|
||||
e.preventDefault();
|
||||
buzz();
|
||||
}
|
||||
})
|
||||
|
||||
window.onbeforeunload = function leave() {
|
||||
// when client leaves
|
||||
console.log("leave")
|
||||
socket.emit("leave", {"username": name, "room": code, "_gid": ""});
|
||||
}
|
||||
|
||||
// div id = game (that's where the game goes)
|
90
src/static/host.js
Normal file
90
src/static/host.js
Normal file
|
@ -0,0 +1,90 @@
|
|||
var socket = io();
|
||||
|
||||
code = document.getElementById("copycode").value;
|
||||
|
||||
function readCookie(name) {
|
||||
var nameEQ = name + "=";
|
||||
var ca = document.cookie.split(';');
|
||||
for(var i=0;i < ca.length;i++) {
|
||||
var c = ca[i];
|
||||
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
||||
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
gid = readCookie("_gid");
|
||||
|
||||
copycode = function() {
|
||||
var copyText = document.getElementById("copycode")
|
||||
copyText.select();
|
||||
copyText.setSelectionRange(0, 99999);
|
||||
document.execCommand("copy")
|
||||
}
|
||||
|
||||
function send(data) {
|
||||
socket.emit("host", {"room": code, "_gid": gid, "data": data});
|
||||
}
|
||||
|
||||
function removeAllChildren(e) {
|
||||
var child = e.lastElementChild;
|
||||
while (child) {
|
||||
e.removeChild(child);
|
||||
child = e.lastElementChild;
|
||||
}
|
||||
}
|
||||
|
||||
socket.on("connect", function() {
|
||||
socket.emit("join", {"room": code, "_gid": gid});
|
||||
});
|
||||
window.onbeforeunload = function leave() {
|
||||
socket.emit("leave", {"room": code, "_gid": gid});
|
||||
}
|
||||
|
||||
|
||||
socket.on("player_join_event", function(data) {
|
||||
div = document.getElementById("sidebar");
|
||||
removeAllChildren(div);
|
||||
if (Object.keys(data).length == 0) {
|
||||
var keepSidebarOpen = document.createElement("input");
|
||||
keepSidebarOpen.setAttribute("type", "hidden");
|
||||
div.appendChild(keepSidebarOpen);
|
||||
return
|
||||
}
|
||||
var keys = Object.keys(data);
|
||||
for (var key in keys) {
|
||||
var playerDisplay = document.createElement("div");
|
||||
playerDisplay.setAttribute("id", keys[key]);
|
||||
playerDisplay.setAttribute("class", "playertag");
|
||||
var playerLink = document.createElement("p");
|
||||
playerLink.appendChild(document.createTextNode(keys[key]));
|
||||
var removeLink = document.createElement("a");
|
||||
removeLink.setAttribute("onclick", "removePlayer('" + keys[key] + "');");
|
||||
removeLink.appendChild(document.createTextNode("Kick"));
|
||||
playerDisplay.appendChild(playerLink);
|
||||
playerDisplay.appendChild(removeLink);
|
||||
playerDisplay.appendChild(document.createElement("br"));
|
||||
div.appendChild(playerDisplay);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on("player_leave_event", function(data) {
|
||||
var element = document.getElementById(data["player"]);
|
||||
element.parentNode.removeChild(element);
|
||||
});
|
||||
|
||||
socket.on("player_kick_event", function(data) {
|
||||
var element = document.getElementById(data["kick"]);
|
||||
element.parentNode.removeChild(element);
|
||||
|
||||
})
|
||||
|
||||
function removePlayer(playername) {
|
||||
send({"kick": playername});
|
||||
}
|
||||
|
||||
socket.on("buzz", function(message) {
|
||||
var audio = new Audio('/static/buzz.mp3');
|
||||
audio.play();
|
||||
})
|
||||
|
|
@ -92,6 +92,63 @@ body {
|
|||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.copycode {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.form {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.form input {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
height: 100%; /* Full-height: remove this if you want "auto" height */
|
||||
font-size: 25px;
|
||||
position: fixed; /* Fixed Sidebar (stay in place on scroll) */
|
||||
z-index: 1; /* Stay on top */
|
||||
top: 0; /* Stay at the top */
|
||||
left: 0;
|
||||
background-color: #e2e27c;
|
||||
padding-top: 20px;
|
||||
padding-left: 10px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
/* The navigation menu links */
|
||||
.sidebar a {
|
||||
padding: 6px 8px 6px 8px;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
color: #ea2a2d;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.sidebar p {
|
||||
padding: 6px 8px 6px 6px;
|
||||
text-decoration: none;
|
||||
font-size: 25px;
|
||||
color: #818181;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
/* When you mouse over the navigation links, change their color */
|
||||
.sidebar a:hover {
|
||||
color: #f1f1f1;
|
||||
}
|
||||
|
||||
/* Style page content */
|
||||
.game {
|
||||
padding: 0px 10px;
|
||||
}
|
||||
|
||||
/* On smaller screens, where height is less than 450px, change the style of the sidebar (less padding and a smaller font size) */
|
||||
@media screen and (max-height: 450px) {
|
||||
.sidebar {padding-top: 15px;}
|
||||
.sidebar a {font-size: 18px;}
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Abberancy-Regular';
|
||||
|
|
14
src/templates/badname.html
Normal file
14
src/templates/badname.html
Normal file
|
@ -0,0 +1,14 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="button top">
|
||||
<a href="{{ url_for('join') }}">Back</a>
|
||||
</div>
|
||||
<div class="title">
|
||||
<h1> Bad Name </h1>
|
||||
</div>
|
||||
<div class="text">
|
||||
<center>
|
||||
<p>Names can only be alphanumeric. </p>
|
||||
</center>
|
||||
</div>
|
||||
{% endblock %}
|
21
src/templates/gamehost.html
Normal file
21
src/templates/gamehost.html
Normal file
|
@ -0,0 +1,21 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="subttl">
|
||||
<h1> Game! </h1>
|
||||
</div>
|
||||
|
||||
<div class="sidebar" id="sidebar">
|
||||
|
||||
</div>
|
||||
<div id="join">
|
||||
<center>
|
||||
<p>Click to copy the game code: </p>
|
||||
<input id="copycode" class="copycode" name="copycode" value="{{ gamecode }}" type="text" size="32" readonly onclick="copycode();"/>
|
||||
</center>
|
||||
</div>
|
||||
<div id="game">
|
||||
</div>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js" integrity="sha256-yr4fRk/GU1ehYJPAs8P4JlTgu0Hdsp4ZKrx8bDEDC3I=" crossorigin="anonymous"></script>
|
||||
<script src="/static/host.js?version={{ version }}" type="text/javascript" charset="utf-8"></script>
|
||||
{% endblock %}
|
9
src/templates/gamenotfound.html
Normal file
9
src/templates/gamenotfound.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="button top">
|
||||
<a href="{{ url_for('join') }}">Back</a>
|
||||
</div>
|
||||
<div class="title">
|
||||
<h1> Game not found </h1>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -4,5 +4,6 @@
|
|||
"bonus": 20,
|
||||
"power": 15,
|
||||
"negs": 5,
|
||||
"teams": false
|
||||
"teams": false,
|
||||
"players": {}
|
||||
}
|
|
@ -7,10 +7,11 @@
|
|||
<div class="subttl">
|
||||
<h1> Host Game </h1>
|
||||
</div>
|
||||
<div class="form host">
|
||||
<form action="" method="post" novalidate>
|
||||
{{ form.csrf_token }}
|
||||
{{ form.hidden_tag() }}
|
||||
<p>
|
||||
<center>
|
||||
{{ form.tossup.label }}<br>
|
||||
{{ form.tossup(size=32, value=default[0]) }}<br>
|
||||
{% for error in form.tossup.errors %}
|
||||
|
@ -35,13 +36,10 @@
|
|||
<span style="color: red;">[{{ error }}]</span><br>
|
||||
{% endfor %}
|
||||
<br>
|
||||
{{ form.teams() }} {{ form.teams.label }}<br>
|
||||
{% for error in form.negs.errors %}
|
||||
<span style="color: red;">[{{ error }}]</span><br>
|
||||
{% endfor %}
|
||||
<br>
|
||||
{{ form.create() }}
|
||||
<br>
|
||||
</center>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,47 +1,30 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="button top">
|
||||
<div class="button top">
|
||||
<a href="{{ url_for('home') }}">Back</a>
|
||||
</div>
|
||||
<div class="subttl">
|
||||
<h1> Host Game </h1>
|
||||
</div>
|
||||
<form action="" method="post" novalidate>
|
||||
</div>
|
||||
<div class="subttl">
|
||||
<h1> Join Game </h1>
|
||||
</div>
|
||||
<div class="form join">
|
||||
<form action="" method="post" novalidate>
|
||||
{{ form.csrf_token }}
|
||||
{{ form.hidden_tag() }}
|
||||
<p>
|
||||
{{ form.tossup.label }}<br>
|
||||
{{ form.tossup(size=32, value=default[0]) }}<br>
|
||||
{% for error in form.tossup.errors %}
|
||||
<p><center>
|
||||
{{ form.roomcode.label }}<br>
|
||||
{{ form.roomcode(size=32) }}<br>
|
||||
{% for error in form.roomcode.errors %}
|
||||
<span style="color: red;">[{{ error }}]</span><br>
|
||||
{% endfor %}
|
||||
<br>
|
||||
{{ form.bonus.label }}<br>
|
||||
{{ form.bonus(size=32, value=default[1]) }}<br>
|
||||
{% for error in form.bonus.errors %}
|
||||
<span style="color: red;">[{{ error }}]</span><br>
|
||||
{% endfor %}
|
||||
<br>
|
||||
{{ form.power.label }}<br>
|
||||
{{ form.power(size=32, value=default[2]) }}<br>
|
||||
{% for error in form.power.errors %}
|
||||
<span style="color: red;">[{{ error }}]</span><br>
|
||||
{% endfor %}
|
||||
<br>
|
||||
{{ form.negs.label }}<br>
|
||||
{{ form.negs(size=32, value=default[3]) }}<br>
|
||||
{% for error in form.negs.errors %}
|
||||
<span style="color: red;">[{{ error }}]</span><br>
|
||||
{% endfor %}
|
||||
<br>
|
||||
{{ form.teams() }} {{ form.teams.label }}<br>
|
||||
{% for error in form.negs.errors %}
|
||||
{{ form.name.label }}<br>
|
||||
{{ form.name(size=32) }}<br>
|
||||
{% for error in form.name.errors %}
|
||||
<span style="color: red;">[{{ error }}]</span><br>
|
||||
{% endfor %}
|
||||
<br>
|
||||
{{ form.create() }}
|
||||
<br>
|
||||
</p>
|
||||
</form>
|
||||
<br> </center></p>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
10
src/templates/kick.html
Normal file
10
src/templates/kick.html
Normal file
|
@ -0,0 +1,10 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="button top">
|
||||
<a href="{{ url_for('join') }}">Back</a>
|
||||
</div>
|
||||
<div class="subttl">
|
||||
<p>You have been kicked. </p>
|
||||
</div>
|
||||
{% endblock %}
|
10
src/templates/nametaken.html
Normal file
10
src/templates/nametaken.html
Normal file
|
@ -0,0 +1,10 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="button top">
|
||||
<a href="{{ url_for('join') }}">Back</a>
|
||||
</div>
|
||||
<div class="subttl">
|
||||
<p>Name is already taken.</p>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,9 +1,42 @@
|
|||
{% extends "base.html" %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
{% if title %}
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="/static/favicon.ico" />
|
||||
<link rel="stylesheet" href="/static/index.css?version={{ version }}">
|
||||
<title>{{ title }} - Buzzer! </title>
|
||||
</head>
|
||||
{% else %}
|
||||
<head>
|
||||
<title> Buzzer! </title>
|
||||
<link rel="shortcut icon" type="image/x-icon" href="/static/favicon.ico" />
|
||||
<link rel="stylesheet" href="/static/index.css?version={{ version }}">
|
||||
</head>
|
||||
{% endif %}
|
||||
<body class="wrap">
|
||||
<div class="subttl">
|
||||
<h1> Play! </h1>
|
||||
</div>
|
||||
|
||||
{% block content %}
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js" integrity="sha256-yr4fRk/GU1ehYJPAs8P4JlTgu0Hdsp4ZKrx8bDEDC3I=" crossorigin="anonymous"></script>
|
||||
<script src="/static/game.js" type="text/javascript" charset="utf-8"></script>
|
||||
<br><input type="hidden" id="code" name="code" value="{{ gamecode }}"><br>
|
||||
<br><input type="hidden" id="name" name="name" value="{{ username }}">
|
||||
<br><input type="hidden" id="kick" name="kick" value="{{ url_for('kick') }}">
|
||||
<div class="sidebar" id="sidebar">
|
||||
</div>
|
||||
<div id="game">
|
||||
<center>
|
||||
<div class="form name">
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
<div class="button buzzer">
|
||||
<a onclick="buzz();">BUZZ! [SPACE]</a>
|
||||
</div>
|
||||
</center>
|
||||
</div>
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js" integrity="sha256-yr4fRk/GU1ehYJPAs8P4JlTgu0Hdsp4ZKrx8bDEDC3I=" crossorigin="anonymous"></script>
|
||||
<script src="/static/game.js?version={{ version }}" type="text/javascript" charset="utf-8"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
9
src/templates/please.html
Normal file
9
src/templates/please.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="button top">
|
||||
<a href="{{ url_for('join') }}">Back</a>
|
||||
</div>
|
||||
<div class="title">
|
||||
<h1> Please join using the Join page. </h1>
|
||||
</div>
|
||||
{% endblock %}
|
Reference in New Issue
Block a user