From e2be99490bdb4ea59ac77f33c5771ed5d0690a3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Fri, 19 Jun 2020 16:36:40 +0200 Subject: [PATCH] Finishing removing any reference to "any" in the front. --- front/src/Connection.ts | 27 +++++++++++---- front/src/Enum/EnvironmentVariable.ts | 2 +- front/src/Phaser/Components/TextInput.ts | 2 +- front/src/Phaser/Entity/Character.ts | 7 +++- front/src/Phaser/Game/GameScene.ts | 34 ++++++++++++------- front/src/Phaser/Login/LoginScene.ts | 4 +-- .../src/Phaser/Login/SelectCharacterScene.ts | 21 ++++++------ front/src/Phaser/Map/ITiledMap.ts | 14 +++++++- .../Phaser/Reconnecting/ReconnectingScene.ts | 6 ---- front/src/WebRtc/SimplePeer.ts | 19 +++++++---- 10 files changed, 89 insertions(+), 47 deletions(-) diff --git a/front/src/Connection.ts b/front/src/Connection.ts index 45d39841..b6b251f0 100644 --- a/front/src/Connection.ts +++ b/front/src/Connection.ts @@ -8,6 +8,7 @@ const SocketIo = require('socket.io-client'); import Socket = SocketIOClient.Socket; import {PlayerAnimationNames} from "./Phaser/Player/Animation"; import {UserSimplePeer} from "./WebRtc/SimplePeer"; +import {SignalData} from "simple-peer"; enum EventMessage{ @@ -110,22 +111,29 @@ export interface WebRtcDisconnectMessageInterface { userId: string } +export interface WebRtcSignalMessageInterface { + userId: string, + receiverId: string, + roomId: string, + signal: SignalData +} + export interface ConnectionInterface { socket: Socket|null; token: string|null; name: string|null; userId: string|null; - createConnection(name: string, characterSelected: string): Promise; + createConnection(name: string, characterSelected: string): Promise; - loadStartMap(): Promise; + loadStartMap(): Promise; joinARoom(roomId: string, startX: number, startY: number, direction: string, moving: boolean): void; sharePosition(x: number, y: number, direction: string, moving: boolean): void; /*webrtc*/ - sendWebrtcSignal(signal: any, roomId: string, userId?: string|null, receiverId?: string): void; + sendWebrtcSignal(signal: unknown, roomId: string, userId?: string|null, receiverId?: string): void; receiveWebrtcSignal(callBack: Function): void; @@ -134,6 +142,11 @@ export interface ConnectionInterface { disconnectMessage(callBack: (message: WebRtcDisconnectMessageInterface) => void): void; } +export interface StartMapInterface { + mapUrlStart: string, + startInstance: string +} + export class Connection implements ConnectionInterface { socket: Socket|null = null; token: string|null = null; @@ -225,7 +238,7 @@ export class Connection implements ConnectionInterface { } //TODO add middleware with access token to secure api - loadStartMap() : Promise { + loadStartMap() : Promise { return Axios.get(`${API_URL}/start-map`) .then((res) => { return res.data; @@ -236,7 +249,7 @@ export class Connection implements ConnectionInterface { } joinARoom(roomId: string, startX: number, startY: number, direction: string, moving: boolean): void { - let point = new Point(startX, startY, direction, moving); + const point = new Point(startX, startY, direction, moving); this.lastPositionShared = point; this.getSocket().emit(EventMessage.JOIN_ROOM, { roomId, position: {x: startX, y: startY, direction, moving }}, (userPositions: MessageUserPositionInterface[]) => { this.GameManager.initUsersPosition(userPositions); @@ -284,7 +297,7 @@ export class Connection implements ConnectionInterface { }) } - sendWebrtcSignal(signal: any, roomId: string, userId? : string|null, receiverId? : string) { + sendWebrtcSignal(signal: unknown, roomId: string, userId? : string|null, receiverId? : string) { return this.getSocket().emit(EventMessage.WEBRTC_SIGNAL, { userId: userId ? userId : this.userId, receiverId: receiverId ? receiverId : this.userId, @@ -297,7 +310,7 @@ export class Connection implements ConnectionInterface { this.getSocket().on(EventMessage.WEBRTC_START, callback); } - receiveWebrtcSignal(callback: Function) { + receiveWebrtcSignal(callback: (message: WebRtcSignalMessageInterface) => void) { return this.getSocket().on(EventMessage.WEBRTC_SIGNAL, callback); } diff --git a/front/src/Enum/EnvironmentVariable.ts b/front/src/Enum/EnvironmentVariable.ts index 2fbf7979..6e0edd8f 100644 --- a/front/src/Enum/EnvironmentVariable.ts +++ b/front/src/Enum/EnvironmentVariable.ts @@ -1,4 +1,4 @@ -const DEBUG_MODE: boolean = process.env.DEBUG_MODE as any === true; +const DEBUG_MODE: boolean = process.env.DEBUG_MODE == "true"; const API_URL = process.env.API_URL || "http://api.workadventure.localhost"; const RESOLUTION = 3; const ZOOM_LEVEL = 1/*3/4*/; diff --git a/front/src/Phaser/Components/TextInput.ts b/front/src/Phaser/Components/TextInput.ts index e1de42e9..3a20eadf 100644 --- a/front/src/Phaser/Components/TextInput.ts +++ b/front/src/Phaser/Components/TextInput.ts @@ -12,7 +12,7 @@ export class TextInput extends Phaser.GameObjects.BitmapText { const keySpace = this.scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE); const keyBackspace = this.scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.BACKSPACE); - this.scene.input.keyboard.on('keydown', (event: any) => { + this.scene.input.keyboard.on('keydown', (event: KeyboardEvent) => { if (event.keyCode === 8 && this.text.length > 0) { this.deleteLetter(); } else if ((event.keyCode === 32 || (event.keyCode >= 48 && event.keyCode <= 90)) && this.text.length < maxLength) { diff --git a/front/src/Phaser/Entity/Character.ts b/front/src/Phaser/Entity/Character.ts index ba6a8228..7453dc75 100644 --- a/front/src/Phaser/Entity/Character.ts +++ b/front/src/Phaser/Entity/Character.ts @@ -2,7 +2,12 @@ import {PlayerAnimationNames} from "../Player/Animation"; import {SpeechBubble} from "./SpeechBubble"; import BitmapText = Phaser.GameObjects.BitmapText; -export const PLAYER_RESOURCES: Array = [ +export interface PlayerResourceDescriptionInterface { + name: string, + img: string +} + +export const PLAYER_RESOURCES: Array = [ {name: "male1", img: "resources/characters/pipoya/Male 01-1.png" /*, x: 32, y: 32*/}, {name: "male2", img: "resources/characters/pipoya/Male 02-2.png"/*, x: 64, y: 32*/}, {name: "male3", img: "resources/characters/pipoya/Male 03-4.png"/*, x: 96, y: 32*/}, diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 42115915..21e0d0b8 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -6,8 +6,13 @@ import { } from "../../Connection"; import {CurrentGamerInterface, hasMovedEventName, Player} from "../Player/Player"; import { DEBUG_MODE, ZOOM_LEVEL, POSITION_DELAY } from "../../Enum/EnvironmentVariable"; -import {ITiledMap, ITiledMapLayer, ITiledTileSet} from "../Map/ITiledMap"; -import {PLAYER_RESOURCES} from "../Entity/Character"; +import { + ITiledMap, + ITiledMapLayer, + ITiledMapLayerProperty, + ITiledTileSet +} from "../Map/ITiledMap"; +import {PLAYER_RESOURCES, PlayerResourceDescriptionInterface} from "../Entity/Character"; import Texture = Phaser.Textures.Texture; import Sprite = Phaser.GameObjects.Sprite; import CanvasTexture = Phaser.Textures.CanvasTexture; @@ -84,7 +89,7 @@ export class GameScene extends Phaser.Scene { //hook preload scene preload(): void { this.GameManager.setCurrentGameScene(this); - this.load.on('filecomplete-tilemapJSON-'+this.MapKey, (key: string, type: string, data: any) => { + this.load.on('filecomplete-tilemapJSON-'+this.MapKey, (key: string, type: string, data: unknown) => { this.onMapLoad(data); }); //TODO strategy to add access token @@ -97,7 +102,7 @@ export class GameScene extends Phaser.Scene { } //add player png - PLAYER_RESOURCES.forEach((playerResource: any) => { + PLAYER_RESOURCES.forEach((playerResource: PlayerResourceDescriptionInterface) => { this.load.spritesheet( playerResource.name, playerResource.img, @@ -108,6 +113,8 @@ export class GameScene extends Phaser.Scene { this.load.bitmapFont('main_font', 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml'); } + // FIXME: we need to put a "unknown" instead of a "any" and validate the structure of the JSON we are receiving. + // eslint-disable-next-line @typescript-eslint/no-explicit-any private onMapLoad(data: any): void { // Triggered when the map is loaded // Load tiles attached to the map recursively @@ -247,11 +254,11 @@ export class GameScene extends Phaser.Scene { } private getProperty(layer: ITiledMapLayer, name: string): string|boolean|number|undefined { - const properties : any = layer.properties; + const properties = layer.properties; if (!properties) { return undefined; } - const obj = properties.find((property:any) => property.name === name); + const obj = properties.find((property: ITiledMapLayerProperty) => property.name === name); if (obj === undefined) { return undefined; } @@ -309,8 +316,11 @@ export class GameScene extends Phaser.Scene { * @param layer */ private startUser(layer: ITiledMapLayer): PositionInterface { - let tiles : any = layer.data; - let possibleStartPositions : PositionInterface[] = []; + const tiles = layer.data; + if (typeof(tiles) === 'string') { + throw new Error('The content of a JSON map must be filled as a JSON array, not as a string'); + } + const possibleStartPositions : PositionInterface[] = []; tiles.forEach((objectKey : number, key: number) => { if(objectKey === 0){ return; @@ -362,11 +372,11 @@ export class GameScene extends Phaser.Scene { } createCollisionObject(){ - this.Objects.forEach((Object : Phaser.Physics.Arcade.Sprite) => { - this.physics.add.collider(this.CurrentPlayer, Object, (object1: any, object2: any) => { - //this.CurrentPlayer.say("Collision with object : " + (object2 as Phaser.Physics.Arcade.Sprite).texture.key) + /*this.Objects.forEach((Object : Phaser.Physics.Arcade.Sprite) => { + this.physics.add.collider(this.CurrentPlayer, Object, (object1, object2) => { + this.CurrentPlayer.say("Collision with object : " + (object2 as Phaser.Physics.Arcade.Sprite).texture.key) }); - }) + })*/ } createCurrentPlayer(){ diff --git a/front/src/Phaser/Login/LoginScene.ts b/front/src/Phaser/Login/LoginScene.ts index e82ece8e..5177659b 100644 --- a/front/src/Phaser/Login/LoginScene.ts +++ b/front/src/Phaser/Login/LoginScene.ts @@ -4,7 +4,7 @@ import {TextInput} from "../Components/TextInput"; import {ClickButton} from "../Components/ClickButton"; import Image = Phaser.GameObjects.Image; import Rectangle = Phaser.GameObjects.Rectangle; -import {PLAYER_RESOURCES} from "../Entity/Character"; +import {PLAYER_RESOURCES, PlayerResourceDescriptionInterface} from "../Entity/Character"; import {cypressAsserter} from "../../Cypress/CypressAsserter"; import {SelectCharacterSceneInitDataInterface, SelectCharacterSceneName} from "./SelectCharacterScene"; @@ -40,7 +40,7 @@ export class LoginScene extends Phaser.Scene { this.load.bitmapFont(LoginTextures.mainFont, 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml'); cypressAsserter.preloadFinished(); //add player png - PLAYER_RESOURCES.forEach((playerResource: any) => { + PLAYER_RESOURCES.forEach((playerResource: PlayerResourceDescriptionInterface) => { this.load.spritesheet( playerResource.name, playerResource.img, diff --git a/front/src/Phaser/Login/SelectCharacterScene.ts b/front/src/Phaser/Login/SelectCharacterScene.ts index 0270a9f5..316ee897 100644 --- a/front/src/Phaser/Login/SelectCharacterScene.ts +++ b/front/src/Phaser/Login/SelectCharacterScene.ts @@ -3,8 +3,9 @@ import {TextField} from "../Components/TextField"; import {ClickButton} from "../Components/ClickButton"; import Image = Phaser.GameObjects.Image; import Rectangle = Phaser.GameObjects.Rectangle; -import {PLAYER_RESOURCES} from "../Entity/Character"; +import {PLAYER_RESOURCES, PlayerResourceDescriptionInterface} from "../Entity/Character"; import {GameSceneInitInterface} from "../Game/GameScene"; +import {StartMapInterface} from "../../Connection"; //todo: put this constants in a dedicated file export const SelectCharacterSceneName = "SelectCharacterScene"; @@ -47,7 +48,7 @@ export class SelectCharacterScene extends Phaser.Scene { // Note: arcade.png from the Phaser 3 examples at: https://github.com/photonstorm/phaser3-examples/tree/master/public/assets/fonts/bitmap this.load.bitmapFont(LoginTextures.mainFont, 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml'); //add player png - PLAYER_RESOURCES.forEach((playerResource: any) => { + PLAYER_RESOURCES.forEach((playerResource: PlayerResourceDescriptionInterface) => { this.load.spritesheet( playerResource.name, playerResource.img, @@ -115,7 +116,7 @@ export class SelectCharacterScene extends Phaser.Scene { this.pressReturnField.setVisible(!!(Math.floor(time / 500) % 2)); } - private async login(name: string) { + private async login(name: string): Promise { return gameManager.connect(name, this.selectedPlayer.texture.key).then(() => { // Do we have a start URL in the address bar? If so, let's redirect to this address const instanceAndMapUrl = this.findMapUrl(); @@ -125,16 +126,16 @@ export class SelectCharacterScene extends Phaser.Scene { this.scene.start(key, { startLayerName: window.location.hash ? window.location.hash.substr(1) : undefined } as GameSceneInitInterface); - return mapUrl; + return { + mapUrlStart: mapUrl, + startInstance: instance + }; } else { // If we do not have a map address in the URL, let's ask the server for a start map. - return gameManager.loadStartMap().then((scene : any) => { - if (!scene) { - return; - } - const key = gameManager.loadMap(window.location.protocol + "//" + scene.mapUrlStart, this.scene, scene.startInstance); + return gameManager.loadStartMap().then((startMap: StartMapInterface) => { + const key = gameManager.loadMap(window.location.protocol + "//" + startMap.mapUrlStart, this.scene, startMap.startInstance); this.scene.start(key); - return scene; + return startMap; }).catch((err) => { console.error(err); throw err; diff --git a/front/src/Phaser/Map/ITiledMap.ts b/front/src/Phaser/Map/ITiledMap.ts index ca10f218..2a82e93a 100644 --- a/front/src/Phaser/Map/ITiledMap.ts +++ b/front/src/Phaser/Map/ITiledMap.ts @@ -26,12 +26,24 @@ export interface ITiledMap { version: number; } +export interface ITiledMapLayerProperty { + name: string; + type: string; + value: string|boolean|number|undefined; +} + +/*export interface ITiledMapLayerBooleanProperty { + name: string, + type: 'bool', + value: boolean +}*/ + export interface ITiledMapLayer { data: number[]|string; height: number; name: string; opacity: number; - properties: {[key: string]: string}; + properties: ITiledMapLayerProperty[]; encoding: string; compression?: string; diff --git a/front/src/Phaser/Reconnecting/ReconnectingScene.ts b/front/src/Phaser/Reconnecting/ReconnectingScene.ts index 2ee91358..7a377b66 100644 --- a/front/src/Phaser/Reconnecting/ReconnectingScene.ts +++ b/front/src/Phaser/Reconnecting/ReconnectingScene.ts @@ -1,11 +1,5 @@ -import {gameManager} from "../Game/GameManager"; import {TextField} from "../Components/TextField"; -import {TextInput} from "../Components/TextInput"; -import {ClickButton} from "../Components/ClickButton"; import Image = Phaser.GameObjects.Image; -import Rectangle = Phaser.GameObjects.Rectangle; -import {PLAYER_RESOURCES} from "../Entity/Character"; -import {cypressAsserter} from "../../Cypress/CypressAsserter"; import Sprite = Phaser.GameObjects.Sprite; export const ReconnectingSceneName = "ReconnectingScene"; diff --git a/front/src/WebRtc/SimplePeer.ts b/front/src/WebRtc/SimplePeer.ts index 3f471253..f5c8e7ef 100644 --- a/front/src/WebRtc/SimplePeer.ts +++ b/front/src/WebRtc/SimplePeer.ts @@ -1,4 +1,9 @@ -import {ConnectionInterface, WebRtcDisconnectMessageInterface, WebRtcStartMessageInterface} from "../Connection"; +import { + ConnectionInterface, + WebRtcDisconnectMessageInterface, + WebRtcSignalMessageInterface, + WebRtcStartMessageInterface +} from "../Connection"; import {MediaManager} from "./MediaManager"; import * as SimplePeerNamespace from "simple-peer"; const Peer: SimplePeerNamespace.SimplePeer = require('simple-peer'); @@ -36,7 +41,7 @@ export class SimplePeer { private initialise() { //receive signal by gemer - this.Connection.receiveWebrtcSignal((message: any) => { + this.Connection.receiveWebrtcSignal((message: WebRtcSignalMessageInterface) => { this.receiveWebrtcSignal(message); }); @@ -122,7 +127,7 @@ export class SimplePeer { this.PeerConnectionArray.set(user.userId, peer); //start listen signal for the peer connection - peer.on('signal', (data: any) => { + peer.on('signal', (data: unknown) => { this.sendWebrtcSignal(data, user.userId); }); @@ -159,6 +164,7 @@ export class SimplePeer { this.closeConnection(user.userId); }); + // eslint-disable-next-line @typescript-eslint/no-explicit-any peer.on('error', (err: any) => { console.error(`error => ${user.userId} => ${err.code}`, err); this.MediaManager.isError(user.userId); @@ -208,7 +214,7 @@ export class SimplePeer { * @param userId * @param data */ - private sendWebrtcSignal(data: any, userId : string) { + private sendWebrtcSignal(data: unknown, userId : string) { try { this.Connection.sendWebrtcSignal(data, this.WebRtcRoomId, null, userId); }catch (e) { @@ -216,7 +222,8 @@ export class SimplePeer { } } - private receiveWebrtcSignal(data: any) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + private receiveWebrtcSignal(data: WebRtcSignalMessageInterface) { try { //if offer type, create peer connection if(data.signal.type === "offer"){ @@ -251,7 +258,7 @@ export class SimplePeer { * * @param userId */ - private addMedia (userId : any = null) { + private addMedia (userId : string) { try { const localStream: MediaStream|null = this.MediaManager.localStream; const peer = this.PeerConnectionArray.get(userId);