Merge pull request #1147 from thecodingmachine/develop

Deploy 2021-06-08
This commit is contained in:
David Négrier 2021-06-08 18:46:10 +02:00 committed by GitHub
commit 856b643c6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 149 additions and 187 deletions

View File

@ -1,9 +1,6 @@
import { import {
BatchMessage,
PusherToBackMessage,
ServerToAdminClientMessage, ServerToAdminClientMessage,
ServerToClientMessage, UserJoinedRoomMessage, UserLeftRoomMessage
SubMessage, UserJoinedRoomMessage, UserLeftRoomMessage
} from "../Messages/generated/messages_pb"; } from "../Messages/generated/messages_pb";
import {AdminSocket} from "../RoomManager"; import {AdminSocket} from "../RoomManager";

View File

@ -108,6 +108,7 @@ export class GameRoom {
this.positionNotifier, this.positionNotifier,
socket, socket,
joinRoomMessage.getTagList(), joinRoomMessage.getTagList(),
joinRoomMessage.getVisitcardurl(),
joinRoomMessage.getName(), joinRoomMessage.getName(),
ProtobufUtils.toCharacterLayerObjects(joinRoomMessage.getCharacterlayerList()), ProtobufUtils.toCharacterLayerObjects(joinRoomMessage.getCharacterlayerList()),
joinRoomMessage.getCompanion() joinRoomMessage.getCompanion()

View File

@ -22,6 +22,7 @@ export class User implements Movable {
private positionNotifier: PositionNotifier, private positionNotifier: PositionNotifier,
public readonly socket: UserSocket, public readonly socket: UserSocket,
public readonly tags: string[], public readonly tags: string[],
public readonly visitCardUrl: string|null,
public readonly name: string, public readonly name: string,
public readonly characterLayers: CharacterLayer[], public readonly characterLayers: CharacterLayer[],
public readonly companion?: CompanionMessage public readonly companion?: CompanionMessage

View File

@ -11,7 +11,7 @@ import {
JoinRoomMessage, JoinRoomMessage,
PlayGlobalMessage, PlayGlobalMessage,
PusherToBackMessage, PusherToBackMessage,
QueryJitsiJwtMessage, RefreshRoomPromptMessage, RequestVisitCardMessage, QueryJitsiJwtMessage, RefreshRoomPromptMessage,
ServerToAdminClientMessage, ServerToAdminClientMessage,
ServerToClientMessage, ServerToClientMessage,
SilentMessage, SilentMessage,
@ -74,8 +74,6 @@ const roomManager: IRoomManagerServer = {
socketManager.handleQueryJitsiJwtMessage(user, message.getQueryjitsijwtmessage() as QueryJitsiJwtMessage); socketManager.handleQueryJitsiJwtMessage(user, message.getQueryjitsijwtmessage() as QueryJitsiJwtMessage);
} else if (message.hasEmotepromptmessage()){ } else if (message.hasEmotepromptmessage()){
socketManager.handleEmoteEventMessage(room, user, message.getEmotepromptmessage() as EmotePromptMessage); socketManager.handleEmoteEventMessage(room, user, message.getEmotepromptmessage() as EmotePromptMessage);
} else if (message.hasRequestvisitcardmessage()) {
socketManager.handleRequestVisitCardMessage(room, user, message.getRequestvisitcardmessage() as RequestVisitCardMessage);
}else if (message.hasSendusermessage()) { }else if (message.hasSendusermessage()) {
const sendUserMessage = message.getSendusermessage(); const sendUserMessage = message.getSendusermessage();
if(sendUserMessage !== undefined) { if(sendUserMessage !== undefined) {

View File

@ -1,22 +0,0 @@
import {ADMIN_API_TOKEN, ADMIN_API_URL} from "../Enum/EnvironmentVariable";
import Axios from "axios";
class AdminApi {
fetchVisitCardUrl(membershipUuid: string): Promise<string> {
if (ADMIN_API_URL) {
return Axios.get(ADMIN_API_URL + '/api/membership/'+membershipUuid,
{headers: {"Authorization": `${ADMIN_API_TOKEN}`}}
).then((res) => {
return res.data;
}).catch(() => {
return 'INVALID';
});
} else {
return Promise.resolve('INVALID')
}
}
}
export const adminApi = new AdminApi();

View File

@ -27,7 +27,7 @@ import {
WorldFullWarningMessage, WorldFullWarningMessage,
UserLeftZoneMessage, UserLeftZoneMessage,
EmoteEventMessage, EmoteEventMessage,
BanUserMessage, RefreshRoomMessage, EmotePromptMessage, RequestVisitCardMessage, VisitCardMessage, BanUserMessage, RefreshRoomMessage, EmotePromptMessage,
} from "../Messages/generated/messages_pb"; } from "../Messages/generated/messages_pb";
import {User, UserSocket} from "../Model/User"; import {User, UserSocket} from "../Model/User";
import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils"; import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils";
@ -51,7 +51,6 @@ import {Zone} from "_Model/Zone";
import Debug from "debug"; import Debug from "debug";
import {Admin} from "_Model/Admin"; import {Admin} from "_Model/Admin";
import crypto from "crypto"; import crypto from "crypto";
import {adminApi} from "./AdminApi";
const debug = Debug('sockermanager'); const debug = Debug('sockermanager');
@ -300,6 +299,9 @@ export class SocketManager {
userJoinedZoneMessage.setCharacterlayersList(ProtobufUtils.toCharacterLayerMessages(thing.characterLayers)); userJoinedZoneMessage.setCharacterlayersList(ProtobufUtils.toCharacterLayerMessages(thing.characterLayers));
userJoinedZoneMessage.setPosition(ProtobufUtils.toPositionMessage(thing.getPosition())); userJoinedZoneMessage.setPosition(ProtobufUtils.toPositionMessage(thing.getPosition()));
userJoinedZoneMessage.setFromzone(this.toProtoZone(fromZone)); userJoinedZoneMessage.setFromzone(this.toProtoZone(fromZone));
if (thing.visitCardUrl) {
userJoinedZoneMessage.setVisitcardurl(thing.visitCardUrl);
}
userJoinedZoneMessage.setCompanion(thing.companion); userJoinedZoneMessage.setCompanion(thing.companion);
const subMessage = new SubToPusherMessage(); const subMessage = new SubToPusherMessage();
@ -605,6 +607,9 @@ export class SocketManager {
userJoinedMessage.setName(thing.name); userJoinedMessage.setName(thing.name);
userJoinedMessage.setCharacterlayersList(ProtobufUtils.toCharacterLayerMessages(thing.characterLayers)); userJoinedMessage.setCharacterlayersList(ProtobufUtils.toCharacterLayerMessages(thing.characterLayers));
userJoinedMessage.setPosition(ProtobufUtils.toPositionMessage(thing.getPosition())); userJoinedMessage.setPosition(ProtobufUtils.toPositionMessage(thing.getPosition()));
if (thing.visitCardUrl) {
userJoinedMessage.setVisitcardurl(thing.visitCardUrl);
}
userJoinedMessage.setCompanion(thing.companion); userJoinedMessage.setCompanion(thing.companion);
const subMessage = new SubToPusherMessage(); const subMessage = new SubToPusherMessage();
@ -770,21 +775,6 @@ export class SocketManager {
emoteEventMessage.setActoruserid(user.id); emoteEventMessage.setActoruserid(user.id);
room.emitEmoteEvent(user, emoteEventMessage); room.emitEmoteEvent(user, emoteEventMessage);
} }
async handleRequestVisitCardMessage(room: GameRoom, user: User, requestvisitcardmessage: RequestVisitCardMessage): Promise<void> {
const targetUser = room.getUserById(requestvisitcardmessage.getTargetuserid());
if (!targetUser) {
throw 'Could not find user for id '+requestvisitcardmessage.getTargetuserid();
}
const url = await adminApi.fetchVisitCardUrl(targetUser.uuid);
const visitCardMessage = new VisitCardMessage();
visitCardMessage.setUrl(url);
const clientMessage = new ServerToClientMessage();
clientMessage.setVisitcardmessage(visitCardMessage);
user.socket.write(clientMessage);
}
} }
export const socketManager = new SocketManager(); export const socketManager = new SocketManager();

View File

@ -1,10 +1,6 @@
import "jasmine"; import "jasmine";
import {GameRoom, ConnectCallback, DisconnectCallback } from "_Model/GameRoom";
import {Point} from "../src/Model/Websocket/MessageUserPosition";
import { Group } from "../src/Model/Group";
import {PositionNotifier} from "../src/Model/PositionNotifier"; import {PositionNotifier} from "../src/Model/PositionNotifier";
import {User, UserSocket} from "../src/Model/User"; import {User, UserSocket} from "../src/Model/User";
import {PointInterface} from "../src/Model/Websocket/PointInterface";
import {Zone} from "_Model/Zone"; import {Zone} from "_Model/Zone";
import {Movable} from "_Model/Movable"; import {Movable} from "_Model/Movable";
import {PositionInterface} from "_Model/PositionInterface"; import {PositionInterface} from "_Model/PositionInterface";
@ -30,14 +26,14 @@ describe("PositionNotifier", () => {
y: 500, y: 500,
moving: false, moving: false,
direction: 'down' direction: 'down'
}, false, positionNotifier, {} as UserSocket, [], 'foo', []); }, false, positionNotifier, {} as UserSocket, [], null, 'foo', []);
const user2 = new User(2, 'test', '10.0.0.2', { const user2 = new User(2, 'test', '10.0.0.2', {
x: -9999, x: -9999,
y: -9999, y: -9999,
moving: false, moving: false,
direction: 'down' direction: 'down'
}, false, positionNotifier, {} as UserSocket, [], 'foo', []); }, false, positionNotifier, {} as UserSocket, [], null, 'foo', []);
positionNotifier.addZoneListener({} as ZoneSocket, 0, 0); positionNotifier.addZoneListener({} as ZoneSocket, 0, 0);
positionNotifier.addZoneListener({} as ZoneSocket, 0, 1); positionNotifier.addZoneListener({} as ZoneSocket, 0, 1);
@ -105,14 +101,14 @@ describe("PositionNotifier", () => {
y: 500, y: 500,
moving: false, moving: false,
direction: 'down' direction: 'down'
}, false, positionNotifier, {} as UserSocket, [], 'foo', []); }, false, positionNotifier, {} as UserSocket, [], null, 'foo', []);
const user2 = new User(2, 'test', '10.0.0.2', { const user2 = new User(2, 'test', '10.0.0.2', {
x: 0, x: 0,
y: 0, y: 0,
moving: false, moving: false,
direction: 'down' direction: 'down'
}, false, positionNotifier, {} as UserSocket, [], 'foo', []); }, false, positionNotifier, {} as UserSocket, [], null, 'foo', []);
const listener = {} as ZoneSocket; const listener = {} as ZoneSocket;
positionNotifier.addZoneListener(listener, 0, 0); positionNotifier.addZoneListener(listener, 0, 0);

