Sharing outline color changes in real time
This commit is contained in:
parent
90f7287860
commit
482ba9690a
@ -2,7 +2,13 @@ import { PointInterface } from "./Websocket/PointInterface";
|
||||
import { Group } from "./Group";
|
||||
import { User, UserSocket } from "./User";
|
||||
import { PositionInterface } from "_Model/PositionInterface";
|
||||
import { EmoteCallback, EntersCallback, LeavesCallback, MovesCallback } from "_Model/Zone";
|
||||
import {
|
||||
EmoteCallback,
|
||||
EntersCallback,
|
||||
LeavesCallback,
|
||||
MovesCallback,
|
||||
PlayerDetailsUpdatedCallback,
|
||||
} from "_Model/Zone";
|
||||
import { PositionNotifier } from "./PositionNotifier";
|
||||
import { Movable } from "_Model/Movable";
|
||||
import {
|
||||
@ -11,6 +17,7 @@ import {
|
||||
EmoteEventMessage,
|
||||
ErrorMessage,
|
||||
JoinRoomMessage,
|
||||
SetPlayerDetailsMessage,
|
||||
SubToPusherRoomMessage,
|
||||
VariableMessage,
|
||||
VariableWithTagMessage,
|
||||
@ -56,10 +63,19 @@ export class GameRoom {
|
||||
onEnters: EntersCallback,
|
||||
onMoves: MovesCallback,
|
||||
onLeaves: LeavesCallback,
|
||||
onEmote: EmoteCallback
|
||||
onEmote: EmoteCallback,
|
||||
onPlayerDetailsUpdated: PlayerDetailsUpdatedCallback
|
||||
) {
|
||||
// A zone is 10 sprites wide.
|
||||
this.positionNotifier = new PositionNotifier(320, 320, onEnters, onMoves, onLeaves, onEmote);
|
||||
this.positionNotifier = new PositionNotifier(
|
||||
320,
|
||||
320,
|
||||
onEnters,
|
||||
onMoves,
|
||||
onLeaves,
|
||||
onEmote,
|
||||
onPlayerDetailsUpdated
|
||||
);
|
||||
}
|
||||
|
||||
public static async create(
|
||||
@ -71,7 +87,8 @@ export class GameRoom {
|
||||
onEnters: EntersCallback,
|
||||
onMoves: MovesCallback,
|
||||
onLeaves: LeavesCallback,
|
||||
onEmote: EmoteCallback
|
||||
onEmote: EmoteCallback,
|
||||
onPlayerDetailsUpdated: PlayerDetailsUpdatedCallback
|
||||
): Promise<GameRoom> {
|
||||
const mapDetails = await GameRoom.getMapDetails(roomUrl);
|
||||
|
||||
@ -85,7 +102,8 @@ export class GameRoom {
|
||||
onEnters,
|
||||
onMoves,
|
||||
onLeaves,
|
||||
onEmote
|
||||
onEmote,
|
||||
onPlayerDetailsUpdated
|
||||
);
|
||||
|
||||
return gameRoom;
|
||||
@ -180,6 +198,14 @@ export class GameRoom {
|
||||
this.updateUserGroup(user);
|
||||
}
|
||||
|
||||
updatePlayerDetails(user: User, playerDetailsMessage: SetPlayerDetailsMessage) {
|
||||
if (playerDetailsMessage.getRemoveoutlinecolor()) {
|
||||
user.outlineColor = undefined;
|
||||
} else {
|
||||
user.outlineColor = playerDetailsMessage.getOutlinecolor();
|
||||
}
|
||||
}
|
||||
|
||||
private updateUserGroup(user: User): void {
|
||||
user.group?.updatePosition();
|
||||
user.group?.searchForNearbyUsers();
|
||||
|
@ -8,12 +8,19 @@
|
||||
* The PositionNotifier is important for performance. It allows us to send the position of players only to a restricted
|
||||
* number of players around the current player.
|
||||
*/
|
||||
import { EmoteCallback, EntersCallback, LeavesCallback, MovesCallback, Zone } from "./Zone";
|
||||
import {
|
||||
EmoteCallback,
|
||||
EntersCallback,
|
||||
LeavesCallback,
|
||||
MovesCallback,
|
||||
PlayerDetailsUpdatedCallback,
|
||||
Zone,
|
||||
} from "./Zone";
|
||||
import { Movable } from "_Model/Movable";
|
||||
import { PositionInterface } from "_Model/PositionInterface";
|
||||
import { ZoneSocket } from "../RoomManager";
|
||||
import { User } from "../Model/User";
|
||||
import { EmoteEventMessage } from "../Messages/generated/messages_pb";
|
||||
import { EmoteEventMessage, SetPlayerDetailsMessage } from "../Messages/generated/messages_pb";
|
||||
|
||||
interface ZoneDescriptor {
|
||||
i: number;
|
||||
@ -42,7 +49,8 @@ export class PositionNotifier {
|
||||
private onUserEnters: EntersCallback,
|
||||
private onUserMoves: MovesCallback,
|
||||
private onUserLeaves: LeavesCallback,
|
||||
private onEmote: EmoteCallback
|
||||
private onEmote: EmoteCallback,
|
||||
private onPlayerDetailsUpdated: PlayerDetailsUpdatedCallback
|
||||
) {}
|
||||
|
||||
private getZoneDescriptorFromCoordinates(x: number, y: number): ZoneDescriptor {
|
||||
@ -98,7 +106,15 @@ export class PositionNotifier {
|
||||
|
||||
let zone = this.zones[j][i];
|
||||
if (zone === undefined) {
|
||||
zone = new Zone(this.onUserEnters, this.onUserMoves, this.onUserLeaves, this.onEmote, i, j);
|
||||
zone = new Zone(
|
||||
this.onUserEnters,
|
||||
this.onUserMoves,
|
||||
this.onUserLeaves,
|
||||
this.onEmote,
|
||||
this.onPlayerDetailsUpdated,
|
||||
i,
|
||||
j
|
||||
);
|
||||
this.zones[j][i] = zone;
|
||||
}
|
||||
return zone;
|
||||
@ -132,4 +148,11 @@ export class PositionNotifier {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public updatePlayerDetails(user: User, playerDetails: SetPlayerDetailsMessage) {
|
||||
const position = user.getPosition();
|
||||
const zoneDesc = this.getZoneDescriptorFromCoordinates(position.x, position.y);
|
||||
const zone = this.getZone(zoneDesc.i, zoneDesc.j);
|
||||
zone.updatePlayerDetails(user, playerDetails);
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
CompanionMessage,
|
||||
PusherToBackMessage,
|
||||
ServerToClientMessage,
|
||||
SetPlayerDetailsMessage,
|
||||
SubMessage,
|
||||
} from "../Messages/generated/messages_pb";
|
||||
import { CharacterLayer } from "_Model/Websocket/CharacterLayer";
|
||||
@ -31,7 +32,8 @@ export class User implements Movable {
|
||||
public readonly visitCardUrl: string | null,
|
||||
public readonly name: string,
|
||||
public readonly characterLayers: CharacterLayer[],
|
||||
public readonly companion?: CompanionMessage
|
||||
public readonly companion?: CompanionMessage,
|
||||
private _outlineColor?: number | undefined
|
||||
) {
|
||||
this.listenedZones = new Set<Zone>();
|
||||
|
||||
@ -69,4 +71,17 @@ export class User implements Movable {
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
public set outlineColor(value: number | undefined) {
|
||||
this._outlineColor = value;
|
||||
|
||||
const playerDetails = new SetPlayerDetailsMessage();
|
||||
if (value === undefined) {
|
||||
playerDetails.setRemoveoutlinecolor(true);
|
||||
} else {
|
||||
playerDetails.setOutlinecolor(value);
|
||||
}
|
||||
|
||||
this.positionNotifier.updatePlayerDetails(this, playerDetails);
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,20 @@ import { PositionInterface } from "_Model/PositionInterface";
|
||||
import { Movable } from "./Movable";
|
||||
import { Group } from "./Group";
|
||||
import { ZoneSocket } from "../RoomManager";
|
||||
import { EmoteEventMessage } from "../Messages/generated/messages_pb";
|
||||
import {
|
||||
EmoteEventMessage,
|
||||
SetPlayerDetailsMessage,
|
||||
PlayerDetailsUpdatedMessage,
|
||||
} from "../Messages/generated/messages_pb";
|
||||
|
||||
export type EntersCallback = (thing: Movable, fromZone: Zone | null, listener: ZoneSocket) => void;
|
||||
export type MovesCallback = (thing: Movable, position: PositionInterface, listener: ZoneSocket) => void;
|
||||
export type LeavesCallback = (thing: Movable, newZone: Zone | null, listener: ZoneSocket) => void;
|
||||
export type EmoteCallback = (emoteEventMessage: EmoteEventMessage, listener: ZoneSocket) => void;
|
||||
export type PlayerDetailsUpdatedCallback = (
|
||||
playerDetailsUpdatedMessage: PlayerDetailsUpdatedMessage,
|
||||
listener: ZoneSocket
|
||||
) => void;
|
||||
|
||||
export class Zone {
|
||||
private things: Set<Movable> = new Set<Movable>();
|
||||
@ -19,6 +27,7 @@ export class Zone {
|
||||
private onMoves: MovesCallback,
|
||||
private onLeaves: LeavesCallback,
|
||||
private onEmote: EmoteCallback,
|
||||
private onPlayerDetailsUpdated: PlayerDetailsUpdatedCallback,
|
||||
public readonly x: number,
|
||||
public readonly y: number
|
||||
) {}
|
||||
@ -106,4 +115,14 @@ export class Zone {
|
||||
this.onEmote(emoteEventMessage, listener);
|
||||
}
|
||||
}
|
||||
|
||||
public updatePlayerDetails(user: User, playerDetails: SetPlayerDetailsMessage) {
|
||||
const playerDetailsUpdatedMessage = new PlayerDetailsUpdatedMessage();
|
||||
playerDetailsUpdatedMessage.setUserid(user.id);
|
||||
playerDetailsUpdatedMessage.setDetails(playerDetails);
|
||||
|
||||
for (const listener of this.listeners) {
|
||||
this.onPlayerDetailsUpdated(playerDetailsUpdatedMessage, listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
AdminPusherToBackMessage,
|
||||
AdminRoomMessage,
|
||||
BanMessage,
|
||||
BanUserMessage,
|
||||
BatchToPusherMessage,
|
||||
BatchToPusherRoomMessage,
|
||||
EmotePromptMessage,
|
||||
@ -16,7 +17,9 @@ import {
|
||||
QueryJitsiJwtMessage,
|
||||
RefreshRoomPromptMessage,
|
||||
RoomMessage,
|
||||
SendUserMessage,
|
||||
ServerToAdminClientMessage,
|
||||
SetPlayerDetailsMessage,
|
||||
SilentMessage,
|
||||
UserMovesMessage,
|
||||
VariableMessage,
|
||||
@ -118,14 +121,17 @@ const roomManager: IRoomManagerServer = {
|
||||
);
|
||||
} else if (message.hasSendusermessage()) {
|
||||
const sendUserMessage = message.getSendusermessage();
|
||||
if (sendUserMessage !== undefined) {
|
||||
socketManager.handlerSendUserMessage(user, sendUserMessage);
|
||||
}
|
||||
socketManager.handleSendUserMessage(user, sendUserMessage as SendUserMessage);
|
||||
} else if (message.hasBanusermessage()) {
|
||||
const banUserMessage = message.getBanusermessage();
|
||||
if (banUserMessage !== undefined) {
|
||||
socketManager.handlerBanUserMessage(room, user, banUserMessage);
|
||||
}
|
||||
socketManager.handlerBanUserMessage(room, user, banUserMessage as BanUserMessage);
|
||||
} else if (message.hasSetplayerdetailsmessage()) {
|
||||
const setPlayerDetailsMessage = message.getSetplayerdetailsmessage();
|
||||
socketManager.handleSetPlayerDetails(
|
||||
room,
|
||||
user,
|
||||
setPlayerDetailsMessage as SetPlayerDetailsMessage
|
||||
);
|
||||
} else {
|
||||
throw new Error("Unhandled message type");
|
||||
}
|
||||
|
@ -33,6 +33,8 @@ import {
|
||||
VariableMessage,
|
||||
BatchToPusherRoomMessage,
|
||||
SubToPusherRoomMessage,
|
||||
SetPlayerDetailsMessage,
|
||||
PlayerDetailsUpdatedMessage,
|
||||
} from "../Messages/generated/messages_pb";
|
||||
import { User, UserSocket } from "../Model/User";
|
||||
import { ProtobufUtils } from "../Model/Websocket/ProtobufUtils";
|
||||
@ -151,20 +153,9 @@ export class SocketManager {
|
||||
//room.setViewport(client, client.viewport);
|
||||
}
|
||||
|
||||
// Useless now, will be useful again if we allow editing details in game
|
||||
/*handleSetPlayerDetails(client: UserSocket, playerDetailsMessage: SetPlayerDetailsMessage) {
|
||||
const playerDetails = {
|
||||
name: playerDetailsMessage.getName(),
|
||||
characterLayers: playerDetailsMessage.getCharacterlayersList()
|
||||
};
|
||||
//console.log(SocketIoEvent.SET_PLAYER_DETAILS, playerDetails);
|
||||
if (!isSetPlayerDetailsMessage(playerDetails)) {
|
||||
emitError(client, 'Invalid SET_PLAYER_DETAILS message received: ');
|
||||
return;
|
||||
handleSetPlayerDetails(room: GameRoom, user: User, playerDetailsMessage: SetPlayerDetailsMessage) {
|
||||
room.updatePlayerDetails(user, playerDetailsMessage);
|
||||
}
|
||||
client.name = playerDetails.name;
|
||||
client.characterLayers = SocketManager.mergeCharacterLayersAndCustomTextures(playerDetails.characterLayers, client.textures);
|
||||
}*/
|
||||
|
||||
handleSilentMessage(room: GameRoom, user: User, silentMessage: SilentMessage) {
|
||||
room.setSilent(user, silentMessage.getSilent());
|
||||
@ -282,7 +273,9 @@ export class SocketManager {
|
||||
(thing: Movable, newZone: Zone | null, listener: ZoneSocket) =>
|
||||
this.onClientLeave(thing, newZone, listener),
|
||||
(emoteEventMessage: EmoteEventMessage, listener: ZoneSocket) =>
|
||||
this.onEmote(emoteEventMessage, listener)
|
||||
this.onEmote(emoteEventMessage, listener),
|
||||
(playerDetailsUpdatedMessage: PlayerDetailsUpdatedMessage, listener: ZoneSocket) =>
|
||||
this.onPlayerDetailsUpdated(playerDetailsUpdatedMessage, listener)
|
||||
)
|
||||
.then((gameRoom) => {
|
||||
gaugeManager.incNbRoomGauge();
|
||||
@ -378,6 +371,13 @@ export class SocketManager {
|
||||
emitZoneMessage(subMessage, client);
|
||||
}
|
||||
|
||||
private onPlayerDetailsUpdated(playerDetailsUpdatedMessage: PlayerDetailsUpdatedMessage, client: ZoneSocket) {
|
||||
const subMessage = new SubToPusherMessage();
|
||||
subMessage.setPlayerdetailsupdatedmessage(playerDetailsUpdatedMessage);
|
||||
|
||||
emitZoneMessage(subMessage, client);
|
||||
}
|
||||
|
||||
private emitCreateUpdateGroupEvent(client: ZoneSocket, fromZone: Zone | null, group: Group): void {
|
||||
const position = group.getPosition();
|
||||
const pointMessage = new PointMessage();
|
||||
@ -572,7 +572,7 @@ export class SocketManager {
|
||||
user.socket.write(serverToClientMessage);
|
||||
}
|
||||
|
||||
public handlerSendUserMessage(user: User, sendUserMessageToSend: SendUserMessage) {
|
||||
public handleSendUserMessage(user: User, sendUserMessageToSend: SendUserMessage) {
|
||||
const sendUserMessage = new SendUserMessage();
|
||||
sendUserMessage.setMessage(sendUserMessageToSend.getMessage());
|
||||
sendUserMessage.setType(sendUserMessageToSend.getType());
|
||||
|
@ -18,6 +18,7 @@ export enum EventMessage {
|
||||
GROUP_DELETE = "group-delete",
|
||||
SET_PLAYER_DETAILS = "set-player-details", // Send the name and character to the server (on connect), receive back the id.
|
||||
ITEM_EVENT = "item-event",
|
||||
USER_DETAILS_UPDATED = "user-details-updated",
|
||||
|
||||
CONNECT_ERROR = "connect_error",
|
||||
CONNECTING_ERROR = "connecting_error",
|
||||
@ -102,6 +103,12 @@ export interface ItemEventMessageInterface {
|
||||
parameters: unknown;
|
||||
}
|
||||
|
||||
export interface PlayerDetailsUpdatedMessageInterface {
|
||||
userId: number;
|
||||
outlineColor: number;
|
||||
removeOutlineColor: boolean;
|
||||
}
|
||||
|
||||
export interface RoomJoinedMessageInterface {
|
||||
//users: MessageUserPositionInterface[],
|
||||
//groups: GroupCreatedUpdatedMessageInterface[],
|
||||
|
@ -34,6 +34,7 @@ import {
|
||||
BanUserMessage,
|
||||
VariableMessage,
|
||||
ErrorMessage,
|
||||
PlayerDetailsUpdatedMessage,
|
||||
} from "../Messages/generated/messages_pb";
|
||||
|
||||
import type { UserSimplePeerInterface } from "../WebRtc/SimplePeer";
|
||||
@ -45,6 +46,7 @@ import {
|
||||
ItemEventMessageInterface,
|
||||
MessageUserJoined,
|
||||
OnConnectInterface,
|
||||
PlayerDetailsUpdatedMessageInterface,
|
||||
PlayGlobalMessageInterface,
|
||||
PositionInterface,
|
||||
RoomJoinedMessageInterface,
|
||||
@ -172,6 +174,9 @@ export class RoomConnection implements RoomConnection {
|
||||
} else if (subMessage.hasEmoteeventmessage()) {
|
||||
const emoteMessage = subMessage.getEmoteeventmessage() as EmoteEventMessage;
|
||||
emoteEventStream.fire(emoteMessage.getActoruserid(), emoteMessage.getEmote());
|
||||
} else if (subMessage.hasPlayerdetailsupdatedmessage()) {
|
||||
event = EventMessage.USER_DETAILS_UPDATED;
|
||||
payload = subMessage.getPlayerdetailsupdatedmessage();
|
||||
} else if (subMessage.hasErrormessage()) {
|
||||
const errorMessage = subMessage.getErrormessage() as ErrorMessage;
|
||||
console.error("An error occurred server side: " + errorMessage.getMessage());
|
||||
@ -276,7 +281,7 @@ export class RoomConnection implements RoomConnection {
|
||||
}
|
||||
}
|
||||
|
||||
public emitPlayerDetailsMessage(userName: string, characterLayersSelected: BodyResourceDescriptionInterface[]) {
|
||||
/*public emitPlayerDetailsMessage(userName: string, characterLayersSelected: BodyResourceDescriptionInterface[]) {
|
||||
const message = new SetPlayerDetailsMessage();
|
||||
message.setName(userName);
|
||||
message.setCharacterlayersList(characterLayersSelected.map((characterLayer) => characterLayer.name));
|
||||
@ -284,6 +289,20 @@ export class RoomConnection implements RoomConnection {
|
||||
const clientToServerMessage = new ClientToServerMessage();
|
||||
clientToServerMessage.setSetplayerdetailsmessage(message);
|
||||
|
||||
this.socket.send(clientToServerMessage.serializeBinary().buffer);
|
||||
}*/
|
||||
|
||||
public emitPlayerOutlineColor(color: number | null) {
|
||||
const message = new SetPlayerDetailsMessage();
|
||||
if (color === null) {
|
||||
message.setRemoveoutlinecolor(true);
|
||||
} else {
|
||||
message.setOutlinecolor(color);
|
||||
}
|
||||
|
||||
const clientToServerMessage = new ClientToServerMessage();
|
||||
clientToServerMessage.setSetplayerdetailsmessage(message);
|
||||
|
||||
this.socket.send(clientToServerMessage.serializeBinary().buffer);
|
||||
}
|
||||
|
||||
@ -596,6 +615,20 @@ export class RoomConnection implements RoomConnection {
|
||||
});
|
||||
}
|
||||
|
||||
onPlayerDetailsUpdated(callback: (message: PlayerDetailsUpdatedMessageInterface) => void): void {
|
||||
this.onMessage(EventMessage.USER_DETAILS_UPDATED, (message: PlayerDetailsUpdatedMessage) => {
|
||||
const details = message.getDetails();
|
||||
if (details === undefined) {
|
||||
throw new Error("Malformed message. Missing details in PlayerDetailsUpdatedMessage");
|
||||
}
|
||||
callback({
|
||||
userId: message.getUserid(),
|
||||
outlineColor: details.getOutlinecolor(),
|
||||
removeOutlineColor: details.getRemoveoutlinecolor(),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public uploadAudio(file: FormData) {
|
||||
return Axios.post(`${UPLOADER_URL}/upload-audio-message`, file)
|
||||
.then((res: { data: {} }) => {
|
||||
|
@ -414,8 +414,8 @@ export abstract class Character extends Container {
|
||||
return this._pictureStore;
|
||||
}
|
||||
|
||||
public setOutlineColor(red: number, green: number, blue: number): void {
|
||||
this.outlineColorStore.setColor((red << 16) | (green << 8) | blue);
|
||||
public setOutlineColor(color: number): void {
|
||||
this.outlineColorStore.setColor(color);
|
||||
}
|
||||
|
||||
public removeOutlineColor(): void {
|
||||
|
@ -55,6 +55,7 @@ import type {
|
||||
MessageUserMovedInterface,
|
||||
MessageUserPositionInterface,
|
||||
OnConnectInterface,
|
||||
PlayerDetailsUpdatedMessageInterface,
|
||||
PointInterface,
|
||||
PositionInterface,
|
||||
RoomJoinedMessageInterface,
|
||||
@ -88,6 +89,7 @@ import Tileset = Phaser.Tilemaps.Tileset;
|
||||
import SpriteSheetFile = Phaser.Loader.FileTypes.SpriteSheetFile;
|
||||
import FILE_LOAD_ERROR = Phaser.Loader.Events.FILE_LOAD_ERROR;
|
||||
import { MapStore } from "../../Stores/Utils/MapStore";
|
||||
import { SetPlayerDetailsMessage } from "../../Messages/generated/messages_pb";
|
||||
export interface GameSceneInitInterface {
|
||||
initPosition: PointInterface | null;
|
||||
reconnecting: boolean;
|
||||
@ -123,6 +125,11 @@ interface DeleteGroupEventInterface {
|
||||
groupId: number;
|
||||
}
|
||||
|
||||
interface PlayerDetailsUpdatedInterface {
|
||||
type: "PlayerDetailsUpdated";
|
||||
details: PlayerDetailsUpdatedMessageInterface;
|
||||
}
|
||||
|
||||
export class GameScene extends DirtyScene {
|
||||
Terrains: Array<Phaser.Tilemaps.Tileset>;
|
||||
CurrentPlayer!: Player;
|
||||
@ -135,20 +142,14 @@ export class GameScene extends DirtyScene {
|
||||
groups: Map<number, Sprite>;
|
||||
circleTexture!: CanvasTexture;
|
||||
circleRedTexture!: CanvasTexture;
|
||||
pendingEvents: Queue<
|
||||
| InitUserPositionEventInterface
|
||||
| AddPlayerEventInterface
|
||||
| RemovePlayerEventInterface
|
||||
| UserMovedEventInterface
|
||||
| GroupCreatedUpdatedEventInterface
|
||||
| DeleteGroupEventInterface
|
||||
> = new Queue<
|
||||
pendingEvents = new Queue<
|
||||
| InitUserPositionEventInterface
|
||||
| AddPlayerEventInterface
|
||||
| RemovePlayerEventInterface
|
||||
| UserMovedEventInterface
|
||||
| GroupCreatedUpdatedEventInterface
|
||||
| DeleteGroupEventInterface
|
||||
| PlayerDetailsUpdatedInterface
|
||||
>();
|
||||
private initPosition: PositionInterface | null = null;
|
||||
private playersPositionInterpolator = new PlayersPositionInterpolator();
|
||||
@ -735,6 +736,13 @@ export class GameScene extends DirtyScene {
|
||||
item.fire(message.event, message.state, message.parameters);
|
||||
});
|
||||
|
||||
this.connection.onPlayerDetailsUpdated((message) => {
|
||||
this.pendingEvents.enqueue({
|
||||
type: "PlayerDetailsUpdated",
|
||||
details: message,
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Triggered when we receive the JWT token to connect to Jitsi
|
||||
*/
|
||||
@ -1306,11 +1314,14 @@ ${escapedMessage}
|
||||
const red = normalizeColor(message.red);
|
||||
const green = normalizeColor(message.green);
|
||||
const blue = normalizeColor(message.blue);
|
||||
this.CurrentPlayer.setOutlineColor(red, green, blue);
|
||||
const color = (red << 16) | (green << 8) | blue;
|
||||
this.CurrentPlayer.setOutlineColor(color);
|
||||
this.connection?.emitPlayerOutlineColor(color);
|
||||
});
|
||||
|
||||
iframeListener.registerAnswerer("removePlayerOutline", (message) => {
|
||||
this.CurrentPlayer.removeOutlineColor();
|
||||
this.connection?.emitPlayerOutlineColor(null);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1689,6 +1700,11 @@ ${escapedMessage}
|
||||
case "DeleteGroupEvent":
|
||||
this.doDeleteGroup(event.groupId);
|
||||
break;
|
||||
case "PlayerDetailsUpdated":
|
||||
this.doUpdatePlayerDetails(event.details);
|
||||
break;
|
||||
default:
|
||||
const tmp: never = event;
|
||||
}
|
||||
}
|
||||
// Let's move all users
|
||||
@ -1865,6 +1881,23 @@ ${escapedMessage}
|
||||
this.groups.delete(groupId);
|
||||
}
|
||||
|
||||
doUpdatePlayerDetails(message: PlayerDetailsUpdatedMessageInterface): void {
|
||||
const character = this.MapPlayersByKey.get(message.userId);
|
||||
if (character === undefined) {
|
||||
console.log(
|
||||
"Could not set new details to character with ID ",
|
||||
message.userId,
|
||||
". Did he/she left before te message was received?"
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (message.removeOutlineColor) {
|
||||
character.removeOutlineColor();
|
||||
} else {
|
||||
character.setOutlineColor(message.outlineColor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends to the server an event emitted by one of the ActionableItems.
|
||||
*/
|
||||
|
@ -365,7 +365,9 @@ function applyCameraConstraints(currentStream: MediaStream | null, constraints:
|
||||
return;
|
||||
}
|
||||
for (const track of currentStream.getVideoTracks()) {
|
||||
toggleConstraints(track, constraints);
|
||||
toggleConstraints(track, constraints).catch((e) =>
|
||||
console.error("Error while setting new camera constraints:", e)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -380,19 +382,21 @@ function applyMicrophoneConstraints(
|
||||
return;
|
||||
}
|
||||
for (const track of currentStream.getAudioTracks()) {
|
||||
toggleConstraints(track, constraints);
|
||||
toggleConstraints(track, constraints).catch((e) =>
|
||||
console.error("Error while setting new audio constraints:", e)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function toggleConstraints(track: MediaStreamTrack, constraints: MediaTrackConstraints | boolean): void {
|
||||
async function toggleConstraints(track: MediaStreamTrack, constraints: MediaTrackConstraints | boolean): Promise<void> {
|
||||
if (implementCorrectTrackBehavior) {
|
||||
track.enabled = constraints !== false;
|
||||
} else if (constraints === false) {
|
||||
track.stop();
|
||||
}
|
||||
// @ts-ignore
|
||||
|
||||
if (typeof constraints !== "boolean" && constraints !== true) {
|
||||
track.applyConstraints(constraints);
|
||||
return track.applyConstraints(constraints);
|
||||
}
|
||||
}
|
||||
|
||||
@ -484,7 +488,12 @@ export const localStreamStore = derived<Readable<MediaStreamConstraints>, LocalS
|
||||
type: "success",
|
||||
stream: null,
|
||||
});
|
||||
initStream(constraints);
|
||||
initStream(constraints).catch((e) => {
|
||||
set({
|
||||
type: "error",
|
||||
error: e instanceof Error ? e : new Error("An unknown error happened"),
|
||||
});
|
||||
});
|
||||
}
|
||||
} else {
|
||||
//on bad navigators like chrome, we have to stop the tracks when we mute and reinstantiate the stream when we need to unmute
|
||||
@ -496,7 +505,12 @@ export const localStreamStore = derived<Readable<MediaStreamConstraints>, LocalS
|
||||
});
|
||||
} //we reemit the stream if it was muted just to be sure
|
||||
else if (constraints.audio /* && !oldConstraints.audio*/ || (!oldConstraints.video && constraints.video)) {
|
||||
initStream(constraints);
|
||||
initStream(constraints).catch((e) => {
|
||||
set({
|
||||
type: "error",
|
||||
error: e instanceof Error ? e : new Error("An unknown error happened"),
|
||||
});
|
||||
});
|
||||
}
|
||||
oldConstraints = {
|
||||
video: !!constraints.video,
|
||||
|
@ -98,7 +98,7 @@ export class SimplePeer {
|
||||
|
||||
private receiveWebrtcStart(user: UserSimplePeerInterface): void {
|
||||
this.Users.push(user);
|
||||
// Note: the clients array contain the list of all clients (even the ones we are already connected to in case a user joints a group)
|
||||
// Note: the clients array contain the list of all clients (even the ones we are already connected to in case a user joins a group)
|
||||
// So we can receive a request we already had before. (which will abort at the first line of createPeerConnection)
|
||||
// This would be symmetrical to the way we handle disconnection.
|
||||
|
||||
|
@ -13,7 +13,6 @@ message PositionMessage {
|
||||
}
|
||||
Direction direction = 3;
|
||||
bool moving = 4;
|
||||
uint32 outlineColor = 5;
|
||||
}
|
||||
|
||||
message PointMessage {
|
||||
@ -48,8 +47,12 @@ message PingMessage {
|
||||
}
|
||||
|
||||
message SetPlayerDetailsMessage {
|
||||
string name = 1;
|
||||
repeated string characterLayers = 2;
|
||||
//string name = 1;
|
||||
//repeated string characterLayers = 2;
|
||||
|
||||
// TODO: switch to google.protobuf.Int32Value when we migrate to ts-proto
|
||||
int32 outlineColor = 3;
|
||||
bool removeOutlineColor = 4;
|
||||
}
|
||||
|
||||
message UserMovesMessage {
|
||||
@ -151,6 +154,7 @@ message SubMessage {
|
||||
EmoteEventMessage emoteEventMessage = 7;
|
||||
VariableMessage variableMessage = 8;
|
||||
ErrorMessage errorMessage = 9;
|
||||
PlayerDetailsUpdatedMessage playerDetailsUpdatedMessage = 10;
|
||||
}
|
||||
}
|
||||
|
||||
@ -333,6 +337,10 @@ message GroupLeftZoneMessage {
|
||||
Zone toZone = 2;
|
||||
}
|
||||
|
||||
message PlayerDetailsUpdatedMessage {
|
||||
int32 userId = 1;
|
||||
SetPlayerDetailsMessage details = 2;
|
||||
}
|
||||
|
||||
message Zone {
|
||||
int32 x = 1;
|
||||
@ -385,6 +393,7 @@ message SubToPusherMessage {
|
||||
BanUserMessage banUserMessage = 8;
|
||||
EmoteEventMessage emoteEventMessage = 9;
|
||||
ErrorMessage errorMessage = 10;
|
||||
PlayerDetailsUpdatedMessage playerDetailsUpdatedMessage = 11;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ import {
|
||||
EmoteEventMessage,
|
||||
CompanionMessage,
|
||||
ErrorMessage,
|
||||
PlayerDetailsUpdatedMessage,
|
||||
} from "../Messages/generated/messages_pb";
|
||||
import { ClientReadableStream } from "grpc";
|
||||
import { PositionDispatcher } from "_Model/PositionDispatcher";
|
||||
@ -32,6 +33,7 @@ export interface ZoneEventListener {
|
||||
onGroupLeaves(groupId: number, listener: ExSocketInterface): void;
|
||||
onEmote(emoteMessage: EmoteEventMessage, listener: ExSocketInterface): void;
|
||||
onError(errorMessage: ErrorMessage, listener: ExSocketInterface): void;
|
||||
onPlayerDetailsUpdated(playerDetailsUpdatedMessage: PlayerDetailsUpdatedMessage, listener: ExSocketInterface): void;
|
||||
}
|
||||
|
||||
/*export type EntersCallback = (thing: Movable, listener: User) => void;
|
||||
@ -219,6 +221,10 @@ export class Zone {
|
||||
} else if (message.hasEmoteeventmessage()) {
|
||||
const emoteEventMessage = message.getEmoteeventmessage() as EmoteEventMessage;
|
||||
this.notifyEmote(emoteEventMessage);
|
||||
} else if (message.hasPlayerdetailsupdatedmessage()) {
|
||||
const playerDetailsUpdatedMessage =
|
||||
message.getPlayerdetailsupdatedmessage() as PlayerDetailsUpdatedMessage;
|
||||
this.notifyPlayerDetailsUpdated(playerDetailsUpdatedMessage);
|
||||
} else if (message.hasErrormessage()) {
|
||||
const errorMessage = message.getErrormessage() as ErrorMessage;
|
||||
this.notifyError(errorMessage);
|
||||
@ -308,6 +314,15 @@ export class Zone {
|
||||
}
|
||||
}
|
||||
|
||||
private notifyPlayerDetailsUpdated(playerDetailsUpdatedMessage: PlayerDetailsUpdatedMessage) {
|
||||
for (const listener of this.listeners) {
|
||||
if (listener.userId === playerDetailsUpdatedMessage.getUserid()) {
|
||||
continue;
|
||||
}
|
||||
this.socketListener.onPlayerDetailsUpdated(playerDetailsUpdatedMessage, listener);
|
||||
}
|
||||
}
|
||||
|
||||
private notifyError(errorMessage: ErrorMessage) {
|
||||
for (const listener of this.listeners) {
|
||||
this.socketListener.onError(errorMessage, listener);
|
||||
|
@ -34,6 +34,7 @@ import {
|
||||
VariableMessage,
|
||||
ErrorMessage,
|
||||
WorldFullMessage,
|
||||
PlayerDetailsUpdatedMessage,
|
||||
} from "../Messages/generated/messages_pb";
|
||||
import { ProtobufUtils } from "../Model/Websocket/ProtobufUtils";
|
||||
import { ADMIN_API_URL, JITSI_ISS, JITSI_URL, SECRET_JITSI_KEY } from "../Enum/EnvironmentVariable";
|
||||
@ -55,6 +56,7 @@ const debug = Debug("socket");
|
||||
interface AdminSocketRoomsList {
|
||||
[index: string]: number;
|
||||
}
|
||||
|
||||
interface AdminSocketUsersList {
|
||||
[index: string]: boolean;
|
||||
}
|
||||
@ -276,6 +278,16 @@ export class SocketManager implements ZoneEventListener {
|
||||
emitInBatch(listener, subMessage);
|
||||
}
|
||||
|
||||
onPlayerDetailsUpdated(
|
||||
playerDetailsUpdatedMessage: PlayerDetailsUpdatedMessage,
|
||||
listener: ExSocketInterface
|
||||
): void {
|
||||
const subMessage = new SubMessage();
|
||||
subMessage.setPlayerdetailsupdatedmessage(playerDetailsUpdatedMessage);
|
||||
|
||||
emitInBatch(listener, subMessage);
|
||||
}
|
||||
|
||||
onError(errorMessage: ErrorMessage, listener: ExSocketInterface): void {
|
||||
const subMessage = new SubMessage();
|
||||
subMessage.setErrormessage(errorMessage);
|
||||
|
Loading…
Reference in New Issue
Block a user