Skip to content

Commit

Permalink
Game server architectural changes (#196)
Browse files Browse the repository at this point in the history
* Player update

* PlayerLocation update

* Match update and addition of MatchLocation

* Replaced Scene class with a GameManager

* Added classes to handle events

* Added a ClientManager and removed the now useless Game class

* Added an AntiCheat class

* Updated Ball class

* Added Server class

* main now uses the new classes

* Updated utils and settings

* Updated documentation

* Updated client to work with the new server

* Fixed the test test_valid_tournament_request not sending a valid list of users
  • Loading branch information
V-Fries authored Feb 10, 2024
1 parent 3605db1 commit 5643b6b
Show file tree
Hide file tree
Showing 36 changed files with 783 additions and 675 deletions.
86 changes: 54 additions & 32 deletions front/src/threejs/Documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,46 +40,59 @@
>> debug_message: str
>> ```
>
>> Prints debug_message on `console.warn`
>> Prints debug_message on `console.log`
- ### `scene`:
>> Argument:
>> ```
>> {
>> 'scene': {
>> 'matches': [
>> "matches": [
>> {
>> 'position': {'x': float, 'y': float, 'z': float},
>> 'players': [
>> "location": {
>> "game_round": int,
>> "match": int
>> },
>> "position": {"x": float, "y": float, "z": float},
>> "players": [
>> {
>> 'position': {'x': float, 'y': float, 'z': float},
>> 'move_speed': float,
>> 'board': {
>> 'size': {'x': float, 'y': float, 'z': float}
>> "position": {"x": float, "y": float, "z": float}, // Relative to the match
>> "move_speed": float,
>> "board": {
>> // Position is [0, 0, 0] relative to the player
>> "size": {"x": float, "y": float, "z": float}
>> },
>> 'paddle': {
>> 'size': {'x': float, 'y': float, 'z': float},
>> 'position': {'x': float, 'y': float, 'z': float},
>> 'movement': {'x': float, 'y': float, 'z': float},
>> 'move_speed': float
>> "paddle": {
>> "size": {"x": float, "y": float, "z": float},
>> "position": {"x": float, "y": float, "z": float}, // Relative to the player
>> "movement": {"x": float, "y": float, "z": float},
>> "move_speed": float
>> }
>> },
>> ... (Should have at least 2 players)
>> ... second player
>> ],
>> 'ball': {
>> 'position': {'x': float, 'y': float, 'z': float},
>> 'movement': {'x': float, 'y': float, 'z': float},
>> 'radius': float
>> 'ball_is_waiting': bool,
>> 'ball_start_time': Optional[float] (Seconds since the Epoch),
>> }
>> "ball": {
>> "position": {"x": float, "y": float, "z": float}, // Relative to the match
>> "movement": {"x": float, "y": float, "z": float},
>> "radius": float,
>> "acceleration": float
>> },
>> "ball_is_waiting": bool,
>> "ball_start_time": Optinal[float] (Seconds since the Epoch)
>> }
>> ]
>> },
>> ],
>>
>> "loosers": [
>> (List of players with the same structure as the players in the matches exept the position is global)
>> ]
>> }
>>
>> 'player_location': { // Location of current client
>> 'is_in_a_match': bool,
>> 'match_index': int,
>> 'is_looser': bool,
>> 'match_location': {
>> 'game_round': int,
>> 'match': int
>> },
>> 'player_index': int
>> }
>> }
Expand All @@ -92,8 +105,11 @@
>> ```
>> {
>> 'player_location': {
>> 'is_in_a_match': bool,
>> 'match_index': int,
>> 'is_looser': bool,
>> 'match_location': {
>> 'game_round': int,
>> 'match': int
>> },
>> 'player_index': int
>> },
>> 'direction': str ('up' | 'down' | 'none'),
Expand All @@ -103,17 +119,20 @@
>
>> Updates the position and direction of the player at index player_index
- ### `update_ball`:
- ### `prepare_ball_for_match`:
>> Argument:
>> ```
>> {
>> 'match_index': int,
>> 'match_location': {
>> 'game_round': int,
>> 'match': int
>> },
>> 'ball_movement': {'x': float, 'y': float, 'z': float}
>> 'ball_start_time': float (Seconds since the Epoch),
>> }
>> ```
>
>> For the ball at `match[match_index]`:
>> For the ball at `matches[match_location]`:
>> Sets the ball position to `[0., 0., current_position.z]`.
>> Sets the ball movement to `'ball_movement'`
>> Stops the ball movement till `ball_start_time`
Expand All @@ -122,8 +141,11 @@
>> Argument:
>> ```
>> {
>> 'match_index': int,
>> 'position': {'x': float, 'y': float, 'z': float}
>> 'match_location': {
>> 'game_round': int,
>> 'match': int
>> },
>> 'position': {'x': float, 'y': float, 'z': float},
>> 'movement': {'x': float, 'y': float, 'z': float}
>> }
>> ```
Expand Down
12 changes: 6 additions & 6 deletions front/src/threejs/Engine/_KeyHookHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ export class _KeyHookHandler {
if (this.#serverKnownMovement !== 'none') {
const scene = this.#engine.scene;
const arg = {
'client_player_position': scene.getCurrentPlayerPaddlePositionAsArray(),
'client_paddle_position': scene.getCurrentPlayerPaddlePositionY(),
'direction': 'none',
};
await this.#engine.emit('update_player', arg);
await this.#engine.emit('update_paddle', arg);
this.#serverKnownMovement = 'none';
this.#engine.scene.setCurrentPlayerPaddleDirection('none');
}
Expand All @@ -111,10 +111,10 @@ export class _KeyHookHandler {
if (this.#serverKnownMovement !== 'up') {
const scene = this.#engine.scene;
const arg = {
'client_player_position': scene.getCurrentPlayerPaddlePositionAsArray(),
'client_paddle_position': scene.getCurrentPlayerPaddlePositionY(),
'direction': 'up',
};
await this.#engine.emit('update_player', arg);
await this.#engine.emit('update_paddle', arg);
this.#serverKnownMovement = 'up';
this.#engine.scene.setCurrentPlayerPaddleDirection('up');
}
Expand All @@ -124,10 +124,10 @@ export class _KeyHookHandler {
if (this.#serverKnownMovement !== 'down') {
const scene = this.#engine.scene;
const arg = {
'client_player_position': scene.getCurrentPlayerPaddlePositionAsArray(),
'client_paddle_position': scene.getCurrentPlayerPaddlePositionY(),
'direction': 'down',
};
await this.#engine.emit('update_player', arg);
await this.#engine.emit('update_paddle', arg);
this.#serverKnownMovement = 'down';
this.#engine.scene.setCurrentPlayerPaddleDirection('down');
}
Expand Down
45 changes: 27 additions & 18 deletions front/src/threejs/Engine/sockets/_GameSocketIO.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {Scene} from '../../Scene/Scene';

import {io} from 'socket.io-client';
import {PlayerLocation} from '../../Scene/PlayerLocation';
import {sleep} from '../../sleep';

export class _GameSocketIO {
#engine;
Expand Down Expand Up @@ -44,39 +46,46 @@ export class _GameSocketIO {

this.#socketIO.on('scene', (data) => {
console.log('game scene received');

this.#engine.scene = new Scene(
data['scene']['matches'],
data['scene'],
data['player_location'],
);
this.#engine.startListeningForKeyHooks();
});

this.#socketIO.on('update_player', (data) => {
console.log('update_player received');
const playerLocation = data['player_location'];
this.#engine.scene.setPlayerPaddleDirection(
playerLocation,
data['direction'],
);
this.#engine.scene.setPlayerPaddlePosition(
playerLocation,
data['position'],
);
this.#socketIO.on('update_paddle', async (data) => {
while (! (this.#engine.scene instanceof Scene)) {
await sleep(50);
}
console.log('update_paddle received');

const paddle = new PlayerLocation(data['player_location'])
.getPlayerFromScene(this.#engine.scene).paddle;
paddle.setDirection(data['direction']);
paddle.setPosition(data['position']);
});

this.#socketIO.on('prepare_ball_for_match', (data) => {
this.#socketIO.on('prepare_ball_for_match', async (data) => {
while (! (this.#engine.scene instanceof Scene)) {
await sleep(50);
}
console.log('prepare_ball_for_match received');
const matchIndex = data['match_index'];
this.#engine.scene.matches[matchIndex].prepare_ball_for_match(

const match = this.#engine.scene.getMatchFromLocation(data['match_location']);
match.prepare_ball_for_match(
data['ball_start_time'],
data['ball_movement'],
);
});

this.#socketIO.on('update_ball', (data) => {
this.#socketIO.on('update_ball', async (data) => {
while (! (this.#engine.scene instanceof Scene)) {
await sleep(50);
}
console.log('update_ball received');
const matchIndex = data['match_index'];
const match = this.#engine.scene.matches[matchIndex];

const match = this.#engine.scene.getMatchFromLocation(data['match_location']);
match.setBallMovement(data['movement']);
match.setBallPosition(data['position']);
});
Expand Down
4 changes: 3 additions & 1 deletion front/src/threejs/Scene/Match.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ import {BallBoundingBox, PaddleBoundingBox} from './boundingBoxes';

export class Match {
#threeJSGroup = new THREE.Group();
#index;
#players = [];
#ball;
#ballBoundingBox;
#paddleBoundingBox;
#ballIsWaiting;
#ballStartTime;

constructor(matchJson) {
constructor(matchJson, index) {
this.#index = index;
this.#ball = new Ball(matchJson['ball']);
this.#ballIsWaiting = matchJson['ball_is_waiting'];
this.#ballStartTime = matchJson['ball_start_time'];
Expand Down
12 changes: 0 additions & 12 deletions front/src/threejs/Scene/Player/Player.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,6 @@ export class Player {
return this.#threeJSGroup;
}

setPaddleDirection(direction) {
this.#paddle.setDirection(direction);
}

setPaddlePosition(positionJson) {
this.#paddle.setPosition(positionJson);
}

getPaddlePosition() {
return this.#paddle.getPosition();
}

get paddle() {
return this.#paddle;
}
Expand Down
15 changes: 10 additions & 5 deletions front/src/threejs/Scene/PlayerLocation.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import {Scene} from './Scene';

export class PlayerLocation {
#isInAMatch;
#matchIndex;
#looser;
#matchKey;
#playerIndex;

constructor(playerLocationJson) {
this.#isInAMatch = playerLocationJson['is_in_a_match'];
this.#matchIndex = playerLocationJson['match_index'];
this.#looser = playerLocationJson['looser'];
this.#matchKey = Scene.convertMatchLocationToKey(playerLocationJson['match_location']);
this.#playerIndex = playerLocationJson['player_index'];
}

getPlayerFromScene(scene) {
return scene.matches[this.#matchIndex].players[this.#playerIndex];
if (this.#looser) {
return scene.loosers[this.#playerIndex];
}
return scene.getMatchFromKey(this.#matchKey).players[this.#playerIndex];
}
}
Loading

0 comments on commit 5643b6b

Please sign in to comment.