Files
partey_workadventure/back/src/Model/User.ts
T
Piotr 'pwh' Hanusiak 7385ce522f removed silentStore
2022-04-14 16:49:05 +02:00

161 lines
5.3 KiB
TypeScript

import { Group } from "./Group";
import { PointInterface } from "./Websocket/PointInterface";
import { Zone } from "../Model/Zone";
import { Movable } from "../Model/Movable";
import { PositionNotifier } from "../Model/PositionNotifier";
import { ServerDuplexStream } from "grpc";
import {
AvailabilityStatus,
BatchMessage,
CompanionMessage,
FollowAbortMessage,
FollowConfirmationMessage,
PusherToBackMessage,
ServerToClientMessage,
SetPlayerDetailsMessage,
SubMessage,
} from "../Messages/generated/messages_pb";
import { CharacterLayer } from "../Model/Websocket/CharacterLayer";
import { BoolValue, UInt32Value } from "google-protobuf/google/protobuf/wrappers_pb";
export type UserSocket = ServerDuplexStream<PusherToBackMessage, ServerToClientMessage>;
export class User implements Movable {
public listenedZones: Set<Zone>;
public group?: Group;
private _following: User | undefined;
private followedBy: Set<User> = new Set<User>();
public constructor(
public id: number,
public readonly uuid: string,
public readonly IPAddress: string,
private position: PointInterface,
private positionNotifier: PositionNotifier,
private status: AvailabilityStatus,
public readonly socket: UserSocket,
public readonly tags: string[],
public readonly visitCardUrl: string | null,
public readonly name: string,
public readonly characterLayers: CharacterLayer[],
public readonly companion?: CompanionMessage,
private outlineColor?: number,
private voiceIndicatorShown?: boolean
) {
this.listenedZones = new Set<Zone>();
this.positionNotifier.enter(this);
}
public getPosition(): PointInterface {
return this.position;
}
public setPosition(position: PointInterface): void {
const oldPosition = this.position;
this.position = position;
this.positionNotifier.updatePosition(this, position, oldPosition);
}
public addFollower(follower: User): void {
this.followedBy.add(follower);
follower._following = this;
const message = new FollowConfirmationMessage();
message.setFollower(follower.id);
message.setLeader(this.id);
const clientMessage = new ServerToClientMessage();
clientMessage.setFollowconfirmationmessage(message);
this.socket.write(clientMessage);
}
public delFollower(follower: User): void {
this.followedBy.delete(follower);
follower._following = undefined;
const message = new FollowAbortMessage();
message.setFollower(follower.id);
message.setLeader(this.id);
const clientMessage = new ServerToClientMessage();
clientMessage.setFollowabortmessage(message);
this.socket.write(clientMessage);
follower.socket.write(clientMessage);
}
public hasFollowers(): boolean {
return this.followedBy.size !== 0;
}
public getOutlineColor(): number | undefined {
return this.outlineColor;
}
public getStatus(): AvailabilityStatus {
return this.status;
}
public get silent(): boolean {
return this.status === AvailabilityStatus.SILENT || this.status === AvailabilityStatus.JITSI;
}
get following(): User | undefined {
return this._following;
}
public stopLeading(): void {
for (const follower of this.followedBy) {
this.delFollower(follower);
}
}
private batchedMessages: BatchMessage = new BatchMessage();
private batchTimeout: NodeJS.Timeout | null = null;
public emitInBatch(payload: SubMessage): void {
this.batchedMessages.addPayload(payload);
if (this.batchTimeout === null) {
this.batchTimeout = setTimeout(() => {
/*if (socket.disconnecting) {
return;
}*/
const serverToClientMessage = new ServerToClientMessage();
serverToClientMessage.setBatchmessage(this.batchedMessages);
this.socket.write(serverToClientMessage);
this.batchedMessages = new BatchMessage();
this.batchTimeout = null;
}, 100);
}
}
public updateDetails(details: SetPlayerDetailsMessage) {
if (details.getRemoveoutlinecolor()) {
this.outlineColor = undefined;
} else if (details.getOutlinecolor()?.getValue() !== undefined) {
this.outlineColor = details.getOutlinecolor()?.getValue();
}
this.voiceIndicatorShown = details.getShowvoiceindicator()?.getValue();
const status = details.getStatus();
if (status !== undefined) {
this.status = status;
}
const playerDetails = new SetPlayerDetailsMessage();
if (this.outlineColor !== undefined) {
playerDetails.setOutlinecolor(new UInt32Value().setValue(this.outlineColor));
}
if (this.voiceIndicatorShown !== undefined) {
playerDetails.setShowvoiceindicator(new BoolValue().setValue(this.voiceIndicatorShown));
}
if (details.getStatus() !== undefined) {
playerDetails.setStatus(details.getStatus());
}
this.positionNotifier.updatePlayerDetails(this, playerDetails);
}
}