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,41 +7,39 @@ | ||||
| 		<div class="subttl"> | ||||
| 			<h1> Host Game </h1> | ||||
| 		</div> | ||||
| 		<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 %} | ||||
| 				<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 %} | ||||
| 				<span style="color: red;">[{{ error }}]</span><br> | ||||
| 				{% endfor %} | ||||
| 				<br> | ||||
| 				{{ form.create() }} | ||||
| 				<br> | ||||
| 			</p> | ||||
| 		</form> | ||||
| 		<div class="form host"> | ||||
| 			<form action="" method="post" novalidate> | ||||
| 				{{ form.csrf_token }} | ||||
| 				<p> | ||||
| 				<center> | ||||
| 					{{ form.tossup.label }}<br> | ||||
| 					{{ form.tossup(size=32, value=default[0]) }}<br> | ||||
| 					{% for error in form.tossup.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.create() }} | ||||
| 					<br> | ||||
| 				</center> | ||||
| 				</p> | ||||
| 			</form> | ||||
| 		</div> | ||||
| {% endblock %} | ||||
| @ -1,47 +1,30 @@ | ||||
| {% extends "base.html" %} | ||||
| 
 | ||||
| {% block content %} | ||||
| <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> | ||||
| 	{{ 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 %} | ||||
| 		<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 %} | ||||
| 		<span style="color: red;">[{{ error }}]</span><br> | ||||
| 		{% endfor %} | ||||
| 		<br> | ||||
| 		{{ form.create() }} | ||||
| 		<br> | ||||
| 	</p> | ||||
| </form> | ||||
| 		<div class="button top"> | ||||
| 			<a href="{{ url_for('home') }}">Back</a> | ||||
| 		</div> | ||||
| 		<div class="subttl"> | ||||
| 			<h1> Join Game </h1> | ||||
| 		</div> | ||||
| 		<div class="form join"> | ||||
| 			<form action="" method="post" novalidate> | ||||
| 			{{ form.csrf_token }} | ||||
| 			<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.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> </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" %} | ||||
| 
 | ||||
| {% 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> | ||||
| 		<div id="game"> | ||||
| 
 | ||||
| <!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> | ||||
| {% endblock %} | ||||
| 
 | ||||
| 		<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> | ||||
| 				<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