Merge pull request #692 from thecodingmachine/develop
Deploy 2021-02-01
This commit is contained in:
commit
cc1e3bbe0e
29
.github/workflows/build-and-deploy.yml
vendored
29
.github/workflows/build-and-deploy.yml
vendored
@ -161,32 +161,3 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
msg: Environment deployed at https://${{ env.GITHUB_REF_SLUG }}.workadventure.test.thecodingmachine.com
|
msg: Environment deployed at https://${{ env.GITHUB_REF_SLUG }}.workadventure.test.thecodingmachine.com
|
||||||
check_for_duplicate_msg: true
|
check_for_duplicate_msg: true
|
||||||
|
|
||||||
- name: Run Cypress tests
|
|
||||||
uses: cypress-io/github-action@v2
|
|
||||||
if: ${{ env.GITHUB_REF_SLUG != 'master' }}
|
|
||||||
env:
|
|
||||||
CYPRESS_BASE_URL: https://play.${{ env.GITHUB_REF_SLUG }}.workadventure.test.thecodingmachine.com
|
|
||||||
with:
|
|
||||||
env: host=play.${{ env.GITHUB_REF_SLUG }}.workadventure.test.thecodingmachine.com,port=80
|
|
||||||
spec: cypress/integration/spec.js
|
|
||||||
wait-on: https://play.${{ env.GITHUB_REF_SLUG }}.workadventure.test.thecodingmachine.com
|
|
||||||
working-directory: e2e
|
|
||||||
|
|
||||||
- name: Run Cypress tests in prod
|
|
||||||
uses: cypress-io/github-action@v2
|
|
||||||
if: ${{ env.GITHUB_REF_SLUG == 'master' }}
|
|
||||||
env:
|
|
||||||
CYPRESS_BASE_URL: https://play.workadventu.re
|
|
||||||
with:
|
|
||||||
env: host=play.workadventu.re
|
|
||||||
spec: cypress/integration/spec.js
|
|
||||||
wait-on: https://workadventu.re
|
|
||||||
working-directory: e2e
|
|
||||||
|
|
||||||
- name: "Upload the screenshot on test failure"
|
|
||||||
uses: actions/upload-artifact@v1
|
|
||||||
if: failure()
|
|
||||||
with:
|
|
||||||
name: "screenshot"
|
|
||||||
path: "./e2e/cypress/screenshots/spec.js/WorkAdventureGame -- loads (failed).png"
|
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
local namespace = env.GITHUB_REF_SLUG,
|
local namespace = env.GITHUB_REF_SLUG,
|
||||||
local tag = namespace,
|
local tag = namespace,
|
||||||
local url = if namespace == "master" then "workadventu.re" else namespace+".workadventure.test.thecodingmachine.com",
|
local url = if namespace == "master" then "workadventu.re" else namespace+".workadventure.test.thecodingmachine.com",
|
||||||
local adminUrl = if namespace == "master" || namespace == "develop" || std.startsWith(namespace, "admin") then "https://"+url else null,
|
// develop branch does not use admin because of issue with SSL certificate of admin as of now.
|
||||||
|
local adminUrl = if namespace == "master" /*|| namespace == "develop"*/ || std.startsWith(namespace, "admin") then "https://"+url else null,
|
||||||
"$schema": "https://raw.githubusercontent.com/thecodingmachine/deeployer/master/deeployer.schema.json",
|
"$schema": "https://raw.githubusercontent.com/thecodingmachine/deeployer/master/deeployer.schema.json",
|
||||||
"version": "1.0",
|
"version": "1.0",
|
||||||
"containers": {
|
"containers": {
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
version: '3'
|
|
||||||
|
|
||||||
services:
|
|
||||||
|
|
||||||
wait_app:
|
|
||||||
image: dadarek/wait-for-dependencies
|
|
||||||
depends_on:
|
|
||||||
- reverse-proxy
|
|
||||||
command: front:8080
|
|
||||||
cypress:
|
|
||||||
# the Docker image to use from https://github.com/cypress-io/cypress-docker-images
|
|
||||||
image: "cypress/included:3.8.3"
|
|
||||||
depends_on:
|
|
||||||
- reverse-proxy
|
|
||||||
environment:
|
|
||||||
# pass base url to test pointing at the web application
|
|
||||||
- CYPRESS_baseUrl=http://front:8080
|
|
||||||
working_dir: /e2e
|
|
||||||
volumes:
|
|
||||||
- ./e2e/:/e2e
|
|
3
e2e/.gitignore
vendored
3
e2e/.gitignore
vendored
@ -1,3 +0,0 @@
|
|||||||
screenshots/
|
|
||||||
videos/
|
|
||||||
node_modules/
|
|
@ -1,36 +0,0 @@
|
|||||||
# Testing with cypress
|
|
||||||
|
|
||||||
This project use [cypress](https://www.cypress.io/) to do functional testing of the website.
|
|
||||||
Unfortunately we cannot integrate it with docker-compose for the moment, so you will need to install some packages locally on your pc.
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
You will need to install theses dependancies on linux (don't know about mac):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install libgtk2.0-0 libgtk-3-0 libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb
|
|
||||||
```
|
|
||||||
|
|
||||||
Cypress can be installed locally in the e2e directory
|
|
||||||
```bash
|
|
||||||
cd e2e
|
|
||||||
npm install
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
How to use:
|
|
||||||
```bash
|
|
||||||
npm run cy:run
|
|
||||||
npm run cy:open
|
|
||||||
```
|
|
||||||
|
|
||||||
The first command will run all tests in the terminal, while the second will open the interactive task runner which allow you to easily manage the test workflow
|
|
||||||
|
|
||||||
[More details here](https://docs.cypress.io/guides/getting-started/testing-your-app.html#Step-1-Start-your-server)
|
|
||||||
|
|
||||||
## How to test a game
|
|
||||||
|
|
||||||
Cypress cannot "see" and so cannot directly manipulate the canva created by Phaser.
|
|
||||||
|
|
||||||
This means we have to do workarounds such as exposing core objects in the window so that cypress can manipulate them or doing console that cypress can catch.
|
|
@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"baseUrl": "http://workadventure.localhost",
|
|
||||||
"video": false,
|
|
||||||
"defaultCommandTimeout": 20000,
|
|
||||||
"pluginsFile": false,
|
|
||||||
"supportFile": false
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
Cypress.on('window:before:load', (win) => {
|
|
||||||
// because this is called before any scripts
|
|
||||||
// have loaded - the ga function is undefined
|
|
||||||
// so we need to create it.
|
|
||||||
win.cypressAsserter = cy.stub().as('ca')
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('WorkAdventureGame', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.visit('/', {
|
|
||||||
onBeforeLoad (win) {
|
|
||||||
cy.spy(win.console, 'log').as('console.log')
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it('loads', () => {
|
|
||||||
cy.get('@console.log').should('be.calledWith', 'Started the game')
|
|
||||||
cy.get('@console.log').should('be.calledWith', 'Preloading')
|
|
||||||
cy.get('@console.log').should('be.calledWith', 'Preloading done')
|
|
||||||
cy.get('@console.log').should('be.calledWith', 'startInit')
|
|
||||||
cy.get('@console.log').should('be.calledWith', 'startInit done')
|
|
||||||
});
|
|
||||||
});
|
|
1406
e2e/package-lock.json
generated
1406
e2e/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"dependencies": {
|
|
||||||
"cypress": "^3.8.3"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"cy:run": "cypress run",
|
|
||||||
"cy:open": "cypress open"
|
|
||||||
}
|
|
||||||
}
|
|
1
front/dist/.gitignore
vendored
Normal file
1
front/dist/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
index.html
|
@ -26,7 +26,7 @@
|
|||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
"generic-type-guard": "^3.2.0",
|
"generic-type-guard": "^3.2.0",
|
||||||
"google-protobuf": "^3.13.0",
|
"google-protobuf": "^3.13.0",
|
||||||
"phaser": "^3.52.0",
|
"phaser": "3.24.1",
|
||||||
"queue-typescript": "^1.0.1",
|
"queue-typescript": "^1.0.1",
|
||||||
"quill": "^1.3.7",
|
"quill": "^1.3.7",
|
||||||
"simple-peer": "^9.6.2",
|
"simple-peer": "^9.6.2",
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
import {RoomConnection} from "../Connexion/RoomConnection";
|
import {RoomConnection} from "../Connexion/RoomConnection";
|
||||||
import * as TypeMessages from "./TypeMessage";
|
import * as TypeMessages from "./TypeMessage";
|
||||||
|
import List = Phaser.Structs.List;
|
||||||
|
import {UpdatedLocalStreamCallback} from "../WebRtc/MediaManager";
|
||||||
|
import {Banned} from "./TypeMessage";
|
||||||
|
|
||||||
export interface TypeMessageInterface {
|
export interface TypeMessageInterface {
|
||||||
showMessage(message: string): void;
|
showMessage(message: string): void;
|
||||||
@ -8,6 +11,7 @@ export interface TypeMessageInterface {
|
|||||||
export class UserMessageManager {
|
export class UserMessageManager {
|
||||||
|
|
||||||
typeMessages: Map<string, TypeMessageInterface> = new Map<string, TypeMessageInterface>();
|
typeMessages: Map<string, TypeMessageInterface> = new Map<string, TypeMessageInterface>();
|
||||||
|
receiveBannedMessageListener: Set<Function> = new Set<UpdatedLocalStreamCallback>();
|
||||||
|
|
||||||
constructor(private Connection: RoomConnection) {
|
constructor(private Connection: RoomConnection) {
|
||||||
const valueTypeMessageTab = Object.values(TypeMessages);
|
const valueTypeMessageTab = Object.values(TypeMessages);
|
||||||
@ -21,7 +25,14 @@ export class UserMessageManager {
|
|||||||
initialise() {
|
initialise() {
|
||||||
//receive signal to show message
|
//receive signal to show message
|
||||||
this.Connection.receiveUserMessage((type: string, message: string) => {
|
this.Connection.receiveUserMessage((type: string, message: string) => {
|
||||||
this.showMessage(type, message);
|
const typeMessage = this.showMessage(type, message);
|
||||||
|
|
||||||
|
//listener on banned receive message
|
||||||
|
if(typeMessage instanceof Banned) {
|
||||||
|
for (const callback of this.receiveBannedMessageListener) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,5 +43,10 @@ export class UserMessageManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
classTypeMessage.showMessage(message);
|
classTypeMessage.showMessage(message);
|
||||||
|
return classTypeMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
setReceiveBanListener(callback: Function){
|
||||||
|
this.receiveBannedMessageListener.add(callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,36 +0,0 @@
|
|||||||
declare let window:WindowWithCypressAsserter;
|
|
||||||
|
|
||||||
interface WindowWithCypressAsserter extends Window {
|
|
||||||
cypressAsserter: CypressAsserter;
|
|
||||||
}
|
|
||||||
|
|
||||||
//this class is used to communicate with cypress, our e2e testing client
|
|
||||||
//Since cypress cannot manipulate canvas, we notified it with console logs
|
|
||||||
class CypressAsserter {
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
window.cypressAsserter = this
|
|
||||||
}
|
|
||||||
|
|
||||||
gameStarted() {
|
|
||||||
console.log('Started the game')
|
|
||||||
}
|
|
||||||
|
|
||||||
preloadStarted() {
|
|
||||||
console.log('Preloading')
|
|
||||||
}
|
|
||||||
|
|
||||||
preloadFinished() {
|
|
||||||
console.log('Preloading done')
|
|
||||||
}
|
|
||||||
|
|
||||||
initStarted() {
|
|
||||||
console.log('startInit')
|
|
||||||
}
|
|
||||||
|
|
||||||
initFinished() {
|
|
||||||
console.log('startInit done')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const cypressAsserter = new CypressAsserter()
|
|
@ -6,7 +6,8 @@ export interface BodyResourceDescriptionListInterface {
|
|||||||
|
|
||||||
export interface BodyResourceDescriptionInterface {
|
export interface BodyResourceDescriptionInterface {
|
||||||
name: string,
|
name: string,
|
||||||
img: string
|
img: string,
|
||||||
|
level?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PLAYER_RESOURCES: BodyResourceDescriptionListInterface = {
|
export const PLAYER_RESOURCES: BodyResourceDescriptionListInterface = {
|
||||||
|
@ -23,21 +23,26 @@ export const loadAllDefaultModels = (load: LoaderPlugin): BodyResourceDescriptio
|
|||||||
});
|
});
|
||||||
return returnArray;
|
return returnArray;
|
||||||
}
|
}
|
||||||
export const loadCustomTexture = (load: LoaderPlugin, texture: CharacterTexture) => {
|
|
||||||
|
export const loadCustomTexture = (loaderPlugin: LoaderPlugin, texture: CharacterTexture) : Promise<BodyResourceDescriptionInterface> => {
|
||||||
const name = 'customCharacterTexture'+texture.id;
|
const name = 'customCharacterTexture'+texture.id;
|
||||||
load.spritesheet(name,texture.url,{frameWidth: 32, frameHeight: 32});
|
const playerResourceDescriptor: BodyResourceDescriptionInterface = {name, img: texture.url, level: texture.level}
|
||||||
return name;
|
return createLoadingPromise(loaderPlugin, playerResourceDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const lazyLoadPlayerCharacterTextures = (loadPlugin: LoaderPlugin, texturePlugin: TextureManager, texturekeys:Array<string|BodyResourceDescriptionInterface>): Promise<string[]> => {
|
export const lazyLoadPlayerCharacterTextures = (loadPlugin: LoaderPlugin, texturekeys:Array<string|BodyResourceDescriptionInterface>): Promise<string[]> => {
|
||||||
const promisesList:Promise<void>[] = [];
|
const promisesList:Promise<unknown>[] = [];
|
||||||
texturekeys.forEach((textureKey: string|BodyResourceDescriptionInterface) => {
|
texturekeys.forEach((textureKey: string|BodyResourceDescriptionInterface) => {
|
||||||
|
try {
|
||||||
|
//TODO refactor
|
||||||
const playerResourceDescriptor = getRessourceDescriptor(textureKey);
|
const playerResourceDescriptor = getRessourceDescriptor(textureKey);
|
||||||
if(!texturePlugin.exists(playerResourceDescriptor.name)) {
|
if (playerResourceDescriptor && !loadPlugin.textureManager.exists(playerResourceDescriptor.name)) {
|
||||||
console.log('Loading '+playerResourceDescriptor.name)
|
|
||||||
promisesList.push(createLoadingPromise(loadPlugin, playerResourceDescriptor));
|
promisesList.push(createLoadingPromise(loadPlugin, playerResourceDescriptor));
|
||||||
}
|
}
|
||||||
})
|
}catch (err){
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
let returnPromise:Promise<Array<string|BodyResourceDescriptionInterface>>;
|
let returnPromise:Promise<Array<string|BodyResourceDescriptionInterface>>;
|
||||||
if (promisesList.length > 0) {
|
if (promisesList.length > 0) {
|
||||||
loadPlugin.start();
|
loadPlugin.start();
|
||||||
@ -66,8 +71,14 @@ export const getRessourceDescriptor = (textureKey: string|BodyResourceDescriptio
|
|||||||
}
|
}
|
||||||
|
|
||||||
const createLoadingPromise = (loadPlugin: LoaderPlugin, playerResourceDescriptor: BodyResourceDescriptionInterface) => {
|
const createLoadingPromise = (loadPlugin: LoaderPlugin, playerResourceDescriptor: BodyResourceDescriptionInterface) => {
|
||||||
return new Promise<void>((res, rej) => {
|
return new Promise<BodyResourceDescriptionInterface>((res) => {
|
||||||
loadPlugin.spritesheet(playerResourceDescriptor.name, playerResourceDescriptor.img, {frameWidth: 32, frameHeight: 32});
|
if (loadPlugin.textureManager.exists(playerResourceDescriptor.name)) {
|
||||||
loadPlugin.once('filecomplete-spritesheet-'+playerResourceDescriptor.name, () => res());
|
return res(playerResourceDescriptor);
|
||||||
|
}
|
||||||
|
loadPlugin.spritesheet(playerResourceDescriptor.name, playerResourceDescriptor.img, {
|
||||||
|
frameWidth: 32,
|
||||||
|
frameHeight: 32
|
||||||
|
});
|
||||||
|
loadPlugin.once('filecomplete-spritesheet-' + playerResourceDescriptor.name, () => res(playerResourceDescriptor));
|
||||||
});
|
});
|
||||||
}
|
}
|
@ -30,7 +30,7 @@ import {RemotePlayer} from "../Entity/RemotePlayer";
|
|||||||
import {Queue} from 'queue-typescript';
|
import {Queue} from 'queue-typescript';
|
||||||
import {SimplePeer, UserSimplePeerInterface} from "../../WebRtc/SimplePeer";
|
import {SimplePeer, UserSimplePeerInterface} from "../../WebRtc/SimplePeer";
|
||||||
import {ReconnectingSceneName} from "../Reconnecting/ReconnectingScene";
|
import {ReconnectingSceneName} from "../Reconnecting/ReconnectingScene";
|
||||||
import {lazyLoadPlayerCharacterTextures} from "../Entity/PlayerTexturesLoadingManager";
|
import {lazyLoadPlayerCharacterTextures, loadCustomTexture} from "../Entity/PlayerTexturesLoadingManager";
|
||||||
import {
|
import {
|
||||||
CenterListener,
|
CenterListener,
|
||||||
layoutManager,
|
layoutManager,
|
||||||
@ -67,6 +67,8 @@ import {SelectCharacterScene, SelectCharacterSceneName} from "../Login/SelectCha
|
|||||||
import {TextureError} from "../../Exception/TextureError";
|
import {TextureError} from "../../Exception/TextureError";
|
||||||
import {addLoader} from "../Components/Loader";
|
import {addLoader} from "../Components/Loader";
|
||||||
import {ErrorSceneName} from "../Reconnecting/ErrorScene";
|
import {ErrorSceneName} from "../Reconnecting/ErrorScene";
|
||||||
|
import {localUserStore} from "../../Connexion/LocalUserStore";
|
||||||
|
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
||||||
|
|
||||||
export interface GameSceneInitInterface {
|
export interface GameSceneInitInterface {
|
||||||
initPosition: PointInterface|null,
|
initPosition: PointInterface|null,
|
||||||
@ -111,7 +113,7 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
MapPlayers!: Phaser.Physics.Arcade.Group;
|
MapPlayers!: Phaser.Physics.Arcade.Group;
|
||||||
MapPlayersByKey : Map<number, RemotePlayer> = new Map<number, RemotePlayer>();
|
MapPlayersByKey : Map<number, RemotePlayer> = new Map<number, RemotePlayer>();
|
||||||
Map!: Phaser.Tilemaps.Tilemap;
|
Map!: Phaser.Tilemaps.Tilemap;
|
||||||
Layers!: Array<Phaser.Tilemaps.TilemapLayer>;
|
Layers!: Array<Phaser.Tilemaps.StaticTilemapLayer>;
|
||||||
Objects!: Array<Phaser.Physics.Arcade.Sprite>;
|
Objects!: Array<Phaser.Physics.Arcade.Sprite>;
|
||||||
mapFile!: ITiledMap;
|
mapFile!: ITiledMap;
|
||||||
groups: Map<number, Sprite>;
|
groups: Map<number, Sprite>;
|
||||||
@ -183,6 +185,14 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
preload(): void {
|
preload(): void {
|
||||||
addLoader(this);
|
addLoader(this);
|
||||||
|
|
||||||
|
const localUser = localUserStore.getLocalUser();
|
||||||
|
const textures = localUser?.textures;
|
||||||
|
if (textures) {
|
||||||
|
for (const texture of textures) {
|
||||||
|
loadCustomTexture(this.load, texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.load.image(openChatIconName, 'resources/objects/talk.png');
|
this.load.image(openChatIconName, 'resources/objects/talk.png');
|
||||||
this.load.on(FILE_LOAD_ERROR, (file: {src: string}) => {
|
this.load.on(FILE_LOAD_ERROR, (file: {src: string}) => {
|
||||||
this.scene.start(ErrorSceneName, {
|
this.scene.start(ErrorSceneName, {
|
||||||
@ -339,11 +349,11 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
this.physics.world.setBounds(0, 0, this.Map.widthInPixels, this.Map.heightInPixels);
|
this.physics.world.setBounds(0, 0, this.Map.widthInPixels, this.Map.heightInPixels);
|
||||||
|
|
||||||
//add layer on map
|
//add layer on map
|
||||||
this.Layers = new Array<Phaser.Tilemaps.TilemapLayer>();
|
this.Layers = new Array<Phaser.Tilemaps.StaticTilemapLayer>();
|
||||||
let depth = -2;
|
let depth = -2;
|
||||||
for (const layer of this.mapFile.layers) {
|
for (const layer of this.mapFile.layers) {
|
||||||
if (layer.type === 'tilelayer') {
|
if (layer.type === 'tilelayer') {
|
||||||
this.addLayer(this.Map.createLayer(layer.name, this.Terrains, 0, 0).setDepth(depth));
|
this.addLayer(this.Map.createStaticLayer(layer.name, this.Terrains, 0, 0).setDepth(depth));
|
||||||
|
|
||||||
const exitSceneUrl = this.getExitSceneUrl(layer);
|
const exitSceneUrl = this.getExitSceneUrl(layer);
|
||||||
if (exitSceneUrl !== undefined) {
|
if (exitSceneUrl !== undefined) {
|
||||||
@ -524,6 +534,7 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
this.simplePeer = new SimplePeer(this.connection, !this.room.isPublic, this.playerName);
|
this.simplePeer = new SimplePeer(this.connection, !this.room.isPublic, this.playerName);
|
||||||
this.GlobalMessageManager = new GlobalMessageManager(this.connection);
|
this.GlobalMessageManager = new GlobalMessageManager(this.connection);
|
||||||
this.UserMessageManager = new UserMessageManager(this.connection);
|
this.UserMessageManager = new UserMessageManager(this.connection);
|
||||||
|
this.UserMessageManager.setReceiveBanListener(this.bannedUser.bind(this));
|
||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
this.simplePeer.registerPeerConnectionListener({
|
this.simplePeer.registerPeerConnectionListener({
|
||||||
@ -848,13 +859,13 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
this.cameras.main.setZoom(ZOOM_LEVEL);
|
this.cameras.main.setZoom(ZOOM_LEVEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
addLayer(Layer : Phaser.Tilemaps.TilemapLayer){
|
addLayer(Layer : Phaser.Tilemaps.StaticTilemapLayer){
|
||||||
this.Layers.push(Layer);
|
this.Layers.push(Layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
createCollisionWithPlayer() {
|
createCollisionWithPlayer() {
|
||||||
//add collision layer
|
//add collision layer
|
||||||
this.Layers.forEach((Layer: Phaser.Tilemaps.TilemapLayer) => {
|
this.Layers.forEach((Layer: Phaser.Tilemaps.StaticTilemapLayer) => {
|
||||||
this.physics.add.collider(this.CurrentPlayer, Layer, (object1: GameObject, object2: GameObject) => {
|
this.physics.add.collider(this.CurrentPlayer, Layer, (object1: GameObject, object2: GameObject) => {
|
||||||
//this.CurrentPlayer.say("Collision with layer : "+ (object2 as Tile).layer.name)
|
//this.CurrentPlayer.say("Collision with layer : "+ (object2 as Tile).layer.name)
|
||||||
});
|
});
|
||||||
@ -872,7 +883,7 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
|
|
||||||
createCurrentPlayer(){
|
createCurrentPlayer(){
|
||||||
//TODO create animation moving between exit and start
|
//TODO create animation moving between exit and start
|
||||||
const texturesPromise = lazyLoadPlayerCharacterTextures(this.load, this.textures, this.characterLayers);
|
const texturesPromise = lazyLoadPlayerCharacterTextures(this.load, this.characterLayers);
|
||||||
try {
|
try {
|
||||||
this.CurrentPlayer = new Player(
|
this.CurrentPlayer = new Player(
|
||||||
this,
|
this,
|
||||||
@ -1066,7 +1077,7 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const texturesPromise = lazyLoadPlayerCharacterTextures(this.load, this.textures, addPlayerData.characterLayers);
|
const texturesPromise = lazyLoadPlayerCharacterTextures(this.load, addPlayerData.characterLayers);
|
||||||
const player = new RemotePlayer(
|
const player = new RemotePlayer(
|
||||||
addPlayerData.userId,
|
addPlayerData.userId,
|
||||||
this,
|
this,
|
||||||
@ -1235,5 +1246,14 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
mediaManager.removeTriggerCloseJitsiFrameButton('close-jisi');
|
mediaManager.removeTriggerCloseJitsiFrameButton('close-jisi');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bannedUser(){
|
||||||
|
this.cleanupClosingScene();
|
||||||
|
this.userInputManager.clearAllInputKeyboard();
|
||||||
|
this.scene.start(ErrorSceneName, {
|
||||||
|
title: 'Banned',
|
||||||
|
subTitle: 'You was banned of WorkAdventure',
|
||||||
|
message: 'If you want more information, you can contact us: workadventure@thecodingmachine.com'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -43,8 +43,9 @@ export class ActionableItem {
|
|||||||
}
|
}
|
||||||
this.isSelectable = true;
|
this.isSelectable = true;
|
||||||
if (this.sprite.pipeline) {
|
if (this.sprite.pipeline) {
|
||||||
this.sprite.setPipeline(OutlinePipeline.KEY);
|
// Commented out to try to fix MacOS issue
|
||||||
this.sprite.pipeline.set2f('uTextureSize', this.sprite.texture.getSourceImage().width, this.sprite.texture.getSourceImage().height);
|
/*this.sprite.setPipeline(OutlinePipeline.KEY);
|
||||||
|
this.sprite.pipeline.set2f('uTextureSize', this.sprite.texture.getSourceImage().width, this.sprite.texture.getSourceImage().height);*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +57,8 @@ export class ActionableItem {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.isSelectable = false;
|
this.isSelectable = false;
|
||||||
this.sprite.resetPipeline();
|
// Commented out to try to fix MacOS issue
|
||||||
|
//this.sprite.resetPipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
41
front/src/Phaser/Login/AbstractCharacterScene.ts
Normal file
41
front/src/Phaser/Login/AbstractCharacterScene.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import {ResizableScene} from "./ResizableScene";
|
||||||
|
import {localUserStore} from "../../Connexion/LocalUserStore";
|
||||||
|
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
||||||
|
import {loadCustomTexture} from "../Entity/PlayerTexturesLoadingManager";
|
||||||
|
import {CharacterTexture} from "../../Connexion/LocalUser";
|
||||||
|
|
||||||
|
export abstract class AbstractCharacterScene extends ResizableScene {
|
||||||
|
|
||||||
|
loadCustomSceneSelectCharacters() : Promise<BodyResourceDescriptionInterface[]> {
|
||||||
|
const textures = this.getTextures();
|
||||||
|
const promises : Promise<BodyResourceDescriptionInterface>[] = [];
|
||||||
|
if (textures) {
|
||||||
|
for (const texture of textures) {
|
||||||
|
if (texture.level === -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
promises.push(loadCustomTexture(this.load, texture));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.all(promises)
|
||||||
|
}
|
||||||
|
|
||||||
|
loadSelectSceneCharacters() : Promise<BodyResourceDescriptionInterface[]> {
|
||||||
|
const textures = this.getTextures();
|
||||||
|
const promises: Promise<BodyResourceDescriptionInterface>[] = [];
|
||||||
|
if (textures) {
|
||||||
|
for (const texture of textures) {
|
||||||
|
if (texture.level !== -1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
promises.push(loadCustomTexture(this.load, texture));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.all(promises)
|
||||||
|
}
|
||||||
|
|
||||||
|
private getTextures() : CharacterTexture[]|undefined{
|
||||||
|
const localUser = localUserStore.getLocalUser();
|
||||||
|
return localUser?.textures;
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ import {ResizableScene} from "./ResizableScene";
|
|||||||
import {localUserStore} from "../../Connexion/LocalUserStore";
|
import {localUserStore} from "../../Connexion/LocalUserStore";
|
||||||
import {addLoader} from "../Components/Loader";
|
import {addLoader} from "../Components/Loader";
|
||||||
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
||||||
|
import {AbstractCharacterScene} from "./AbstractCharacterScene";
|
||||||
|
|
||||||
export const CustomizeSceneName = "CustomizeScene";
|
export const CustomizeSceneName = "CustomizeScene";
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ enum CustomizeTextures{
|
|||||||
arrowUp = "arrow_up",
|
arrowUp = "arrow_up",
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CustomizeScene extends ResizableScene {
|
export class CustomizeScene extends AbstractCharacterScene {
|
||||||
|
|
||||||
private textField!: TextField;
|
private textField!: TextField;
|
||||||
private enterField!: TextField;
|
private enterField!: TextField;
|
||||||
@ -48,29 +49,21 @@ export class CustomizeScene extends ResizableScene {
|
|||||||
|
|
||||||
preload() {
|
preload() {
|
||||||
addLoader(this);
|
addLoader(this);
|
||||||
|
|
||||||
|
this.layers = loadAllLayers(this.load);
|
||||||
|
this.loadCustomSceneSelectCharacters().then((bodyResourceDescriptions) => {
|
||||||
|
bodyResourceDescriptions.forEach((bodyResourceDescription) => {
|
||||||
|
if(!bodyResourceDescription.level){
|
||||||
|
throw 'Texture level is null';
|
||||||
|
}
|
||||||
|
this.layers[bodyResourceDescription.level].unshift(bodyResourceDescription);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
this.load.image(CustomizeTextures.arrowRight, "resources/objects/arrow_right.png");
|
this.load.image(CustomizeTextures.arrowRight, "resources/objects/arrow_right.png");
|
||||||
this.load.image(CustomizeTextures.icon, "resources/logos/tcm_full.png");
|
this.load.image(CustomizeTextures.icon, "resources/logos/tcm_full.png");
|
||||||
this.load.image(CustomizeTextures.arrowUp, "resources/objects/arrow_up.png");
|
this.load.image(CustomizeTextures.arrowUp, "resources/objects/arrow_up.png");
|
||||||
this.load.bitmapFont(CustomizeTextures.mainFont, 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml');
|
this.load.bitmapFont(CustomizeTextures.mainFont, 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml');
|
||||||
|
|
||||||
this.layers = loadAllLayers(this.load);
|
|
||||||
|
|
||||||
const localUser = localUserStore.getLocalUser();
|
|
||||||
|
|
||||||
const textures = localUser?.textures;
|
|
||||||
if (textures) {
|
|
||||||
for (const texture of textures) {
|
|
||||||
if(texture.level === -1){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
loadCustomTexture(this.load, texture);
|
|
||||||
const name = 'customCharacterTexture'+texture.id;
|
|
||||||
this.layers[texture.level].unshift({
|
|
||||||
name,
|
|
||||||
img: texture.url
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
|
@ -2,7 +2,6 @@ import {gameManager} from "../Game/GameManager";
|
|||||||
import {TextField} from "../Components/TextField";
|
import {TextField} from "../Components/TextField";
|
||||||
import {TextInput} from "../Components/TextInput";
|
import {TextInput} from "../Components/TextInput";
|
||||||
import Image = Phaser.GameObjects.Image;
|
import Image = Phaser.GameObjects.Image;
|
||||||
import {cypressAsserter} from "../../Cypress/CypressAsserter";
|
|
||||||
import {SelectCharacterSceneName} from "./SelectCharacterScene";
|
import {SelectCharacterSceneName} from "./SelectCharacterScene";
|
||||||
import {ResizableScene} from "./ResizableScene";
|
import {ResizableScene} from "./ResizableScene";
|
||||||
|
|
||||||
@ -29,16 +28,13 @@ export class LoginScene extends ResizableScene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
preload() {
|
preload() {
|
||||||
cypressAsserter.preloadStarted();
|
|
||||||
//this.load.image(LoginTextures.playButton, "resources/objects/play_button.png");
|
//this.load.image(LoginTextures.playButton, "resources/objects/play_button.png");
|
||||||
this.load.image(LoginTextures.icon, "resources/logos/tcm_full.png");
|
this.load.image(LoginTextures.icon, "resources/logos/tcm_full.png");
|
||||||
// Note: arcade.png from the Phaser 3 examples at: https://github.com/photonstorm/phaser3-examples/tree/master/public/assets/fonts/bitmap
|
// 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');
|
this.load.bitmapFont(LoginTextures.mainFont, 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml');
|
||||||
cypressAsserter.preloadFinished();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
cypressAsserter.initStarted();
|
|
||||||
|
|
||||||
this.textField = new TextField(this, this.game.renderer.width / 2, 50, 'Enter your name:');
|
this.textField = new TextField(this, this.game.renderer.width / 2, 50, 'Enter your name:');
|
||||||
this.nameInput = new TextInput(this, this.game.renderer.width / 2, 70, 8, this.name,(text: string) => {
|
this.nameInput = new TextInput(this, this.game.renderer.width / 2, 70, 8, this.name,(text: string) => {
|
||||||
@ -59,8 +55,6 @@ export class LoginScene extends ResizableScene {
|
|||||||
}
|
}
|
||||||
this.login(this.name);
|
this.login(this.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
cypressAsserter.initFinished();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update(time: number, delta: number): void {
|
update(time: number, delta: number): void {
|
||||||
|
@ -9,6 +9,7 @@ import {localUserStore} from "../../Connexion/LocalUserStore";
|
|||||||
import {loadAllDefaultModels, loadCustomTexture} from "../Entity/PlayerTexturesLoadingManager";
|
import {loadAllDefaultModels, loadCustomTexture} from "../Entity/PlayerTexturesLoadingManager";
|
||||||
import {addLoader} from "../Components/Loader";
|
import {addLoader} from "../Components/Loader";
|
||||||
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
||||||
|
import {AbstractCharacterScene} from "./AbstractCharacterScene";
|
||||||
|
|
||||||
|
|
||||||
//todo: put this constants in a dedicated file
|
//todo: put this constants in a dedicated file
|
||||||
@ -21,7 +22,7 @@ enum LoginTextures {
|
|||||||
customizeButtonSelected = "customize_button_selected"
|
customizeButtonSelected = "customize_button_selected"
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SelectCharacterScene extends ResizableScene {
|
export class SelectCharacterScene extends AbstractCharacterScene {
|
||||||
private readonly nbCharactersPerRow = 6;
|
private readonly nbCharactersPerRow = 6;
|
||||||
private textField!: TextField;
|
private textField!: TextField;
|
||||||
private pressReturnField!: TextField;
|
private pressReturnField!: TextField;
|
||||||
@ -44,6 +45,13 @@ export class SelectCharacterScene extends ResizableScene {
|
|||||||
|
|
||||||
preload() {
|
preload() {
|
||||||
addLoader(this);
|
addLoader(this);
|
||||||
|
|
||||||
|
this.loadSelectSceneCharacters().then((bodyResourceDescriptions) => {
|
||||||
|
bodyResourceDescriptions.forEach((bodyResourceDescription) => {
|
||||||
|
this.playerModels.push(bodyResourceDescription);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
this.load.image(LoginTextures.playButton, "resources/objects/play_button.png");
|
this.load.image(LoginTextures.playButton, "resources/objects/play_button.png");
|
||||||
this.load.image(LoginTextures.icon, "resources/logos/tcm_full.png");
|
this.load.image(LoginTextures.icon, "resources/logos/tcm_full.png");
|
||||||
// Note: arcade.png from the Phaser 3 examples at: https://github.com/photonstorm/phaser3-examples/tree/master/public/assets/fonts/bitmap
|
// Note: arcade.png from the Phaser 3 examples at: https://github.com/photonstorm/phaser3-examples/tree/master/public/assets/fonts/bitmap
|
||||||
@ -51,18 +59,6 @@ export class SelectCharacterScene extends ResizableScene {
|
|||||||
this.playerModels = loadAllDefaultModels(this.load);
|
this.playerModels = loadAllDefaultModels(this.load);
|
||||||
this.load.image(LoginTextures.customizeButton, 'resources/objects/customize.png');
|
this.load.image(LoginTextures.customizeButton, 'resources/objects/customize.png');
|
||||||
this.load.image(LoginTextures.customizeButtonSelected, 'resources/objects/customize_selected.png');
|
this.load.image(LoginTextures.customizeButtonSelected, 'resources/objects/customize_selected.png');
|
||||||
|
|
||||||
const localUser = localUserStore.getLocalUser();
|
|
||||||
const textures = localUser?.textures;
|
|
||||||
if (textures) {
|
|
||||||
for (const texture of textures) {
|
|
||||||
if(texture.level !== -1){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const name = loadCustomTexture(this.load, texture);
|
|
||||||
this.playerModels.push({name: name, img: texture.url});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export class OutlinePipeline extends Phaser.Renderer.WebGL.Pipelines.MultiPipeline {
|
export class OutlinePipeline extends Phaser.Renderer.WebGL.Pipelines.TextureTintPipeline {
|
||||||
|
|
||||||
// the unique id of this pipeline
|
// the unique id of this pipeline
|
||||||
public static readonly KEY = 'Outline';
|
public static readonly KEY = 'Outline';
|
||||||
|
@ -60,7 +60,7 @@ export class UserInputManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
clearAllInputKeyboard(){
|
clearAllInputKeyboard(){
|
||||||
this.Scene.input.keyboard.removeAllKeys();
|
this.Scene.input.keyboard.removeAllListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
getEventListForGameTick(): ActiveEventList {
|
getEventListForGameTick(): ActiveEventList {
|
||||||
|
@ -1,21 +1,19 @@
|
|||||||
export class HtmlUtils {
|
export class HtmlUtils {
|
||||||
public static getElementByIdOrFail<T extends HTMLElement>(id: string): T {
|
public static getElementByIdOrFail<T extends HTMLElement>(id: string): T {
|
||||||
const elem = document.getElementById(id);
|
const elem = document.getElementById(id);
|
||||||
if (elem === null) {
|
if (HtmlUtils.isHtmlElement<T>(elem)) {
|
||||||
throw new Error("Cannot find HTML element with id '"+id+"'");
|
return elem;
|
||||||
}
|
}
|
||||||
// FIXME: does not check the type of the returned type
|
throw new Error("Cannot find HTML element with id '"+id+"'");
|
||||||
return elem as T;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static removeElementByIdOrFail<T extends HTMLElement>(id: string): T {
|
public static removeElementByIdOrFail<T extends HTMLElement>(id: string): T {
|
||||||
const elem = document.getElementById(id);
|
const elem = document.getElementById(id);
|
||||||
if (elem === null) {
|
if (HtmlUtils.isHtmlElement<T>(elem)) {
|
||||||
throw new Error("Cannot find HTML element with id '"+id+"'");
|
|
||||||
}
|
|
||||||
// FIXME: does not check the type of the returned type
|
|
||||||
elem.remove();
|
elem.remove();
|
||||||
return elem as T;
|
return elem;
|
||||||
|
}
|
||||||
|
throw new Error("Cannot find HTML element with id '"+id+"'");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static urlify(text: string): string {
|
public static urlify(text: string): string {
|
||||||
@ -24,4 +22,8 @@ export class HtmlUtils {
|
|||||||
return '<a href="' + url + '" target="_blank" style=":visited {color: white}">' + url + '</a>';
|
return '<a href="' + url + '" target="_blank" style=":visited {color: white}">' + url + '</a>';
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static isHtmlElement<T extends HTMLElement>(elem: HTMLElement | null): elem is T {
|
||||||
|
return elem !== null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import 'phaser';
|
import 'phaser';
|
||||||
import GameConfig = Phaser.Types.Core.GameConfig;
|
import GameConfig = Phaser.Types.Core.GameConfig;
|
||||||
import {DEBUG_MODE, JITSI_URL, RESOLUTION} from "./Enum/EnvironmentVariable";
|
import {DEBUG_MODE, JITSI_URL, RESOLUTION} from "./Enum/EnvironmentVariable";
|
||||||
import {cypressAsserter} from "./Cypress/CypressAsserter";
|
|
||||||
import {LoginScene} from "./Phaser/Login/LoginScene";
|
import {LoginScene} from "./Phaser/Login/LoginScene";
|
||||||
import {ReconnectingScene} from "./Phaser/Reconnecting/ReconnectingScene";
|
import {ReconnectingScene} from "./Phaser/Reconnecting/ReconnectingScene";
|
||||||
import {SelectCharacterScene} from "./Phaser/Login/SelectCharacterScene";
|
import {SelectCharacterScene} from "./Phaser/Login/SelectCharacterScene";
|
||||||
@ -93,16 +92,15 @@ const config: GameConfig = {
|
|||||||
},
|
},
|
||||||
callbacks: {
|
callbacks: {
|
||||||
postBoot: game => {
|
postBoot: game => {
|
||||||
const renderer = game.renderer;
|
// Commented out to try to fix MacOS bug
|
||||||
|
/*const renderer = game.renderer;
|
||||||
if (renderer instanceof WebGLRenderer) {
|
if (renderer instanceof WebGLRenderer) {
|
||||||
renderer.pipelines.add(OutlinePipeline.KEY, new OutlinePipeline(game));
|
renderer.pipelines.add(OutlinePipeline.KEY, new OutlinePipeline(game));
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
cypressAsserter.gameStarted();
|
|
||||||
|
|
||||||
const game = new Phaser.Game(config);
|
const game = new Phaser.Game(config);
|
||||||
|
|
||||||
window.addEventListener('resize', function (event) {
|
window.addEventListener('resize', function (event) {
|
||||||
|
@ -1771,7 +1771,7 @@ eventemitter3@^2.0.3:
|
|||||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-2.0.3.tgz#b5e1079b59fb5e1ba2771c0a993be060a58c99ba"
|
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-2.0.3.tgz#b5e1079b59fb5e1ba2771c0a993be060a58c99ba"
|
||||||
integrity sha1-teEHm1n7XhuidxwKmTvgYKWMmbo=
|
integrity sha1-teEHm1n7XhuidxwKmTvgYKWMmbo=
|
||||||
|
|
||||||
eventemitter3@^4.0.0, eventemitter3@^4.0.7:
|
eventemitter3@^4.0.0, eventemitter3@^4.0.4:
|
||||||
version "4.0.7"
|
version "4.0.7"
|
||||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
||||||
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
|
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
|
||||||
@ -1829,7 +1829,7 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
homedir-polyfill "^1.0.1"
|
homedir-polyfill "^1.0.1"
|
||||||
|
|
||||||
exports-loader@^1.1.1:
|
exports-loader@^1.1.0:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/exports-loader/-/exports-loader-1.1.1.tgz#88c9a6877ee6a5519d7c41a016bdd99148421e69"
|
resolved "https://registry.yarnpkg.com/exports-loader/-/exports-loader-1.1.1.tgz#88c9a6877ee6a5519d7c41a016bdd99148421e69"
|
||||||
integrity sha512-CmyhIR2sJ3KOfVsHjsR0Yvo+0lhRhRMAevCbB8dhTVLHsZPs0lCQTvRmR9YNvBXDBxUuhmCE2f54KqEjZUaFrg==
|
integrity sha512-CmyhIR2sJ3KOfVsHjsR0Yvo+0lhRhRMAevCbB8dhTVLHsZPs0lCQTvRmR9YNvBXDBxUuhmCE2f54KqEjZUaFrg==
|
||||||
@ -2528,7 +2528,7 @@ import-local@^2.0.0:
|
|||||||
pkg-dir "^3.0.0"
|
pkg-dir "^3.0.0"
|
||||||
resolve-cwd "^2.0.0"
|
resolve-cwd "^2.0.0"
|
||||||
|
|
||||||
imports-loader@^1.2.0:
|
imports-loader@^1.1.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/imports-loader/-/imports-loader-1.2.0.tgz#b06823d0bb42e6f5ff89bc893829000eda46693f"
|
resolved "https://registry.yarnpkg.com/imports-loader/-/imports-loader-1.2.0.tgz#b06823d0bb42e6f5ff89bc893829000eda46693f"
|
||||||
integrity sha512-zPvangKEgrrPeqeUqH0Uhc59YqK07JqZBi9a9cQ3v/EKUIqrbJHY4CvUrDus2lgQa5AmPyXuGrWP8JJTqzE5RQ==
|
integrity sha512-zPvangKEgrrPeqeUqH0Uhc59YqK07JqZBi9a9cQ3v/EKUIqrbJHY4CvUrDus2lgQa5AmPyXuGrWP8JJTqzE5RQ==
|
||||||
@ -3663,14 +3663,14 @@ pbkdf2@^3.0.3:
|
|||||||
safe-buffer "^5.0.1"
|
safe-buffer "^5.0.1"
|
||||||
sha.js "^2.4.8"
|
sha.js "^2.4.8"
|
||||||
|
|
||||||
phaser@^3.52.0:
|
phaser@3.24.1:
|
||||||
version "3.52.0"
|
version "3.24.1"
|
||||||
resolved "https://registry.yarnpkg.com/phaser/-/phaser-3.52.0.tgz#834dd7a7717308c2576d2450d0806317cf3d1ea8"
|
resolved "https://registry.yarnpkg.com/phaser/-/phaser-3.24.1.tgz#376e0c965d2a35af37c06ee78627dafbde5be017"
|
||||||
integrity sha512-oH39AUXR+cletB3GIvLnVO2J7/M6xs0D0LamVdCrbCDO3jckQOVBcqR6SJ2wam+4D5iJTCXv8K+FmxFzcTUWuA==
|
integrity sha512-WbrRMkbpEzarkfrq83akeauc6b8xNxsOTpDygyW7wrU2G2ne6kOYu3hji4UAaGnZaOLrVuj8ycYPjX9P1LxcDw==
|
||||||
dependencies:
|
dependencies:
|
||||||
eventemitter3 "^4.0.7"
|
eventemitter3 "^4.0.4"
|
||||||
exports-loader "^1.1.1"
|
exports-loader "^1.1.0"
|
||||||
imports-loader "^1.2.0"
|
imports-loader "^1.1.0"
|
||||||
path "^0.12.7"
|
path "^0.12.7"
|
||||||
|
|
||||||
picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1:
|
picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1:
|
||||||
|
Loading…
Reference in New Issue
Block a user