View File

@ -209,9 +209,9 @@
} }
}, },
"glob-parent": { "glob-parent": {
"version": "5.1.1", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"requires": { "requires": {
"is-glob": "^4.0.1" "is-glob": "^4.0.1"
} }

View File

@ -148,8 +148,8 @@ get-stdin@^4.0.1:
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
glob-parent@~5.1.0: glob-parent@~5.1.0:
version "5.1.1" version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
dependencies: dependencies:
is-glob "^4.0.1" is-glob "^4.0.1"

View File

@ -64,7 +64,7 @@
<button id="adminConsoleButton">Admin console</button> <button id="adminConsoleButton">Admin console</button>
</section> </section>
<section id="socialLinks" hidden> <section id="socialLinks" hidden>
<a class="not-button" href="https://www.facebook.com/workadventurebytcm" target="_blank"><img class="not-button" src="/resources/objects/facebook-icon.png"/></a> <a class="not-button" href="https://www.facebook.com/workadventure.WA" target="_blank"><img class="not-button" src="/resources/objects/facebook-icon.png"/></a>
<a class="not-button" href="https://twitter.com/Workadventure_" target="_blank"><img class="not-button" src="/resources/objects/twitter-icon.png"/></a> <a class="not-button" href="https://twitter.com/Workadventure_" target="_blank"><img class="not-button" src="/resources/objects/twitter-icon.png"/></a>
</section> </section>
</main> </main>

View File

@ -70,15 +70,23 @@ class IframeListener {
// Do we trust the sender of this message? // Do we trust the sender of this message?
// Let's only accept messages from the iframe that are allowed. // Let's only accept messages from the iframe that are allowed.
// Note: maybe we could restrict on the domain too for additional security (in case the iframe goes to another domain). // Note: maybe we could restrict on the domain too for additional security (in case the iframe goes to another domain).
let foundSrc: string | null = null; let foundSrc: string | undefined;
for (const iframe of this.iframes) {
if (iframe.contentWindow === message.source) { foundSrc = [...this.scripts.keys()].find(key => {
foundSrc = iframe.src; return this.scripts.get(key)?.contentWindow == message.source
break; });
if (foundSrc === undefined) {
for (const iframe of this.iframes) {
if (iframe.contentWindow === message.source) {
foundSrc = iframe.src;
break;
}
}
if (foundSrc === undefined) {
return;
} }
}
if (!foundSrc) {
return;
} }
const payload = message.data; const payload = message.data;
@ -106,11 +114,7 @@ class IframeListener {
this._loadSoundStream.next(payload.data); this._loadSoundStream.next(payload.data);
} }
else if (payload.type === 'openCoWebSite' && isOpenCoWebsite(payload.data)) { else if (payload.type === 'openCoWebSite' && isOpenCoWebsite(payload.data)) {
const scriptUrl = [...this.scripts.keys()].find(key => { scriptUtils.openCoWebsite(payload.data.url, foundSrc);
return this.scripts.get(key)?.contentWindow == message.source
})
scriptUtils.openCoWebsite(payload.data.url, scriptUrl || foundSrc);
} }
else if (payload.type === 'closeCoWebSite') { else if (payload.type === 'closeCoWebSite') {

View File

@ -61,8 +61,8 @@
onDestroy(unsubscribe); onDestroy(unsubscribe);
function normalizeDeviceName(label: string): string { function normalizeDeviceName(label: string): string {
// remove text in parenthesis // remove IDs (that can appear in Chrome, like: "HD Pro Webcam (4df7:4eda)"
return label.replace(/\([^()]*\)/g, '').trim(); return label.replace(/(\([[0-9a-f]{4}:[0-9a-f]{4}\))/g, '').trim();
} }
function selectCamera() { function selectCamera() {
@ -93,7 +93,7 @@
{#if $cameraListStore.length > 1 } {#if $cameraListStore.length > 1 }
<div class="control-group"> <div class="control-group">
<img src={cinemaImg} alt="Camera" /> <img src={cinemaImg} alt="Camera" />
<div class="nes-select"> <div class="nes-select is-dark">
<select bind:value={selectedCamera} on:change={selectCamera}> <select bind:value={selectedCamera} on:change={selectCamera}>
{#each $cameraListStore as camera} {#each $cameraListStore as camera}
<option value={camera.deviceId}> <option value={camera.deviceId}>
@ -108,7 +108,7 @@
{#if $microphoneListStore.length > 1 } {#if $microphoneListStore.length > 1 }
<div class="control-group"> <div class="control-group">
<img src={microphoneImg} alt="Microphone" /> <img src={microphoneImg} alt="Microphone" />
<div class="nes-select"> <div class="nes-select is-dark">
<select bind:value={selectedMicrophone} on:change={selectMicrophone}> <select bind:value={selectedMicrophone} on:change={selectMicrophone}>
{#each $microphoneListStore as microphone} {#each $microphoneListStore as microphone}
<option value={microphone.deviceId}> <option value={microphone.deviceId}>
@ -136,7 +136,7 @@
margin-top: 3vh; margin-top: 3vh;
margin-bottom: 3vh; margin-bottom: 3vh;
min-height: 10vh; min-height: 10vh;
width: 50%; width: 50vw;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
@ -144,12 +144,12 @@
font-family: "Press Start 2P"; font-family: "Press Start 2P";
margin-top: 1vh; margin-top: 1vh;
margin-bottom: 1vh; margin-bottom: 1vh;
}
option { option {
font-family: "Press Start 2P"; font-family: "Press Start 2P";
} }
} }
}
section.action{ section.action{
text-align: center; text-align: center;
@ -173,6 +173,8 @@
.control-group { .control-group {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
max-height: 60px;
margin-top: 10px;
img { img {
width: 30px; width: 30px;
@ -210,8 +212,18 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
}
@media only screen and (max-width: 800px) {
.enableCameraScene h2 {
font-size: 80%;
}
.enableCameraScene .control-group .nes-select {
font-size: 80%;
}
.enableCameraScene button.letsgo {
font-size: 160%;
}
} }
</style> </style>

View File

@ -14,14 +14,15 @@
pointer-events: all; pointer-events: all;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
width: 515px; width: 530px;
margin-top: 200px; margin-top: 200px;
max-width: 100vw;
.defaultCard { .defaultCard {
border-radius: 5px; border-radius: 5px;
border: 2px black solid; border: 2px black solid;
background-color: whitesmoke; background-color: whitesmoke;
width: 500px; width: 530px;
header { header {
padding: 5px; padding: 5px;
@ -30,7 +31,7 @@
iframe { iframe {
border: 0; border: 0;
width: 515px; width: 530px;
height: 270px; height: 270px;
overflow: hidden; overflow: hidden;
} }
@ -43,22 +44,8 @@
<section class="visitCard" transition:fly="{{ y: -200, duration: 1000 }}"> <section class="visitCard" transition:fly="{{ y: -200, duration: 1000 }}">
{#if visitCardUrl === 'INVALID'} <iframe title="visitCardTitle" src={visitCardUrl}></iframe>
<div class="defaultCard">
<header>
<h2>Sorry</h2>
<p style="font-style: italic;">This user doesn't have a contact card.</p>
</header>
<main style="padding: 5px; background-color: gray">
<p>Maybe he is offline, or this feature is deactivated.</p>
</main>
</div>
{:else}
<iframe title="visitCardTitle" src={visitCardUrl}></iframe>
{/if}
<div class="buttonContainer"> <div class="buttonContainer">
<button class="nes-btn is-popUpElement" on:click={closeCard}>Close</button> <button class="nes-btn is-popUpElement" on:click={closeCard}>Close</button>
</div> </div>
</section> </section>

View File

@ -1,5 +1,3 @@
import {PlayerAnimationDirections} from "../Phaser/Player/Animation";
import {UserSimplePeerInterface} from "../WebRtc/SimplePeer";
import type {SignalData} from "simple-peer"; import type {SignalData} from "simple-peer";
import type {RoomConnection} from "./RoomConnection"; import type {RoomConnection} from "./RoomConnection";
import type {BodyResourceDescriptionInterface} from "../Phaser/Entity/PlayerTextures"; import type {BodyResourceDescriptionInterface} from "../Phaser/Entity/PlayerTextures";
@ -47,6 +45,7 @@ export interface MessageUserPositionInterface {
name: string; name: string;
characterLayers: BodyResourceDescriptionInterface[]; characterLayers: BodyResourceDescriptionInterface[];
position: PointInterface; position: PointInterface;
visitCardUrl: string|null;
companion: string|null; companion: string|null;
} }
@ -60,6 +59,7 @@ export interface MessageUserJoined {
name: string; name: string;
characterLayers: BodyResourceDescriptionInterface[]; characterLayers: BodyResourceDescriptionInterface[];
position: PointInterface; position: PointInterface;
visitCardUrl: string | null;
companion: string|null; companion: string|null;
} }
@ -85,11 +85,6 @@ export interface WebRtcSignalReceivedMessageInterface {
webRtcPassword: string | undefined webRtcPassword: string | undefined
} }
export interface StartMapInterface {
mapUrlStart: string,
startInstance: string
}
export interface ViewportInterface { export interface ViewportInterface {
left: number, left: number,
top: number, top: number,

View File

@ -30,7 +30,7 @@ import {
EmoteEventMessage, EmoteEventMessage,
EmotePromptMessage, EmotePromptMessage,
SendUserMessage, SendUserMessage,
BanUserMessage, RequestVisitCardMessage BanUserMessage,
} from "../Messages/generated/messages_pb" } from "../Messages/generated/messages_pb"
import type {UserSimplePeerInterface} from "../WebRtc/SimplePeer"; import type {UserSimplePeerInterface} from "../WebRtc/SimplePeer";
@ -50,7 +50,6 @@ import {worldFullMessageStream} from "./WorldFullMessageStream";
import {worldFullWarningStream} from "./WorldFullWarningStream"; import {worldFullWarningStream} from "./WorldFullWarningStream";
import {connectionManager} from "./ConnectionManager"; import {connectionManager} from "./ConnectionManager";
import {emoteEventStream} from "./EmoteEventStream"; import {emoteEventStream} from "./EmoteEventStream";
import {requestVisitCardsStore} from "../Stores/GameStore";
const manualPingDelay = 20000; const manualPingDelay = 20000;
@ -204,8 +203,6 @@ export class RoomConnection implements RoomConnection {
adminMessagesService.onSendusermessage(message.getBanusermessage() as BanUserMessage); adminMessagesService.onSendusermessage(message.getBanusermessage() as BanUserMessage);
} else if (message.hasWorldfullwarningmessage()) { } else if (message.hasWorldfullwarningmessage()) {
worldFullWarningStream.onMessage(); worldFullWarningStream.onMessage();
} else if (message.hasVisitcardmessage()) {
requestVisitCardsStore.set(message?.getVisitcardmessage()?.getUrl() as unknown as string);
} else if (message.hasRefreshroommessage()) { } else if (message.hasRefreshroommessage()) {
//todo: implement a way to notify the user the room was refreshed. //todo: implement a way to notify the user the room was refreshed.
} else { } else {
@ -347,6 +344,7 @@ export class RoomConnection implements RoomConnection {
userId: message.getUserid(), userId: message.getUserid(),
name: message.getName(), name: message.getName(),
characterLayers, characterLayers,
visitCardUrl: message.getVisitcardurl(),
position: ProtobufClientUtils.toPointInterface(position), position: ProtobufClientUtils.toPointInterface(position),
companion: companion ? companion.getName() : null companion: companion ? companion.getName() : null
} }
@ -620,14 +618,4 @@ export class RoomConnection implements RoomConnection {
this.socket.send(clientToServerMessage.serializeBinary().buffer); this.socket.send(clientToServerMessage.serializeBinary().buffer);
} }
public requestVisitCardUrl(targetUserId: number): void {
const message = new RequestVisitCardMessage();
message.setTargetuserid(targetUserId);
const clientToServerMessage = new ClientToServerMessage();
clientToServerMessage.setRequestvisitcardmessage(message);
this.socket.send(clientToServerMessage.serializeBinary().buffer);
}
} }

View File

@ -41,6 +41,7 @@ export abstract class Character extends Container {
direction: PlayerAnimationDirections, direction: PlayerAnimationDirections,
moving: boolean, moving: boolean,
frame: string | number, frame: string | number,
isClickable: boolean,
companion: string|null, companion: string|null,
companionTexturePromise?: Promise<string> companionTexturePromise?: Promise<string>
) { ) {
@ -60,7 +61,7 @@ export abstract class Character extends Container {
this.playerName.setOrigin(0.5).setDepth(DEPTH_INGAME_TEXT_INDEX); this.playerName.setOrigin(0.5).setDepth(DEPTH_INGAME_TEXT_INDEX);
this.add(this.playerName); this.add(this.playerName);
if (this.isClickable()) { if (isClickable) {
this.setInteractive({ this.setInteractive({
hitArea: new Phaser.Geom.Circle(0, 0, interactiveRadius), hitArea: new Phaser.Geom.Circle(0, 0, interactiveRadius),
hitAreaCallback: Phaser.Geom.Circle.Contains, //eslint-disable-line @typescript-eslint/unbound-method hitAreaCallback: Phaser.Geom.Circle.Contains, //eslint-disable-line @typescript-eslint/unbound-method
@ -91,8 +92,6 @@ export abstract class Character extends Container {
} }
} }
public abstract isClickable(): boolean;
public addTextures(textures: string[], frame?: string | number): void { public addTextures(textures: string[], frame?: string | number): void {
for (const texture of textures) { for (const texture of textures) {
if(!this.scene.textures.exists(texture)){ if(!this.scene.textures.exists(texture)){
@ -261,7 +260,7 @@ export abstract class Character extends Container {
} }
private createStartTransition(scalingFactor: number, emoteY: number) { private createStartTransition(scalingFactor: number, emoteY: number) {
this.emoteTween = this.scene.tweens.add({ this.emoteTween = this.scene?.tweens.add({
targets: this.emote, targets: this.emote,
props: { props: {
scale: scalingFactor, scale: scalingFactor,
@ -277,7 +276,7 @@ export abstract class Character extends Container {
} }
private startPulseTransition(emoteY: number, scalingFactor: number) { private startPulseTransition(emoteY: number, scalingFactor: number) {
this.emoteTween = this.scene.tweens.add({ this.emoteTween = this.scene?.tweens.add({
targets: this.emote, targets: this.emote,
props: { props: {
y: emoteY * 1.3, y: emoteY * 1.3,
@ -294,7 +293,7 @@ export abstract class Character extends Container {
} }
private startExitTransition(emoteY: number) { private startExitTransition(emoteY: number) {
this.emoteTween = this.scene.tweens.add({ this.emoteTween = this.scene?.tweens.add({
targets: this.emote, targets: this.emote,
props: { props: {
alpha: 0, alpha: 0,

View File

@ -2,14 +2,15 @@ import type {GameScene} from "../Game/GameScene";
import type {PointInterface} from "../../Connexion/ConnexionModels"; import type {PointInterface} from "../../Connexion/ConnexionModels";
import {Character} from "../Entity/Character"; import {Character} from "../Entity/Character";
import type {PlayerAnimationDirections} from "../Player/Animation"; import type {PlayerAnimationDirections} from "../Player/Animation";
import {requestVisitCardsStore} from "../../Stores/GameStore";
export const playerClickedEvent = 'playerClickedEvent';
/** /**
* Class representing the sprite of a remote player (a player that plays on another computer) * Class representing the sprite of a remote player (a player that plays on another computer)
*/ */
export class RemotePlayer extends Character { export class RemotePlayer extends Character {
userId: number; userId: number;
private visitCardUrl: string|null;
constructor( constructor(
userId: number, userId: number,
@ -20,16 +21,18 @@ export class RemotePlayer extends Character {
texturesPromise: Promise<string[]>, texturesPromise: Promise<string[]>,
direction: PlayerAnimationDirections, direction: PlayerAnimationDirections,
moving: boolean, moving: boolean,
visitCardUrl: string|null,
companion: string|null, companion: string|null,
companionTexturePromise?: Promise<string> companionTexturePromise?: Promise<string>
) { ) {
super(Scene, x, y, texturesPromise, name, direction, moving, 1, companion, companionTexturePromise); super(Scene, x, y, texturesPromise, name, direction, moving, 1, !!visitCardUrl, companion, companionTexturePromise);
//set data //set data
this.userId = userId; this.userId = userId;
this.visitCardUrl = visitCardUrl;
this.on('pointerdown', () => { this.on('pointerdown', () => {
this.emit(playerClickedEvent, this.userId); requestVisitCardsStore.set(this.visitCardUrl);
}) })
} }
@ -44,8 +47,4 @@ export class RemotePlayer extends Character {
this.companion.setTarget(position.x, position.y, position.direction as PlayerAnimationDirections); this.companion.setTarget(position.x, position.y, position.direction as PlayerAnimationDirections);
} }
} }
isClickable(): boolean {
return true; //todo: make remote players clickable if they are logged in.
}
} }

View File

@ -6,5 +6,6 @@ export interface AddPlayerInterface {
name: string; name: string;
characterLayers: BodyResourceDescriptionInterface[]; characterLayers: BodyResourceDescriptionInterface[];
position: PointInterface; position: PointInterface;
visitCardUrl: string|null;
companion: string|null; companion: string|null;
} }

View File

@ -21,7 +21,6 @@ import type {
ITiledMapLayer, ITiledMapLayer,
ITiledMapLayerProperty, ITiledMapLayerProperty,
ITiledMapObject, ITiledMapObject,
ITiledText,
ITiledMapTileLayer, ITiledMapTileLayer,
ITiledTileSet ITiledTileSet
} from "../Map/ITiledMap"; } from "../Map/ITiledMap";
@ -29,7 +28,7 @@ import type {AddPlayerInterface} from "./AddPlayerInterface";
import {PlayerAnimationDirections} from "../Player/Animation"; import {PlayerAnimationDirections} from "../Player/Animation";
import {PlayerMovement} from "./PlayerMovement"; import {PlayerMovement} from "./PlayerMovement";
import {PlayersPositionInterpolator} from "./PlayersPositionInterpolator"; import {PlayersPositionInterpolator} from "./PlayersPositionInterpolator";
import {playerClickedEvent, RemotePlayer} from "../Entity/RemotePlayer"; 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";
@ -572,6 +571,7 @@ export class GameScene extends DirtyScene implements CenterListener {
characterLayers: message.characterLayers, characterLayers: message.characterLayers,
name: message.name, name: message.name,
position: message.position, position: message.position,
visitCardUrl: message.visitCardUrl,
companion: message.companion companion: message.companion
} }
this.addPlayer(userMessage); this.addPlayer(userMessage);
@ -1376,12 +1376,10 @@ ${escapedMessage}
texturesPromise, texturesPromise,
addPlayerData.position.direction as PlayerAnimationDirections, addPlayerData.position.direction as PlayerAnimationDirections,
addPlayerData.position.moving, addPlayerData.position.moving,
addPlayerData.visitCardUrl,
addPlayerData.companion, addPlayerData.companion,
addPlayerData.companion !== null ? lazyLoadCompanionResource(this.load, addPlayerData.companion) : undefined addPlayerData.companion !== null ? lazyLoadCompanionResource(this.load, addPlayerData.companion) : undefined
); );
player.on(playerClickedEvent, (userID:number) => {
this.connection?.requestVisitCardUrl(userID);
})
this.MapPlayers.add(player); this.MapPlayers.add(player);
this.MapPlayersByKey.set(player.userId, player); this.MapPlayersByKey.set(player.userId, player);
player.updatePosition(addPlayerData.position); player.updatePosition(addPlayerData.position);

View File

@ -32,6 +32,7 @@ export class SelectCharacterScene extends AbstractCharacterScene {
protected selectCharacterSceneElement!: Phaser.GameObjects.DOMElement; protected selectCharacterSceneElement!: Phaser.GameObjects.DOMElement;
protected currentSelectUser = 0; protected currentSelectUser = 0;
protected pointerClicked: boolean = false; protected pointerClicked: boolean = false;
protected pointerTimer: number = 0;
protected lazyloadingAttempt = true; //permit to update texture loaded after renderer protected lazyloadingAttempt = true; //permit to update texture loaded after renderer
@ -137,13 +138,19 @@ export class SelectCharacterScene extends AbstractCharacterScene {
repeat: -1 repeat: -1
}); });
player.setInteractive().on("pointerdown", () => { player.setInteractive().on("pointerdown", () => {
if (this.pointerClicked || this.currentSelectUser === i) { if (this.pointerClicked) {
return; return;
} }
if (this.currentSelectUser === i) {
return;
}
//To not trigger two time the pointerdown events :
// We set a boolean to true so that pointerdown events does nothing when the boolean is true
// We set a timer that we decrease in update function to not trigger the pointerdown events twice
this.pointerClicked = true; this.pointerClicked = true;
this.pointerTimer = 250;
this.currentSelectUser = i; this.currentSelectUser = i;
this.moveUser(); this.moveUser();
setTimeout(() => {this.pointerClicked = false;}, 100);
}); });
this.players.push(player); this.players.push(player);
} }
@ -243,6 +250,13 @@ export class SelectCharacterScene extends AbstractCharacterScene {
} }
update(time: number, delta: number): void { update(time: number, delta: number): void {
// pointerTimer is set to 250 when pointerdown events is trigger
// After 250ms, pointerClicked is set to false and the pointerdown events can be trigger again
this.pointerTimer -= delta;
if (this.pointerTimer <= 0) {
this.pointerClicked = false;
}
if(this.lazyloadingAttempt){ if(this.lazyloadingAttempt){
this.moveUser(); this.moveUser();
this.lazyloadingAttempt = false; this.lazyloadingAttempt = false;

View File

@ -23,6 +23,8 @@ export class SelectCompanionScene extends ResizableScene {
private saveZoom: number = 0; private saveZoom: number = 0;
private currentCompanion = 0; private currentCompanion = 0;
private pointerClicked: boolean = false;
private pointerTimer: number = 0;
constructor() { constructor() {
super({ super({
@ -72,7 +74,12 @@ export class SelectCompanionScene extends ResizableScene {
} }
update(time: number, delta: number): void { update(time: number, delta: number): void {
// pointerTimer is set to 250 when pointerdown events is trigger
// After 250ms, pointerClicked is set to false and the pointerdown events can be trigger again
this.pointerTimer -= delta;
if (this.pointerTimer <= 0) {
this.pointerClicked = false;
}
} }
public selectCompanion(): void { public selectCompanion(): void {
@ -105,6 +112,14 @@ export class SelectCompanionScene extends ResizableScene {
}); });
companion.setInteractive().on("pointerdown", () => { companion.setInteractive().on("pointerdown", () => {
if (this.pointerClicked) {
return;
}
//To not trigger two time the pointerdown events :
// We set a boolean to true so that pointerdown events does nothing when the boolean is true
// We set a timer that we decrease in update function to not trigger the pointerdown events twice
this.pointerClicked = true;
this.pointerTimer = 250;
this.currentCompanion = i; this.currentCompanion = i;
this.moveCompanion(); this.moveCompanion();
}); });

View File

@ -26,7 +26,7 @@ export class Player extends Character {
companion: string|null, companion: string|null,
companionTexturePromise?: Promise<string> companionTexturePromise?: Promise<string>
) { ) {
super(Scene, x, y, texturesPromise, name, direction, moving, 1, companion, companionTexturePromise); super(Scene, x, y, texturesPromise, name, direction, moving, 1, true, companion, companionTexturePromise);
//the current player model should be push away by other players to prevent conflict //the current player model should be push away by other players to prevent conflict
this.getBody().setImmovable(false); this.getBody().setImmovable(false);
@ -102,10 +102,6 @@ export class Player extends Character {
} }
} }
isClickable(): boolean {
return true;
}
openEmoteMenu(emotes:RadialMenuItem[]): void { openEmoteMenu(emotes:RadialMenuItem[]): void {
this.cancelPreviousEmote(); this.cancelPreviousEmote();
this.emoteMenu = new RadialMenu(this.scene, this.x, this.y, emotes) this.emoteMenu = new RadialMenu(this.scene, this.x, this.y, emotes)

View File

@ -367,6 +367,7 @@ body {
} }
#game { #game {
height: 100%;
width: 100%; width: 100%;
position: relative; /* Position relative is needed for the game-overlay. */ position: relative; /* Position relative is needed for the game-overlay. */
} }

View File

@ -1641,9 +1641,9 @@ dns-equal@^1.0.0:
integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0=
dns-packet@^1.3.1: dns-packet@^1.3.1:
version "1.3.1" version "1.3.4"
resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f"
integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg== integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==
dependencies: dependencies:
ip "^1.1.0" ip "^1.1.0"
safe-buffer "^5.0.1" safe-buffer "^5.0.1"

View File

@ -617,9 +617,9 @@ get-stdin@^4.0.1:
integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=
glob-parent@^5.0.0, glob-parent@~5.1.0: glob-parent@^5.0.0, glob-parent@~5.1.0:
version "5.1.1" version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
dependencies: dependencies:
is-glob "^4.0.1" is-glob "^4.0.1"

View File

@ -75,14 +75,6 @@ message EmoteEventMessage {
string emote = 2; string emote = 2;
} }
message RequestVisitCardMessage {
int32 targetUserId = 1;
}
message VisitCardMessage {
string url = 1;
}
message QueryJitsiJwtMessage { message QueryJitsiJwtMessage {
string jitsiRoom = 1; string jitsiRoom = 1;
string tag = 2; // FIXME: rather than reading the tag from the query, we should read it from the current map! string tag = 2; // FIXME: rather than reading the tag from the query, we should read it from the current map!
@ -102,7 +94,6 @@ message ClientToServerMessage {
ReportPlayerMessage reportPlayerMessage = 11; ReportPlayerMessage reportPlayerMessage = 11;
QueryJitsiJwtMessage queryJitsiJwtMessage = 12; QueryJitsiJwtMessage queryJitsiJwtMessage = 12;
EmotePromptMessage emotePromptMessage = 13; EmotePromptMessage emotePromptMessage = 13;
RequestVisitCardMessage requestVisitCardMessage = 14;
} }
} }
@ -166,6 +157,7 @@ message UserJoinedMessage {
repeated CharacterLayerMessage characterLayers = 3; repeated CharacterLayerMessage characterLayers = 3;
PositionMessage position = 4; PositionMessage position = 4;
CompanionMessage companion = 5; CompanionMessage companion = 5;
string visitCardUrl = 6;
} }
message UserLeftMessage { message UserLeftMessage {
@ -268,7 +260,6 @@ message ServerToClientMessage {
RefreshRoomMessage refreshRoomMessage = 17; RefreshRoomMessage refreshRoomMessage = 17;
WorldConnexionMessage worldConnexionMessage = 18; WorldConnexionMessage worldConnexionMessage = 18;
EmoteEventMessage emoteEventMessage = 19; EmoteEventMessage emoteEventMessage = 19;
VisitCardMessage visitCardMessage = 20;
} }
} }
@ -284,6 +275,7 @@ message JoinRoomMessage {
repeated string tag = 6; repeated string tag = 6;
string IPAddress = 7; string IPAddress = 7;
CompanionMessage companion = 8; CompanionMessage companion = 8;
string visitCardUrl = 9;
} }
message UserJoinedZoneMessage { message UserJoinedZoneMessage {
@ -293,6 +285,7 @@ message UserJoinedZoneMessage {
PositionMessage position = 4; PositionMessage position = 4;
Zone fromZone = 5; Zone fromZone = 5;
CompanionMessage companion = 6; CompanionMessage companion = 6;
string visitCardUrl = 7;
} }
message UserLeftZoneMessage { message UserLeftZoneMessage {
@ -340,7 +333,6 @@ message PusherToBackMessage {
SendUserMessage sendUserMessage = 12; SendUserMessage sendUserMessage = 12;
BanUserMessage banUserMessage = 13; BanUserMessage banUserMessage = 13;
EmotePromptMessage emotePromptMessage = 14; EmotePromptMessage emotePromptMessage = 14;
RequestVisitCardMessage requestVisitCardMessage = 15;
} }
} }

View File

@ -1823,9 +1823,9 @@ getpass@^0.1.1:
assert-plus "^1.0.0" assert-plus "^1.0.0"
glob-parent@^5.0.0, glob-parent@^5.1.0: glob-parent@^5.0.0, glob-parent@^5.1.0:
version "5.1.1" version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
dependencies: dependencies:
is-glob "^4.0.1" is-glob "^4.0.1"

View File

@ -1,5 +1,5 @@
import {CharacterLayer, ExSocketInterface} from "../Model/Websocket/ExSocketInterface"; //TODO fix import by "_Model/.." import {CharacterLayer, ExSocketInterface} from "../Model/Websocket/ExSocketInterface"; //TODO fix import by "_Model/.."
import {GameRoomPolicyTypes, PusherRoom} from "../Model/PusherRoom"; import {GameRoomPolicyTypes} from "../Model/PusherRoom";
import {PointInterface} from "../Model/Websocket/PointInterface"; import {PointInterface} from "../Model/Websocket/PointInterface";
import { import {
SetPlayerDetailsMessage, SetPlayerDetailsMessage,
@ -12,13 +12,11 @@ import {
WebRtcSignalToServerMessage, WebRtcSignalToServerMessage,
PlayGlobalMessage, PlayGlobalMessage,
ReportPlayerMessage, ReportPlayerMessage,
EmoteEventMessage,
QueryJitsiJwtMessage, QueryJitsiJwtMessage,
SendUserMessage, SendUserMessage,
ServerToClientMessage, ServerToClientMessage,
CompanionMessage, CompanionMessage,
EmotePromptMessage, EmotePromptMessage,
RequestVisitCardMessage
} from "../Messages/generated/messages_pb"; } from "../Messages/generated/messages_pb";
import {UserMovesMessage} from "../Messages/generated/messages_pb"; import {UserMovesMessage} from "../Messages/generated/messages_pb";
import {TemplatedApp} from "uWebSockets.js" import {TemplatedApp} from "uWebSockets.js"
@ -26,7 +24,7 @@ import {parse} from "query-string";
import {jwtTokenManager} from "../Services/JWTTokenManager"; import {jwtTokenManager} from "../Services/JWTTokenManager";
import {adminApi, CharacterTexture, FetchMemberDataByUuidResponse} from "../Services/AdminApi"; import {adminApi, CharacterTexture, FetchMemberDataByUuidResponse} from "../Services/AdminApi";
import {SocketManager, socketManager} from "../Services/SocketManager"; import {SocketManager, socketManager} from "../Services/SocketManager";
import {emitError, emitInBatch} from "../Services/IoSocketHelpers"; import {emitInBatch} from "../Services/IoSocketHelpers";
import {ADMIN_API_TOKEN, ADMIN_API_URL, SOCKET_IDLE_TIMER} from "../Enum/EnvironmentVariable"; import {ADMIN_API_TOKEN, ADMIN_API_URL, SOCKET_IDLE_TIMER} from "../Enum/EnvironmentVariable";
import {Zone} from "_Model/Zone"; import {Zone} from "_Model/Zone";
import {ExAdminSocketInterface} from "_Model/Websocket/ExAdminSocketInterface"; import {ExAdminSocketInterface} from "_Model/Websocket/ExAdminSocketInterface";
@ -169,6 +167,7 @@ export class IoSocketController {
const userUuid = await jwtTokenManager.getUserUuidFromToken(token, IPAddress, roomId); const userUuid = await jwtTokenManager.getUserUuidFromToken(token, IPAddress, roomId);
let memberTags: string[] = []; let memberTags: string[] = [];
let memberVisitCardUrl: string|null = null;
let memberMessages: unknown; let memberMessages: unknown;
let memberTextures: CharacterTexture[] = []; let memberTextures: CharacterTexture[] = [];
const room = await socketManager.getOrCreateRoom(roomId); const room = await socketManager.getOrCreateRoom(roomId);
@ -177,6 +176,7 @@ export class IoSocketController {
let userData : FetchMemberDataByUuidResponse = { let userData : FetchMemberDataByUuidResponse = {
uuid: v4(), uuid: v4(),
tags: [], tags: [],
visitCardUrl: null,
textures: [], textures: [],
messages: [], messages: [],
anonymous: true anonymous: true
@ -204,6 +204,7 @@ export class IoSocketController {
} }
memberMessages = userData.messages; memberMessages = userData.messages;
memberTags = userData.tags; memberTags = userData.tags;
memberVisitCardUrl = userData.visitCardUrl;
memberTextures = userData.textures; memberTextures = userData.textures;
if (!room.public && room.policyType === GameRoomPolicyTypes.USE_TAGS_POLICY && (userData.anonymous === true || !room.canAccess(memberTags))) { if (!room.public && room.policyType === GameRoomPolicyTypes.USE_TAGS_POLICY && (userData.anonymous === true || !room.canAccess(memberTags))) {
throw new Error('Insufficient privileges to access this room') throw new Error('Insufficient privileges to access this room')
@ -240,6 +241,7 @@ export class IoSocketController {
characterLayers: characterLayerObjs, characterLayers: characterLayerObjs,
messages: memberMessages, messages: memberMessages,
tags: memberTags, tags: memberTags,
visitCardUrl: memberVisitCardUrl,
textures: memberTextures, textures: memberTextures,
position: { position: {
x: x, x: x,
@ -338,9 +340,6 @@ export class IoSocketController {
socketManager.handleQueryJitsiJwtMessage(client, message.getQueryjitsijwtmessage() as QueryJitsiJwtMessage); socketManager.handleQueryJitsiJwtMessage(client, message.getQueryjitsijwtmessage() as QueryJitsiJwtMessage);
} else if (message.hasEmotepromptmessage()){ } else if (message.hasEmotepromptmessage()){
socketManager.handleEmotePromptMessage(client, message.getEmotepromptmessage() as EmotePromptMessage); socketManager.handleEmotePromptMessage(client, message.getEmotepromptmessage() as EmotePromptMessage);
} else if (message.hasRequestvisitcardmessage()) {
socketManager.handleRequestVisitCardMessage(client, message.getRequestvisitcardmessage() as RequestVisitCardMessage);
} }
/* Ok is false if backpressure was built up, wait for drain */ /* Ok is false if backpressure was built up, wait for drain */
@ -381,6 +380,7 @@ export class IoSocketController {
client.messages = ws.messages; client.messages = ws.messages;
client.name = ws.name; client.name = ws.name;
client.tags = ws.tags; client.tags = ws.tags;
client.visitCardUrl = ws.visitCardUrl;
client.textures = ws.textures; client.textures = ws.textures;
client.characterLayers = ws.characterLayers; client.characterLayers = ws.characterLayers;
client.companion = ws.companion; client.companion = ws.companion;

View File

@ -40,6 +40,7 @@ export interface ExSocketInterface extends WebSocket, Identificable {
disconnecting: boolean, disconnecting: boolean,
messages: unknown, messages: unknown,
tags: string[], tags: string[],
visitCardUrl: string|null,
textures: CharacterTexture[], textures: CharacterTexture[],
backConnection: BackConnection, backConnection: BackConnection,
listenedZones: Set<Zone>; listenedZones: Set<Zone>;

View File

@ -30,7 +30,7 @@ export type MovesCallback = (thing: Movable, position: PositionInterface, listen
export type LeavesCallback = (thing: Movable, listener: User) => void;*/ export type LeavesCallback = (thing: Movable, listener: User) => void;*/
export class UserDescriptor { export class UserDescriptor {
private constructor(public readonly userId: number, private name: string, private characterLayers: CharacterLayerMessage[], private position: PositionMessage, private companion?: CompanionMessage) { private constructor(public readonly userId: number, private name: string, private characterLayers: CharacterLayerMessage[], private position: PositionMessage, private visitCardUrl: string | null, private companion?: CompanionMessage) {
if (!Number.isInteger(this.userId)) { if (!Number.isInteger(this.userId)) {
throw new Error('UserDescriptor.userId is not an integer: '+this.userId); throw new Error('UserDescriptor.userId is not an integer: '+this.userId);
} }
@ -41,7 +41,7 @@ export class UserDescriptor {
if (position === undefined) { if (position === undefined) {
throw new Error('Missing position'); throw new Error('Missing position');
} }
return new UserDescriptor(message.getUserid(), message.getName(), message.getCharacterlayersList(), position, message.getCompanion()); return new UserDescriptor(message.getUserid(), message.getName(), message.getCharacterlayersList(), position, message.getVisitcardurl(), message.getCompanion());
} }
public update(userMovedMessage: UserMovedMessage) { public update(userMovedMessage: UserMovedMessage) {
@ -59,7 +59,10 @@ export class UserDescriptor {
userJoinedMessage.setName(this.name); userJoinedMessage.setName(this.name);
userJoinedMessage.setCharacterlayersList(this.characterLayers); userJoinedMessage.setCharacterlayersList(this.characterLayers);
userJoinedMessage.setPosition(this.position); userJoinedMessage.setPosition(this.position);
userJoinedMessage.setCompanion(this.companion) if (this.visitCardUrl) {
userJoinedMessage.setVisitcardurl(this.visitCardUrl);
}
userJoinedMessage.setCompanion(this.companion);
return userJoinedMessage; return userJoinedMessage;
} }

View File

@ -36,6 +36,7 @@ export interface CharacterTexture {
export interface FetchMemberDataByUuidResponse { export interface FetchMemberDataByUuidResponse {
uuid: string; uuid: string;
tags: string[]; tags: string[];
visitCardUrl: string|null;
textures: CharacterTexture[]; textures: CharacterTexture[];
messages: unknown[]; messages: unknown[];
anonymous?: boolean; anonymous?: boolean;

View File

@ -30,7 +30,6 @@ import {
BanMessage, BanMessage,
RefreshRoomMessage, RefreshRoomMessage,
EmotePromptMessage, EmotePromptMessage,
RequestVisitCardMessage
} from "../Messages/generated/messages_pb"; } from "../Messages/generated/messages_pb";
import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils"; import {ProtobufUtils} from "../Model/Websocket/ProtobufUtils";
import {JITSI_ISS, SECRET_JITSI_KEY} from "../Enum/EnvironmentVariable"; import {JITSI_ISS, SECRET_JITSI_KEY} from "../Enum/EnvironmentVariable";
@ -162,6 +161,9 @@ export class SocketManager implements ZoneEventListener {
joinRoomMessage.setName(client.name); joinRoomMessage.setName(client.name);
joinRoomMessage.setPositionmessage(ProtobufUtils.toPositionMessage(client.position)); joinRoomMessage.setPositionmessage(ProtobufUtils.toPositionMessage(client.position));
joinRoomMessage.setTagList(client.tags); joinRoomMessage.setTagList(client.tags);
if (client.visitCardUrl) {
joinRoomMessage.setVisitcardurl(client.visitCardUrl);
}
joinRoomMessage.setCompanion(client.companion); joinRoomMessage.setCompanion(client.companion);
for (const characterLayer of client.characterLayers) { for (const characterLayer of client.characterLayers) {
@ -604,13 +606,6 @@ export class SocketManager implements ZoneEventListener {
client.backConnection.write(pusherToBackMessage); client.backConnection.write(pusherToBackMessage);
} }
handleRequestVisitCardMessage(client: ExSocketInterface, requestVisitCardMessage: RequestVisitCardMessage) {
const pusherToBackMessage = new PusherToBackMessage();
pusherToBackMessage.setRequestvisitcardmessage(requestVisitCardMessage);
client.backConnection.write(pusherToBackMessage);
}
} }
export const socketManager = new SocketManager(); export const socketManager = new SocketManager();

View File

@ -763,9 +763,9 @@ get-stdin@^4.0.1:
integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=
glob-parent@^5.0.0, glob-parent@~5.1.0: glob-parent@^5.0.0, glob-parent@~5.1.0:
version "5.1.1" version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
dependencies: dependencies:
is-glob "^4.0.1" is-glob "^4.0.1"