From 5255847452fcc521d81193ea8f20c6cae380e4bb Mon Sep 17 00:00:00 2001 From: Kharhamel Date: Thu, 7 Oct 2021 11:04:40 +0200 Subject: [PATCH 1/2] FIX: if a conversion group move to another user, this user will be added to the group --- back/src/Model/GameRoom.ts | 2 + back/src/Model/Group.ts | 32 ++++++---- back/src/Model/PositionNotifier.ts | 32 +++++++++- back/src/Services/GaugeManager.ts | 9 --- back/tests/getNearbyDescriptorsMatrixTest.ts | 67 ++++++++++++++++++++ 5 files changed, 117 insertions(+), 25 deletions(-) create mode 100644 back/tests/getNearbyDescriptorsMatrixTest.ts diff --git a/back/src/Model/GameRoom.ts b/back/src/Model/GameRoom.ts index 5667146a..74849fe0 100644 --- a/back/src/Model/GameRoom.ts +++ b/back/src/Model/GameRoom.ts @@ -181,6 +181,7 @@ export class GameRoom { private updateUserGroup(user: User): void { user.group?.updatePosition(); + user.group?.searchForNearbyUsers(); if (user.silent) { return; @@ -206,6 +207,7 @@ export class GameRoom { const group: Group = new Group( this.roomUrl, [user, closestUser], + this.groupRadius, this.connectCallback, this.disconnectCallback, this.positionNotifier diff --git a/back/src/Model/Group.ts b/back/src/Model/Group.ts index 5a0f3be6..931ddda5 100644 --- a/back/src/Model/Group.ts +++ b/back/src/Model/Group.ts @@ -1,10 +1,10 @@ -import { ConnectCallback, DisconnectCallback } from "./GameRoom"; +import { ConnectCallback, DisconnectCallback, GameRoom } from "./GameRoom"; import { User } from "./User"; import { PositionInterface } from "_Model/PositionInterface"; import { Movable } from "_Model/Movable"; import { PositionNotifier } from "_Model/PositionNotifier"; -import { gaugeManager } from "../Services/GaugeManager"; import { MAX_PER_GROUP } from "../Enum/EnvironmentVariable"; +import type { Zone } from "../Model/Zone"; export class Group implements Movable { private static nextId: number = 1; @@ -13,13 +13,14 @@ export class Group implements Movable { private users: Set; private x!: number; private y!: number; - private hasEditedGauge: boolean = false; private wasDestroyed: boolean = false; private roomId: string; + private currentZone: Zone | null = null; constructor( roomId: string, users: User[], + private groupRadius: number, private connectCallback: ConnectCallback, private disconnectCallback: DisconnectCallback, private positionNotifier: PositionNotifier @@ -28,13 +29,6 @@ export class Group implements Movable { this.users = new Set(); this.id = Group.nextId; Group.nextId++; - //we only send a event for prometheus metrics if the group lives more than 5 seconds - setTimeout(() => { - if (!this.wasDestroyed) { - this.hasEditedGauge = true; - gaugeManager.incNbGroupsPerRoomGauge(roomId); - } - }, 5000); users.forEach((user: User) => { this.join(user); @@ -85,9 +79,22 @@ export class Group implements Movable { this.y = y; if (oldX === undefined) { - this.positionNotifier.enter(this); + this.currentZone = this.positionNotifier.enter(this); } else { - this.positionNotifier.updatePosition(this, { x, y }, { x: oldX, y: oldY }); + this.currentZone = this.positionNotifier.updatePosition(this, { x, y }, { x: oldX, y: oldY }); + } + } + + searchForNearbyUsers(): void { + if (!this.currentZone) return; + + for (const user of this.positionNotifier.getAllUsersInSquareAroundZone(this.currentZone)) { + if (user.group || this.isFull()) return; //we ignore users that are already in a group. + const distance = GameRoom.computeDistanceBetweenPositions(user.getPosition(), this.getPosition()); + if (distance < this.groupRadius) { + this.join(user); + this.updatePosition(); + } } } @@ -126,7 +133,6 @@ export class Group implements Movable { * Usually used when there is only one user left. */ destroy(): void { - if (this.hasEditedGauge) gaugeManager.decNbGroupsPerRoomGauge(this.roomId); for (const user of this.users) { this.leave(user); } diff --git a/back/src/Model/PositionNotifier.ts b/back/src/Model/PositionNotifier.ts index 4f911637..2052f229 100644 --- a/back/src/Model/PositionNotifier.ts +++ b/back/src/Model/PositionNotifier.ts @@ -12,7 +12,7 @@ import { EmoteCallback, EntersCallback, LeavesCallback, MovesCallback, Zone } fr import { Movable } from "_Model/Movable"; import { PositionInterface } from "_Model/PositionInterface"; import { ZoneSocket } from "../RoomManager"; -import { User } from "_Model/User"; +import { User } from "../Model/User"; import { EmoteEventMessage } from "../Messages/generated/messages_pb"; interface ZoneDescriptor { @@ -20,6 +20,17 @@ interface ZoneDescriptor { j: number; } +export function* getNearbyDescriptorsMatrix(middleZoneDescriptor: ZoneDescriptor): Generator { + for (let n = 0; n < 9; n++) { + const i = middleZoneDescriptor.i + ((n % 3) - 1); + const j = middleZoneDescriptor.j + (Math.floor(n / 3) - 1); + + if (i >= 0 && j >= 0) { + yield { i, j }; + } + } +} + export class PositionNotifier { // TODO: we need a way to clean the zones if no one is in the zone and no one listening (to free memory!) @@ -41,14 +52,15 @@ export class PositionNotifier { }; } - public enter(thing: Movable): void { + public enter(thing: Movable): Zone { const position = thing.getPosition(); const zoneDesc = this.getZoneDescriptorFromCoordinates(position.x, position.y); const zone = this.getZone(zoneDesc.i, zoneDesc.j); zone.enter(thing, null, position); + return zone; } - public updatePosition(thing: Movable, newPosition: PositionInterface, oldPosition: PositionInterface): void { + public updatePosition(thing: Movable, newPosition: PositionInterface, oldPosition: PositionInterface): Zone { // Did we change zone? const oldZoneDesc = this.getZoneDescriptorFromCoordinates(oldPosition.x, oldPosition.y); const newZoneDesc = this.getZoneDescriptorFromCoordinates(newPosition.x, newPosition.y); @@ -62,9 +74,11 @@ export class PositionNotifier { // Enter new zone newZone.enter(thing, oldZone, newPosition); + return newZone; } else { const zone = this.getZone(oldZoneDesc.i, oldZoneDesc.j); zone.move(thing, newPosition); + return zone; } } @@ -106,4 +120,16 @@ export class PositionNotifier { const zone = this.getZone(zoneDesc.i, zoneDesc.j); zone.emitEmoteEvent(emoteEventMessage); } + + public *getAllUsersInSquareAroundZone(zone: Zone): Generator { + const zoneDescriptor = this.getZoneDescriptorFromCoordinates(zone.x, zone.y); + for (const d of getNearbyDescriptorsMatrix(zoneDescriptor)) { + const zone = this.getZone(d.i, d.j); + for (const thing of zone.getThings()) { + if (thing instanceof User) { + yield thing; + } + } + } + } } diff --git a/back/src/Services/GaugeManager.ts b/back/src/Services/GaugeManager.ts index 6d2183d8..740692a8 100644 --- a/back/src/Services/GaugeManager.ts +++ b/back/src/Services/GaugeManager.ts @@ -52,15 +52,6 @@ class GaugeManager { this.nbClientsGauge.dec(); this.nbClientsPerRoomGauge.dec({ room: roomId }); } - - incNbGroupsPerRoomGauge(roomId: string): void { - this.nbGroupsPerRoomCounter.inc({ room: roomId }); - this.nbGroupsPerRoomGauge.inc({ room: roomId }); - } - - decNbGroupsPerRoomGauge(roomId: string): void { - this.nbGroupsPerRoomGauge.dec({ room: roomId }); - } } export const gaugeManager = new GaugeManager(); diff --git a/back/tests/getNearbyDescriptorsMatrixTest.ts b/back/tests/getNearbyDescriptorsMatrixTest.ts new file mode 100644 index 00000000..6c81db76 --- /dev/null +++ b/back/tests/getNearbyDescriptorsMatrixTest.ts @@ -0,0 +1,67 @@ +import "jasmine"; +import { getNearbyDescriptorsMatrix } from "../src/Model/PositionNotifier"; + +describe("getNearbyDescriptorsMatrix", () => { + it("should create a matrix of coordinates in a square around the parameter", () => { + const matrix = []; + for (const d of getNearbyDescriptorsMatrix({ i: 1, j: 1 })) { + matrix.push(d); + } + + expect(matrix).toEqual([ + { i: 0, j: 0 }, + { i: 1, j: 0 }, + { i: 2, j: 0 }, + { i: 0, j: 1 }, + { i: 1, j: 1 }, + { i: 2, j: 1 }, + { i: 0, j: 2 }, + { i: 1, j: 2 }, + { i: 2, j: 2 }, + ]); + }); + + it("should create a matrix of coordinates in a square around the parameter bis", () => { + const matrix = []; + for (const d of getNearbyDescriptorsMatrix({ i: 8, j: 3 })) { + matrix.push(d); + } + + expect(matrix).toEqual([ + { i: 7, j: 2 }, + { i: 8, j: 2 }, + { i: 9, j: 2 }, + { i: 7, j: 3 }, + { i: 8, j: 3 }, + { i: 9, j: 3 }, + { i: 7, j: 4 }, + { i: 8, j: 4 }, + { i: 9, j: 4 }, + ]); + }); + + it("should not create a matrix with negative coordinates", () => { + const matrix = []; + for (const d of getNearbyDescriptorsMatrix({ i: 0, j: 0 })) { + matrix.push(d); + } + + expect(matrix).toEqual([ + { i: 0, j: 0 }, + { i: 1, j: 0 }, + { i: 0, j: 1 }, + { i: 1, j: 1 }, + ]); + }); + + /*it("should not create a matrix with coordinates bigger than its dimmensions", () => { + const matrix = getNearbyDescriptorsMatrix({i: 4, j: 4}, 5, 5); + + expect(matrix).toEqual([ + {i: 3,j: 3}, + {i: 4,j: 3}, + {i: 3,j: 4}, + {i: 4,j: 4}, + ]) + });*/ +}); From 59fa68e0639b3aa8e6a0db7e4421d51a9c9d0c94 Mon Sep 17 00:00:00 2001 From: Kharhamel Date: Fri, 8 Oct 2021 11:53:45 +0200 Subject: [PATCH 2/2] FIX: updated posthog client version and fixed a bug with its toolbar --- front/package.json | 2 +- front/src/Administration/AnalyticsClient.ts | 4 ++++ front/yarn.lock | 8 ++++---- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/front/package.json b/front/package.json index 8fd4f4c3..ec81d8a7 100644 --- a/front/package.json +++ b/front/package.json @@ -50,7 +50,7 @@ "phaser": "^3.54.0", "phaser-animated-tiles": "workadventure/phaser-animated-tiles#da68bbededd605925621dd4f03bd27e69284b254", "phaser3-rex-plugins": "^1.1.42", - "posthog-js": "^1.13.12", + "posthog-js": "^1.14.1", "queue-typescript": "^1.0.1", "quill": "1.3.6", "quill-delta-to-html": "^0.12.0", diff --git a/front/src/Administration/AnalyticsClient.ts b/front/src/Administration/AnalyticsClient.ts index f73a1981..c8f13e3c 100644 --- a/front/src/Administration/AnalyticsClient.ts +++ b/front/src/Administration/AnalyticsClient.ts @@ -1,4 +1,6 @@ import { POSTHOG_API_KEY, POSTHOG_URL } from "../Enum/EnvironmentVariable"; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +declare let window: any; class AnalyticsClient { // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -8,6 +10,8 @@ class AnalyticsClient { if (POSTHOG_API_KEY && POSTHOG_URL) { this.posthogPromise = import("posthog-js").then(({ default: posthog }) => { posthog.init(POSTHOG_API_KEY, { api_host: POSTHOG_URL, disable_cookie: true }); + //the posthog toolbar need a reference in window to be able to work + window.posthog = posthog; return posthog; }); } else { diff --git a/front/yarn.lock b/front/yarn.lock index b2c0f785..f94e659f 100644 --- a/front/yarn.lock +++ b/front/yarn.lock @@ -4494,10 +4494,10 @@ postcss@^8.2.10: nanoid "^3.1.23" source-map "^0.6.1" -posthog-js@^1.13.12: - version "1.13.12" - resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.13.12.tgz#b54efcb92de43724c889048135ccaae3dc4b874c" - integrity sha512-MU1I0zSVhdCcnWI8jAZLtbNJmjfg9AnhUDq5dUzNkb0qPXtNz17BekalnNwDMKs0Zlek3UCOVsIpyc85M+VRNA== +posthog-js@^1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.14.1.tgz#68553b9074c686784b994b3f433ad035b241deaa" + integrity sha512-gVFk6fsTxG9T+5oqZghffYovENSrs05v3hQMiRQENtGlsHGpt1fnoQ52En8Vg5brMxqLv1XZO4lMgm12/ubH0Q== dependencies: "@sentry/types" "^6.11.0" fflate "^0.4.1"