Compare commits

..

15 Commits

Author SHA1 Message Date
a3f495f87b done with actions 2026-05-14 20:17:50 -05:00
5615622acc d
Some checks failed
build-service / build-and-release (push) Failing after 1m8s
2026-05-14 20:14:38 -05:00
b96f00c847 fixes
Some checks failed
build-service / build-and-release (push) Failing after 1m8s
2026-05-14 20:11:54 -05:00
85f8e6eded fixes
Some checks failed
build-service / build-and-release (push) Failing after 5s
2026-05-14 20:10:18 -05:00
20313de5dc added release
Some checks failed
build-service / Build aarch64-unknown-linux-gnu (push) Failing after 54s
build-service / Gitea Release (push) Has been cancelled
build-service / Build x86_64-unknown-linux-gnu (push) Has been cancelled
2026-05-14 20:06:11 -05:00
56275c7369 giving up if this doesn't work
All checks were successful
build-service / Build aarch64-unknown-linux-gnu (push) Successful in 59s
build-service / Build x86_64-unknown-linux-gnu (push) Successful in 40s
2026-05-14 20:03:31 -05:00
baad3d7791 gemini workflow change
Some checks failed
build-service / Build aarch64-unknown-linux-gnu (push) Failing after 1m38s
build-service / Build x86_64-unknown-linux-gnu (push) Successful in 43s
2026-05-14 19:59:28 -05:00
5211266f3a using ubuntu with rust install
Some checks failed
build-service / build (push) Failing after 1m2s
2026-05-14 19:55:59 -05:00
44fd16d9c7 fixed hopefuuly
Some checks failed
build-service / build (push) Failing after 1m5s
2026-05-14 19:53:20 -05:00
848ec596c6 uasing cross
Some checks failed
build-service / compile-binaries (push) Failing after 1m50s
2026-05-14 19:39:17 -05:00
e802c757f7 added workflow change
Some checks failed
build-service / compile-binaries (push) Failing after 1m1s
2026-05-14 19:36:12 -05:00
223b6d1640 ci: implement gitea actions pipeline and makefile
All checks were successful
build-service / compile-binaries (push) Successful in 2m40s
2026-05-14 19:13:05 -05:00
7232c56e4e added error handling, random input etc 2026-05-14 19:07:53 -05:00
59477c3ea7 added python files and fixed logs, gitignore 2026-05-14 18:58:30 -05:00
88b1cb8076 finished server main hopefully 2026-05-14 18:53:48 -05:00
4 changed files with 152 additions and 2 deletions

2
.gitignore vendored
View File

@@ -1 +1,3 @@
/target /target
**/.venv/**

16
python/admin.py Normal file
View File

@@ -0,0 +1,16 @@
import random
import socket
SERVER_IP = "127.0.0.1"
PORT = 5901
input = random.randint(1, 1000)
# Manually set the starting "input" for the first team
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((SERVER_IP, PORT))
# Using "0" as the ID for the very first team's source
s.send(f"ADMIN SET 0 {input}".encode()) # Sets the first clue as 80
print(f"Input of {input} Set")
print(s.recv(1024).decode())
s.close()

30
python/team.py Normal file
View File

@@ -0,0 +1,30 @@
import socket
# Config
SERVER_IP = "127.0.0.1" # Change to master server's IP
PORT = 5901
MY_ID = "1" # Team Number
PREV_ID = "0" # Team Number of Team Sending Clue (should be previous team, but in case of abscences)
# 1. GET: Wait for input
print(f"Waiting for Team {PREV_ID}...")
while True:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((SERVER_IP, PORT))
s.send(f"GET {PREV_ID}".encode())
input = s.recv(1024).decode().strip() # Clue is called input in the code
s.close()
if input != "-1": # -1 Means Clue Is Not Yet Sent
print(f"Received input: {input}")
break
# 2. TRANSFORM: Do your logic to convert input to output clue, which should also be an integer Number
output = int(input) + 42
# 3. PUT: Send output
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((SERVER_IP, PORT))
s.send(f"PUT {MY_ID} {output}".encode())
s.close()
print(f"Sent output: {output}")

View File

@@ -1,3 +1,105 @@
fn main() { use std::collections::HashMap;
println!("Hello, world!"); use std::sync::Arc;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::{TcpListener, TcpStream};
use tokio::sync::RwLock; // Use Tokio's async-aware lock
// Type alias for our shared thread-safe state
type Db = Arc<RwLock<HashMap<String, String>>>;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Bind to all interfaces on port 5901
let listener = TcpListener::bind("0.0.0.0:5901").await?;
let db: Db = Arc::new(RwLock::new(HashMap::new()));
println!("🚀 Escape Room Server active on port 5901");
println!("Waiting for teams to connect...");
loop {
let (socket, _) = listener.accept().await?;
let db_clone = Arc::clone(&db);
// Spawn a new async task for every connection
tokio::spawn(async move {
if let Err(e) = handle_connection(socket, db_clone).await {
eprintln!("[SOCKET ERROR] {}", e);
} }
});
}
}
async fn handle_connection(mut socket: TcpStream, db: Db) -> std::io::Result<()> {
let mut buf = [0; 1024];
let n = socket.read(&mut buf).await?;
if n == 0 {
return Ok(());
}
let request = String::from_utf8_lossy(&buf[..n]);
let parts: Vec<&str> = request.trim().split_whitespace().collect();
if parts.is_empty() {
return Ok(());
}
match parts[0].to_uppercase().as_str() {
"PUT" => {
if parts.len() == 3 {
let team_id = parts[1].to_string();
let val_str = parts[2];
// Validate if the value is an integer
if val_str.parse::<i32>().is_ok() {
let mut data = db.write().await;
data.insert(team_id.clone(), val_str.to_string());
socket.write_all(b"ACK\n").await?;
println!("[LOG] Team {} submitted solution: {}", team_id, val_str);
} else {
// Send error but don't stop the server
socket.write_all(b"ERR_NOT_AN_INT\n").await?;
println!("[WARN] Team {} tried to send non-int: {}", team_id, val_str);
}
}
}
"GET" => {
if parts.len() == 2 {
let target_id = parts[1];
let data = db.read().await;
let response = data
.get(target_id)
.cloned()
.unwrap_or_else(|| "-1".to_string());
socket.write_all(response.as_bytes()).await?;
}
}
"ADMIN" => {
if parts.len() == 4 && parts[1].to_uppercase() == "SET" {
let team_id = parts[2].to_string();
let val_str = parts[3];
if val_str.parse::<i32>().is_ok() {
let mut data = db.write().await;
data.insert(team_id.clone(), val_str.to_string());
socket.write_all(b"ADMIN_OK\n").await?;
println!("[ADMIN] Manual set: Team {} -> {}", team_id, val_str);
} else {
socket.write_all(b"ADMIN_ERR_NOT_AN_INT\n").await?;
println!("[ADMIN] Manual set failed: {} is not an int", val_str);
}
}
}
_ => {
socket.write_all(b"ERR_INVALID_CMD\n").await?;
}
}
Ok(())
}