header cleanup + fixes + websocket moves
This commit is contained in:
parent
b407bee0c9
commit
0924b4ee45
118
main.py
118
main.py
|
@ -1,25 +1,34 @@
|
||||||
# Python
|
# Python
|
||||||
from flask import Flask, render_template, request
|
from flask import Flask, render_template, request
|
||||||
|
from flask_socketio import SocketIO, join_room
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
ozai_url = 'http://localhost:8000/api/'
|
ozai_url = 'http://localhost:8000/api/'
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
socketio = SocketIO(app)
|
||||||
|
|
||||||
# @app.route('/azul.webp')
|
#get tis from env variable
|
||||||
# def background():
|
import os
|
||||||
# #return the background image
|
app.config['SECRET_KEY'] = os.environ.get('OZAI_WEBUI_SECRET_KEY')
|
||||||
# return app.send_static_file('azul.webp')
|
|
||||||
|
|
||||||
|
|
||||||
|
#home page
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def home():
|
def home():
|
||||||
return render_template('home.html')
|
return render_template('home.html')
|
||||||
|
|
||||||
|
#static files
|
||||||
@app.route('/azul.webp')
|
@app.route('/azul.webp')
|
||||||
def background():
|
def background():
|
||||||
#return the background image
|
#return the background image
|
||||||
return app.send_static_file('azul.webp')
|
return app.send_static_file('azul.webp')
|
||||||
|
@app.route('/azul-flake.png')
|
||||||
|
def logo():
|
||||||
|
#return the background image
|
||||||
|
return app.send_static_file('azul-flake.png')
|
||||||
|
|
||||||
|
|
||||||
|
#game creation page
|
||||||
@app.route('/create', methods=['GET', 'POST'])
|
@app.route('/create', methods=['GET', 'POST'])
|
||||||
def create():
|
def create():
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
@ -57,6 +66,7 @@ def create():
|
||||||
return render_template('create.html')
|
return render_template('create.html')
|
||||||
|
|
||||||
|
|
||||||
|
#join page, for when the user has gotten a game id.
|
||||||
@app.route('/join', methods=['GET', 'POST'])
|
@app.route('/join', methods=['GET', 'POST'])
|
||||||
def join():
|
def join():
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
@ -65,7 +75,7 @@ def join():
|
||||||
return render_template('join.html', game_id=game_id)
|
return render_template('join.html', game_id=game_id)
|
||||||
return render_template('join.html')
|
return render_template('join.html')
|
||||||
|
|
||||||
|
#select player name page
|
||||||
@app.route('/join_game/<game_id>/', methods=['GET','POST'])
|
@app.route('/join_game/<game_id>/', methods=['GET','POST'])
|
||||||
def join_game(game_id):
|
def join_game(game_id):
|
||||||
|
|
||||||
|
@ -85,49 +95,67 @@ def join_game(game_id):
|
||||||
return render_template('join_game.html', game_id=game_id, players=players)
|
return render_template('join_game.html', game_id=game_id, players=players)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/game/<game_id>/player/<player_name>', methods=['GET', 'POST'])
|
#play game page
|
||||||
|
@app.route('/game/<game_id>/player/<player_name>', methods=['GET'])
|
||||||
def game(game_id, player_name):
|
def game(game_id, player_name):
|
||||||
gamestate = requests.get(ozai_url + 'game/' + game_id).json()
|
gamestate = requests.get(ozai_url + 'game/' + game_id).json()
|
||||||
move_status = False
|
#dont send player parameter if the player is a spectator
|
||||||
|
if player_name == 'spectator':
|
||||||
|
gamestate = requests.get(ozai_url + 'game/' + game_id).json()
|
||||||
|
return render_template('game.html', game_id=game_id, gamestate=gamestate)
|
||||||
|
elif player_name in gamestate['players']:
|
||||||
|
gamestate = requests.get(ozai_url + 'game/' + game_id + '?player=' + player_name).json()
|
||||||
|
return render_template('game.html', game_id=game_id, gamestate=gamestate, player_name=player_name)
|
||||||
|
else:
|
||||||
|
return 'Player not found', 404
|
||||||
|
|
||||||
|
|
||||||
|
@socketio.on('connect')
|
||||||
|
def ws_connect(message):
|
||||||
|
print('Client connected' + str(message))
|
||||||
|
pass
|
||||||
|
|
||||||
|
@socketio.on('join')
|
||||||
|
def ws_message(message):
|
||||||
|
print('Client message' + str(message))
|
||||||
|
game_id = message['game_id']
|
||||||
|
print('Game ID: ', game_id)
|
||||||
|
join_room(game_id)
|
||||||
|
|
||||||
|
@socketio.on('move')
|
||||||
|
def ws_message(data):
|
||||||
|
print('Client move' + str(data))
|
||||||
|
|
||||||
|
game_id = data['game_id']
|
||||||
|
player_name = data['player_name']
|
||||||
|
|
||||||
#if a move was made.
|
#if a move was made.
|
||||||
if request.method == 'POST':
|
source = data['move']['source']
|
||||||
|
color = data['move']['color']
|
||||||
source = request.form['source']
|
destination = data['move']['destination']
|
||||||
color = request.form['color']
|
if source != "market":
|
||||||
destination = request.form['destination']
|
source = int(source)-1
|
||||||
|
if destination != "floor":
|
||||||
if source != "market":
|
destination = int(destination)-1
|
||||||
source = int(source)-1
|
move = {
|
||||||
if destination != "floor":
|
'player': str(player_name),
|
||||||
destination = int(destination)-1
|
'policy': 'strict', # or 'loose' depending on your needs
|
||||||
|
'color': str(color),
|
||||||
|
'source': source,
|
||||||
|
'destination': destination
|
||||||
|
}
|
||||||
|
print(move)
|
||||||
|
response = requests.put(ozai_url + 'game/' + game_id, json=move)
|
||||||
|
if response.status_code == 200:
|
||||||
|
socketio.emit('move', data, room=game_id)
|
||||||
|
#send message to the other players, that the move was made
|
||||||
|
socketio.emit('move_status', 'sucsess', room=game_id)
|
||||||
|
else:
|
||||||
|
#send message to the player that the move was invalid
|
||||||
|
socketio.emit('move_status', response.text, room=game_id)
|
||||||
|
|
||||||
move = {
|
|
||||||
'player': str(player_name),
|
|
||||||
'policy': 'strict', # or 'loose' depending on your needs
|
|
||||||
'color': str(color),
|
|
||||||
'source': source,
|
|
||||||
'destination': destination
|
|
||||||
}
|
|
||||||
|
|
||||||
print(move)
|
|
||||||
response = requests.put(ozai_url + 'game/' + game_id, json=move)
|
|
||||||
if response.status_code == 200:
|
|
||||||
move_status = "Move Successful"
|
|
||||||
else:
|
|
||||||
move_status = response.text
|
|
||||||
|
|
||||||
#dont send player parameter if the player is a spectator
|
|
||||||
while True:
|
|
||||||
if player_name == 'spectator':
|
|
||||||
gamestate = requests.get(ozai_url + 'game/' + game_id).json()
|
|
||||||
return render_template('game.html', game_id=game_id, gamestate=gamestate)
|
|
||||||
elif player_name in gamestate['players']:
|
|
||||||
gamestate = requests.get(ozai_url + 'game/' + game_id + '?player=' + player_name).json()
|
|
||||||
return render_template('game.html', game_id=game_id, gamestate=gamestate, player_name=player_name, move_status=move_status)
|
|
||||||
else:
|
|
||||||
return 'Player not found', 404
|
|
||||||
return 'Player not found', 404
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(debug=True, host='0.0.0.0', port=5000)
|
# app.run(debug=True, host='0.0.0.0', port=5000,ssl_context='adhoc')
|
||||||
|
|
||||||
|
socketio.run(app, debug=True, host='0.0.0.0', port=5000)
|
Binary file not shown.
After Width: | Height: | Size: 5.4 KiB |
|
@ -2,7 +2,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Create Game</title>
|
<title>Ozai:create</title>
|
||||||
|
<link rel="icon" type="image/png" href="/azul-flake.png">
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -11,11 +12,12 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-left: 20vw;
|
margin-left: 20vw;
|
||||||
width: 60vw;
|
width: 60vw;
|
||||||
background: url({{ url_for('static', filename='azul.webp') }}) no-repeat center center fixed;
|
/* removed due to low visibility */
|
||||||
|
/* background: url({{ url_for('static', filename='azul.webp') }}) no-repeat center center fixed;
|
||||||
-webkit-background-size: cover;
|
-webkit-background-size: cover;
|
||||||
-moz-background-size: cover;
|
-moz-background-size: cover;
|
||||||
-o-background-size: cover;
|
-o-background-size: cover;
|
||||||
background-size: cover;
|
background-size: cover; */
|
||||||
}
|
}
|
||||||
|
|
||||||
form {
|
form {
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Game</title>
|
<title>Ozai:game</title>
|
||||||
|
<link rel="icon" type="image/png" href="/azul-flake.png">
|
||||||
<style>
|
<style>
|
||||||
a {
|
a {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -233,13 +234,13 @@
|
||||||
<div class="flex-col">
|
<div class="flex-col">
|
||||||
<!-- <h3>Pattern Lines</h3> -->
|
<!-- <h3>Pattern Lines</h3> -->
|
||||||
{% for line in player_data.pattern_lines %}
|
{% for line in player_data.pattern_lines %}
|
||||||
<div class="pattern_line">
|
<div class="pattern_line" onclick="selectPatternLine(this)" value="{{loop.index}}">
|
||||||
<!-- TODO: Fix this to not fill empty spaces. -->
|
<!-- TODO: Fix this to not fill empty spaces. -->
|
||||||
{% for i in range(0, loop.index) %}
|
{% for i in range(0, loop.index) %}
|
||||||
{% if line.number > i %}
|
{% if line.number > i %}
|
||||||
<div class="{{ line.color }}">{{ line.color[:1] }}</div>
|
<div class="{{ line.color }}" >{{ line.color[:1] }}</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div>_</div>
|
<div >_</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -269,7 +270,7 @@
|
||||||
<div style="width: 0.7em;">3</div>
|
<div style="width: 0.7em;">3</div>
|
||||||
<div style="width: 0.7em;">3</div>
|
<div style="width: 0.7em;">3</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="floor">
|
<div class="floor" onclick="selectPatternLine(this)" value="floor">
|
||||||
{% set floor_count = 0 %}
|
{% set floor_count = 0 %}
|
||||||
{% for color, number in player_data.floor.items() %}
|
{% for color, number in player_data.floor.items() %}
|
||||||
{% if number > 0 %}
|
{% if number > 0 %}
|
||||||
|
@ -298,12 +299,12 @@
|
||||||
<h1>Play area</h1>
|
<h1>Play area</h1>
|
||||||
<p>Playing as: {{ player_name }}</p>
|
<p>Playing as: {{ player_name }}</p>
|
||||||
<!-- form for submitting a move, a move is a selection of marcet or factory, what color, and what patternline or floor it goes to. -->
|
<!-- form for submitting a move, a move is a selection of marcet or factory, what color, and what patternline or floor it goes to. -->
|
||||||
<form action="/game/{{ game_id }}/player/{{ player_name }}" method="POST">
|
<form id='moveForm'</form>>
|
||||||
<label for="source">Source:</label>
|
<label for="source">Source:</label>
|
||||||
<select id="source" name="source">
|
<select id="source" name="source">
|
||||||
<option value="market">Market {{ gamestate.market }}</option>
|
<option value="market">Market</option>
|
||||||
{% for factory in gamestate.factories %}
|
{% for factory in gamestate.factories %}
|
||||||
<option value="{{ loop.index }}">Factory {{ loop.index }} ({{ factory }})</option>
|
<option value="{{ loop.index }}">Factory {{ loop.index }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
@ -333,14 +334,12 @@
|
||||||
{% set next_index = current_index + 1 if current_index + 1 < gamestate.player_names|length else 0 %}
|
{% set next_index = current_index + 1 if current_index + 1 < gamestate.player_names|length else 0 %}
|
||||||
<a href="/game/{{ game_id }}/player/{{ gamestate.player_names[next_index] }}">Next Player</a>
|
<a href="/game/{{ game_id }}/player/{{ gamestate.player_names[next_index] }}">Next Player</a>
|
||||||
|
|
||||||
{% if move_status %}
|
|
||||||
<div>{{ move_status }}</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.1.3/socket.io.js"></script>
|
||||||
<script>
|
<script>
|
||||||
console.log('Game ID: {{ game_id }}');
|
console.log('Game ID: {{ game_id }}');
|
||||||
console.log('Player Name: {{ player_name }}');
|
console.log('Player Name: {{ player_name }}');
|
||||||
|
@ -370,18 +369,46 @@
|
||||||
//set the selected attribute to true
|
//set the selected attribute to true
|
||||||
sourceOption.selected = true;
|
sourceOption.selected = true;
|
||||||
colorOption.selected = true;
|
colorOption.selected = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function select_pattern_line(pattern_line) {
|
function selectPatternLine(pattern_line) {
|
||||||
pattern_line = pattern_line.getAttribute('pattern_line');
|
//get the value of the pattern line element
|
||||||
console.log('Selected pattern line: ' + pattern_line);
|
value = pattern_line.getAttribute('value');
|
||||||
|
console.log('Selected pattern line: ' + pattern_line + ' with value: ' + value);
|
||||||
var destinationElement = document.getElementById('destination');
|
var destinationElement = document.getElementById('destination');
|
||||||
var destinationOption = destinationElement.querySelector('option[value="' + pattern_line + '"]');
|
var destinationOption = destinationElement.querySelector('option[value="' + value + '"]');
|
||||||
destinationOption.selected = true;
|
destinationOption.selected = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// refresh the page by listening to websocket events
|
||||||
|
|
||||||
|
game_id = '{{ game_id }}';
|
||||||
|
player_name = '{{ player_name }}';
|
||||||
|
|
||||||
|
var socket = io();
|
||||||
|
|
||||||
|
// send a message to the server in the message name space
|
||||||
|
socket.emit('join', {game_id: game_id});
|
||||||
|
|
||||||
|
socket.addEventListener('move', function (event) {
|
||||||
|
console.log('Game update received: ' + event);
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
|
||||||
|
// if we wana go over to using websocket entirely to send the move
|
||||||
|
let form = document.querySelector('#moveForm');
|
||||||
|
form.addEventListener('submit', function(event) {
|
||||||
|
// Prevent the form from being submitted normally
|
||||||
|
event.preventDefault();
|
||||||
|
// Create a FormData object from the form
|
||||||
|
let formData = new FormData(form);
|
||||||
|
// Convert the FormData to a plain object
|
||||||
|
let data = {};
|
||||||
|
formData.forEach((value, key) => data[key] = value);
|
||||||
|
console.log(data);
|
||||||
|
socket.emit('move', {game_id: game_id, player_name, move: data});
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Ozai webui:home</title>
|
<title>Ozai:home</title>
|
||||||
|
<link rel="icon" type="image/png" href="/azul-flake.png">
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -2,9 +2,21 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Ozai webui:Join Game</title>
|
<title>Ozai:Join</title>
|
||||||
|
<link rel="icon" type="image/png" href="/azul-flake.png">
|
||||||
<style>
|
<style>
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 10px;
|
||||||
|
background: url({{ url_for('static', filename='azul.webp') }}) no-repeat center center fixed;
|
||||||
|
-webkit-background-size: cover;
|
||||||
|
-moz-background-size: cover;
|
||||||
|
-o-background-size: cover;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -12,6 +12,10 @@
|
||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
|
|
Loading…
Reference in New Issue