define uuid for players

This commit is contained in:
Thilo Behnke
2022-06-23 20:23:32 +02:00
parent 407f03c540
commit 5c99bd761d
9 changed files with 57 additions and 29 deletions

View File

@@ -9,7 +9,6 @@
import SessionWrapper from "./components/SessionWrapper.svelte";
import api from "./api/session";
import Error from "./components/Error.svelte";
import session from "./api/session";
let error: string = null;
let errorAt: number = null;

View File

@@ -66,17 +66,12 @@ async function sessionResponseHandler(response: Response): Promise<NetworkSessio
return response.json().then(({data}) => {
console.debug(`session action result: ${JSON.stringify(data)}`)
return data;
}).then((event: NetworkSessionEventPayload) => event.session);
}).then((event: NetworkSessionEventPayload) => ({you: event.actor, ...event.session}));
}
async function createEventWebsocket(session: Session): Promise<WebSocket> {
return new Promise((res, rej) => {
if (session.type === SessionType.LOCAL) {
return rej("Websocket not allowed for local session!");
}
const url = `/pong/ws?session_id=${session.session_id}&connection_type=${session.type.toLowerCase()}`;
return createWebsocket(url);
})
async function createEventWebsocket(session: NetworkSession): Promise<WebSocket> {
const url = `/pong/ws?session_id=${session.session_id}&player_id=${session.you.id}&connection_type=${session.type.toLowerCase()}`;
return createWebsocket(url);
}
async function createWebsocket(path: string): Promise<WebSocket> {

View File

@@ -16,7 +16,7 @@
if (!window.location.search.startsWith("?")) {
return;
}
const params = window.location.search.slice(1).split("?").map(p => p.split('=')).reduce((acc, [key, val]) => ({...acc, [key]: val}), {}) as any;
const params = window.location.search.slice(1).split("&").map(p => p.split('=')).reduce((acc, [key, val]) => ({...acc, [key]: val}), {}) as any;
console.log(params)
if (!params.session_id) {
return;

View File

@@ -29,3 +29,11 @@ export type NetworkSession = {
you: Player
}
export type Session = LocalSession | NetworkSession;
export function isNetworkSession(session: Session): session is NetworkSession {
return !isLocalSession(session)
}
export function isLocalSession(session: Session): session is LocalSession {
return session.type === SessionType.LOCAL
}

View File

@@ -2,8 +2,8 @@ import {derived, get, readable, Readable, writable} from "svelte/store";
import {keysPressed} from "./io";
import {onDestroy} from "svelte";
import api from "../api/session";
import type {Session} from "./model/session";
import {SessionType} from "./model/session";
import type {NetworkSession, Session} from "./model/session";
import {isLocalSession, SessionType} from "./model/session";
export type Input = {
input: 'UP' | 'DOWN',
@@ -43,7 +43,7 @@ const player2KeyboardInputs = derived(
}
)
const sessionEvents = (session: Session) => readable([], function(set) {
const networkSessionEvents = (session: Session) => readable([], function(set) {
const websocket = writable<WebSocket>(null);
api.createEventWebsocket(session).then(ws => {
websocket.set(ws);
@@ -70,12 +70,12 @@ const sessionEvents = (session: Session) => readable([], function(set) {
}
})
const inputEvents = (session: Session): Readable<unknown[]> => derived(sessionEvents(session), $sessionEvents => $sessionEvents.filter(({input}) => input === 'topic'));
const networkInputEvents = (session: NetworkSession): Readable<unknown[]> => derived(networkSessionEvents(session), $sessionEvents => $sessionEvents.filter(({input}) => input === 'topic'));
export const sessionInputs = (session: Session) => readable([], function(setInputs) {
let player1Inputs = writable([]);
let player2Inputs = writable([]);
if (session.type === SessionType.LOCAL) {
if (isLocalSession(session)) {
player1KeyboardInputs.subscribe(inputs => {
player1Inputs.set(inputs)
setInputs([...get(player1Inputs), ...get(player2Inputs)])
@@ -87,12 +87,13 @@ export const sessionInputs = (session: Session) => readable([], function(setInpu
return () => {
}
}
if (session.type === SessionType.HOST) {
player1KeyboardInputs.subscribe(inputs => {
player1Inputs.set(inputs)
setInputs([...get(player1Inputs), ...get(player2Inputs)])
})
inputEvents(session).subscribe(inputs => {
networkInputEvents(session).subscribe(inputs => {
player2Inputs.set(inputs)
setInputs([...get(player1Inputs), ...get(player2Inputs)])
})
@@ -100,7 +101,7 @@ export const sessionInputs = (session: Session) => readable([], function(setInpu
}
}
if (session.type === SessionType.PEER) {
inputEvents(session).subscribe(inputs => {
networkInputEvents(session).subscribe(inputs => {
player1Inputs.set(inputs)
setInputs([...get(player1Inputs), ...get(player2Inputs)])
})
@@ -112,7 +113,7 @@ export const sessionInputs = (session: Session) => readable([], function(setInpu
}
}
if (session.type === SessionType.OBSERVER) {
const events = inputEvents(session);
const events = networkInputEvents(session);
events.subscribe(inputs => {
player1Inputs.set(inputs)
setInputs([...get(player1Inputs), ...get(player2Inputs)])

View File

@@ -17,6 +17,7 @@ pong = { path = "../pong", version = "0.1.0" }
hyper-tungstenite = "0.8.0"
futures = { version = "0.3.12" }
async-trait = "0.1.56"
uuid = { version = "1.1.2", features = ["v4"] }
[dev-dependencies]
rstest = "0.12.0"

View File

@@ -1,4 +1,5 @@
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(tag = "actor_type")]
@@ -19,6 +20,18 @@ impl Actor {
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Player {
pub id: String,
pub ip: String,
pub nr: u8
}
impl Player {
pub fn new(nr: u8, ip: String) -> Player {
Player {
ip,
id: Uuid::new_v4().to_string(),
nr
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]

View File

@@ -4,6 +4,7 @@ use std::str::FromStr;
use std::sync::Arc;
use futures::{stream::StreamExt};
use futures::future::err;
use hyper::{Body, Request, Response, Server, StatusCode};
use hyper::server::conn::AddrStream;
use hyper::service::{make_service_fn, service_fn};
@@ -82,6 +83,13 @@ async fn handle_potential_ws_upgrade(session_manager: Arc<Mutex<SessionManager>>
StatusCode::BAD_REQUEST,
);
}
if !params.contains_key("player_id") {
eprintln!("Missing player id request param for websocket connection, don't upgrade connection to ws.");
return build_error_res(
"Missing request param: player_id",
StatusCode::BAD_REQUEST,
);
}
if !params.contains_key("connection_type") {
eprintln!("Missing connection type request param for websocket connection, don't upgrade connection to ws.");
let res = build_error_res(
@@ -90,11 +98,12 @@ async fn handle_potential_ws_upgrade(session_manager: Arc<Mutex<SessionManager>>
);
return res;
}
let session_id = params.get("session_id").unwrap();
let request_player_id = addr.ip().to_string();
let session = session_manager.lock().await.get_session(session_id);
let request_session_id = *params.get("session_id").unwrap();
let request_player_id = *params.get("player_id").unwrap();
let request_player_ip = addr.ip().to_string();
let session = session_manager.lock().await.get_session(request_session_id);
if let None = session {
let error = format!("Session does not exist: {}", session_id);
let error = format!("Session does not exist: {}", request_session_id);
eprintln!("{}", error);
return build_error_res(error.as_str(), StatusCode::NOT_FOUND);
}
@@ -105,6 +114,12 @@ async fn handle_potential_ws_upgrade(session_manager: Arc<Mutex<SessionManager>>
eprintln!("{}", error);
return build_error_res(error.as_str(), StatusCode::FORBIDDEN);
}
let matching_player = matching_player.unwrap();
if matching_player.ip != request_player_ip {
let error = format!("Player with wrong ip tried to join session: {} (expected) vs {} (actual)", matching_player.ip, request_player_ip);
eprintln!("{}", error);
return build_error_res(error.as_str(), StatusCode::FORBIDDEN);
}
let connection_type_raw = params.get("connection_type").unwrap();
let connection_type =
WebSocketConnectionType::from_str(connection_type_raw);

View File

@@ -71,9 +71,7 @@ async fn handle_session_create(
) -> Result<Response<Body>, Infallible> {
println!("Called to create new session: {:?}", req);
let mut locked = session_manager.lock().await;
let player = Player {
id: addr.ip().to_string(),
};
let player = Player::new(1, addr.ip().to_string());
let session_create_res = locked.create_session(player.clone()).await;
if let Err(e) = session_create_res {
return Ok(Response::builder()
@@ -99,9 +97,7 @@ async fn handle_session_join(
println!("Received request to join session: {:?}", req);
let mut locked = session_manager.lock().await;
let body = read_json_body::<SessionJoinDto>(&mut req).await;
let player = Player {
id: addr.ip().to_string()
};
let player = Player::new(2, addr.ip().to_string());
let session_join_res = locked.join_session(body.session_id, player.clone()).await;
if let Err(e) = session_join_res {
eprintln!("Failed to join session: {:?}", e);