Add changing gamemode
This commit is contained in:
@@ -5,6 +5,7 @@ import dbus
|
|||||||
from urllib.parse import parse_qs
|
from urllib.parse import parse_qs
|
||||||
from ac_tracks import change_track, get_all_tracks, get_configs, get_preview_image, get_outline_image, get_current_track
|
from ac_tracks import change_track, get_all_tracks, get_configs, get_preview_image, get_outline_image, get_current_track
|
||||||
from ac_cars import get_all_cars, get_car_image, update_cars, get_current_cars
|
from ac_cars import get_all_cars, get_car_image, update_cars, get_current_cars
|
||||||
|
from ac_gamemodes import get_gamemodes, update_gamemodes
|
||||||
|
|
||||||
class Handler(BaseHTTPRequestHandler):
|
class Handler(BaseHTTPRequestHandler):
|
||||||
def do_GET(self):
|
def do_GET(self):
|
||||||
@@ -39,6 +40,8 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
return self.handle_get_current_cars_path()
|
return self.handle_get_current_cars_path()
|
||||||
if self.path == "/currenttrack":
|
if self.path == "/currenttrack":
|
||||||
return self.handle_get_current_track_path()
|
return self.handle_get_current_track_path()
|
||||||
|
if self.path == "/gamemodes":
|
||||||
|
return self.handle_get_gamemodes_path()
|
||||||
|
|
||||||
if self.path == "/" or self.path == "/index.html":
|
if self.path == "/" or self.path == "/index.html":
|
||||||
return self.handle_get_root_path()
|
return self.handle_get_root_path()
|
||||||
@@ -128,6 +131,22 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
self.wfile.write(json.dumps(data).encode())
|
self.wfile.write(json.dumps(data).encode())
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def handle_get_gamemodes_path(self):
|
||||||
|
gamemodes = get_gamemodes()
|
||||||
|
data = {
|
||||||
|
"gamemodes": {
|
||||||
|
"practice_minutes": gamemodes[0],
|
||||||
|
"qualify_minutes": gamemodes[1],
|
||||||
|
"race_laps": gamemodes[2]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header("Content-type", "application/json")
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(json.dumps(data).encode())
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def handle_get_root_path(self):
|
def handle_get_root_path(self):
|
||||||
with open("index.html", "r") as f:
|
with open("index.html", "r") as f:
|
||||||
html = f.read()
|
html = f.read()
|
||||||
@@ -149,6 +168,8 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
return self.handle_post_change_track()
|
return self.handle_post_change_track()
|
||||||
if (self.path.startswith("/changecars")):
|
if (self.path.startswith("/changecars")):
|
||||||
return self.handle_post_change_car()
|
return self.handle_post_change_car()
|
||||||
|
if (self.path.startswith("/changegamemodes")):
|
||||||
|
return self.handle_post_change_gamemodes()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def handle_post_change_track(self):
|
def handle_post_change_track(self):
|
||||||
@@ -214,6 +235,44 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
print("Invalid JSON received")
|
print("Invalid JSON received")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def handle_post_change_gamemodes(self):
|
||||||
|
length = int(self.headers.get("Content-Length", 0))
|
||||||
|
|
||||||
|
body = self.rfile.read(length).decode("utf-8")
|
||||||
|
|
||||||
|
import json
|
||||||
|
try:
|
||||||
|
data = json.loads(body)
|
||||||
|
gamemodes = data.get("gamemodes", {})
|
||||||
|
print("Received gamemodes:", gamemodes)
|
||||||
|
practice = gamemodes.get("practice_minutes", 0)
|
||||||
|
qualify = gamemodes.get("qualify_minutes", 0)
|
||||||
|
race = gamemodes.get("race_laps", 0)
|
||||||
|
success, message = update_gamemodes(practice, qualify, race)
|
||||||
|
if success:
|
||||||
|
success, message = restart_ac_server()
|
||||||
|
print(f"restart succeeded: {success}, {message}")
|
||||||
|
|
||||||
|
if success:
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header("Content-type", "application/json")
|
||||||
|
self.end_headers()
|
||||||
|
response = {"status": "success", "message": message}
|
||||||
|
self.wfile.write(json.dumps(response).encode())
|
||||||
|
else:
|
||||||
|
self.send_response(400)
|
||||||
|
self.send_header("Content-type", "application/json")
|
||||||
|
self.end_headers()
|
||||||
|
response = {"status": "error", "message": message}
|
||||||
|
self.wfile.write(json.dumps(response).encode())
|
||||||
|
return True
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
self.send_response(400)
|
||||||
|
self.send_header("Content-Type", "application/json")
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(b'{"error":"invalid json"}')
|
||||||
|
print("Invalid JSON received")
|
||||||
|
return False
|
||||||
|
|
||||||
def send_image(self, img_path: str):
|
def send_image(self, img_path: str):
|
||||||
if os.path.exists(img_path):
|
if os.path.exists(img_path):
|
||||||
|
|||||||
61
ac_gamemodes.py
Normal file
61
ac_gamemodes.py
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
CONFIG_FILE = "server_cfg.ini"
|
||||||
|
CONTENT_FOLDER = "/home/sem/assetto-corsa/content"
|
||||||
|
CONFIG_PATH = "/home/sem/assetto-corsa/cfg"
|
||||||
|
# CONTENT_FOLDER = "./content"
|
||||||
|
# CONFIG_PATH = "./cfg"
|
||||||
|
|
||||||
|
def get_gamemodes() -> list:
|
||||||
|
gamemodes = [0,0,0] # practice, qualify, race
|
||||||
|
index = 0
|
||||||
|
config_path = os.path.join(CONFIG_PATH, CONFIG_FILE)
|
||||||
|
with open(config_path,'r') as file:
|
||||||
|
for line in file:
|
||||||
|
line = line.strip()
|
||||||
|
if line.startswith("[PRACTICE]"):
|
||||||
|
index = 0
|
||||||
|
elif line.startswith("[QUALIFY]"):
|
||||||
|
index = 1
|
||||||
|
elif line.startswith("[RACE]"):
|
||||||
|
index = 2
|
||||||
|
elif line.startswith("TIME="):
|
||||||
|
gamemodes[index] = int(line.replace("TIME=","").strip())
|
||||||
|
elif line.startswith("LAPS="):
|
||||||
|
gamemodes[index] = int(line.replace("LAPS=","").strip())
|
||||||
|
print(f"loaded gamemodes: {gamemodes}")
|
||||||
|
return gamemodes
|
||||||
|
|
||||||
|
def update_gamemodes(practice: int, qualify: int, race: int) -> tuple[bool, str]:
|
||||||
|
print(f"updating gamemodes to practice: {practice}, qualify: {qualify}, race: {race}")
|
||||||
|
new_content = ""
|
||||||
|
config_path = os.path.join(CONFIG_PATH, CONFIG_FILE)
|
||||||
|
with open(config_path,'r') as file:
|
||||||
|
in_practice = False
|
||||||
|
in_qualify = False
|
||||||
|
for line in file:
|
||||||
|
line = line.strip()
|
||||||
|
if line.startswith("[PRACTICE]"):
|
||||||
|
in_practice = True
|
||||||
|
in_qualify = False
|
||||||
|
if line.startswith("[QUALIFY]"):
|
||||||
|
in_practice = False
|
||||||
|
in_qualify = True
|
||||||
|
|
||||||
|
if line.startswith("TIME="):
|
||||||
|
if in_practice:
|
||||||
|
new_content += f"TIME={practice}"
|
||||||
|
print(f"changing line to TIME={practice}")
|
||||||
|
elif in_qualify:
|
||||||
|
new_content += f"TIME={qualify}"
|
||||||
|
print(f"changing line to TIME={qualify}")
|
||||||
|
elif line.startswith("LAPS="):
|
||||||
|
new_content += f"LAPS={race}"
|
||||||
|
print(f"changing line to LAPS={race}")
|
||||||
|
else:
|
||||||
|
new_content += line
|
||||||
|
new_content += "\n"
|
||||||
|
|
||||||
|
with open(config_path,'w') as file:
|
||||||
|
file.write(new_content)
|
||||||
|
return True, "Gamemodes updated successfully."
|
||||||
58
index.html
58
index.html
@@ -145,6 +145,13 @@
|
|||||||
<img id="outline" src="" width="400">
|
<img id="outline" src="" width="400">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<h1>Choose gamemode</h1>
|
||||||
|
<p>Set to 0 to disable</p>
|
||||||
|
<input type="number" class="practice-minutes" placeholder="Practice minutes">
|
||||||
|
<input type="number" class="qualify-minutes" placeholder="Qualify minutes">
|
||||||
|
<input type="number" class="race-laps" placeholder="Race laps">
|
||||||
|
<button onclick="applyGamemodes()">Apply</button>
|
||||||
|
|
||||||
<h1>Choose cars</h1>
|
<h1>Choose cars</h1>
|
||||||
<button id="addCarBtn">Add Car</button>
|
<button id="addCarBtn">Add Car</button>
|
||||||
<button id="applyCarsBtn">Change cars</button>
|
<button id="applyCarsBtn">Change cars</button>
|
||||||
@@ -222,6 +229,54 @@
|
|||||||
window.addEventListener('load', updateCurrentTrack, false); // NB **not** 'onload'
|
window.addEventListener('load', updateCurrentTrack, false); // NB **not** 'onload'
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<script>
|
||||||
|
function updateGameModes() {
|
||||||
|
fetch('/gamemodes')
|
||||||
|
.then(r => r.json())
|
||||||
|
.then(data => {
|
||||||
|
document.querySelector(".practice-minutes").value = data.gamemodes.practice_minutes;
|
||||||
|
document.querySelector(".qualify-minutes").value = data.gamemodes.qualify_minutes;
|
||||||
|
document.querySelector(".race-laps").value = data.gamemodes.race_laps;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyGamemodes() {
|
||||||
|
const practiceMinutes = document.querySelector(".practice-minutes").value || 0;
|
||||||
|
const qualifyMinutes = document.querySelector(".qualify-minutes").value || 0;
|
||||||
|
const raceLaps = document.querySelector(".race-laps").value || 0;
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
gamemodes: {
|
||||||
|
practice_minutes: parseInt(practiceMinutes),
|
||||||
|
qualify_minutes: parseInt(qualifyMinutes),
|
||||||
|
race_laps: parseInt(raceLaps)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetch("/changegamemodes", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify(payload)
|
||||||
|
})
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
console.log("Server response:", data);
|
||||||
|
if (data.status == "success") {
|
||||||
|
alert("Gamemodes changed successfully!");
|
||||||
|
} else {
|
||||||
|
alert("Failed to change gamemodes: " + data.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.addEventListener) // W3C standard
|
||||||
|
{
|
||||||
|
window.addEventListener('load', updateGameModes, false); // NB **not** 'onload'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const addCarBtn = document.getElementById("addCarBtn");
|
const addCarBtn = document.getElementById("addCarBtn");
|
||||||
const carList = document.getElementById("carList");
|
const carList = document.getElementById("carList");
|
||||||
@@ -237,7 +292,7 @@
|
|||||||
blocks.forEach(block => {
|
blocks.forEach(block => {
|
||||||
const carSelect = block.querySelector(".car-select");
|
const carSelect = block.querySelector(".car-select");
|
||||||
const skinSelect = block.querySelector(".skin-select");
|
const skinSelect = block.querySelector(".skin-select");
|
||||||
const amountInput = block.querySelector("input[type='number']");
|
const amountInput = block.querySelector(".amount-input");
|
||||||
|
|
||||||
const carName = carSelect?.value || "";
|
const carName = carSelect?.value || "";
|
||||||
const skinName = skinSelect?.value || "";
|
const skinName = skinSelect?.value || "";
|
||||||
@@ -310,6 +365,7 @@
|
|||||||
|
|
||||||
const amountSelect = document.createElement("input");
|
const amountSelect = document.createElement("input");
|
||||||
amountSelect.style.marginLeft = "10px";
|
amountSelect.style.marginLeft = "10px";
|
||||||
|
amountSelect.className = "amount-input";
|
||||||
amountSelect.type = "number";
|
amountSelect.type = "number";
|
||||||
amountSelect.min = "1";
|
amountSelect.min = "1";
|
||||||
if (amount > 0) {
|
if (amount > 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user