Refactoring following code to make a distinction beween followed and following users.
Also, moving sending messages to the User class.
This commit is contained in:
parent
fd9cb09de6
commit
cd805fab31
@ -125,7 +125,6 @@ export class GameRoom {
|
|||||||
joinRoomMessage.getIpaddress(),
|
joinRoomMessage.getIpaddress(),
|
||||||
position,
|
position,
|
||||||
false,
|
false,
|
||||||
[],
|
|
||||||
this.positionNotifier,
|
this.positionNotifier,
|
||||||
socket,
|
socket,
|
||||||
joinRoomMessage.getTagList(),
|
joinRoomMessage.getTagList(),
|
||||||
@ -228,7 +227,7 @@ export class GameRoom {
|
|||||||
this.leaveGroup(user);
|
this.leaveGroup(user);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const users = user.group.getUsers().filter((u) => u.following.length === 0);
|
const users = user.group.getUsers().filter((u) => !u.hasFollowers() && !u.following);
|
||||||
users.forEach((foreignUser) => leaveIfOutOfRadius(foreignUser));
|
users.forEach((foreignUser) => leaveIfOutOfRadius(foreignUser));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,4 +152,16 @@ export class Group implements Movable {
|
|||||||
get getSize() {
|
get getSize() {
|
||||||
return this.users.size;
|
return this.users.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A group can have at most one person leading the way in it.
|
||||||
|
*/
|
||||||
|
get leader(): User|undefined {
|
||||||
|
for (const user of this.users) {
|
||||||
|
if (user.hasFollowers()) {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import { PositionNotifier } from "_Model/PositionNotifier";
|
|||||||
import { ServerDuplexStream } from "grpc";
|
import { ServerDuplexStream } from "grpc";
|
||||||
import {
|
import {
|
||||||
BatchMessage,
|
BatchMessage,
|
||||||
CompanionMessage,
|
CompanionMessage, FollowAbortMessage, FollowConfirmationMessage,
|
||||||
PusherToBackMessage,
|
PusherToBackMessage,
|
||||||
ServerToClientMessage,
|
ServerToClientMessage,
|
||||||
SubMessage,
|
SubMessage,
|
||||||
@ -18,6 +18,8 @@ export type UserSocket = ServerDuplexStream<PusherToBackMessage, ServerToClientM
|
|||||||
export class User implements Movable {
|
export class User implements Movable {
|
||||||
public listenedZones: Set<Zone>;
|
public listenedZones: Set<Zone>;
|
||||||
public group?: Group;
|
public group?: Group;
|
||||||
|
private _following: User|undefined;
|
||||||
|
private followedBy: Set<User> = new Set<User>();
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
public id: number,
|
public id: number,
|
||||||
@ -25,7 +27,6 @@ export class User implements Movable {
|
|||||||
public readonly IPAddress: string,
|
public readonly IPAddress: string,
|
||||||
private position: PointInterface,
|
private position: PointInterface,
|
||||||
public silent: boolean,
|
public silent: boolean,
|
||||||
public following: number[],
|
|
||||||
private positionNotifier: PositionNotifier,
|
private positionNotifier: PositionNotifier,
|
||||||
public readonly socket: UserSocket,
|
public readonly socket: UserSocket,
|
||||||
public readonly tags: string[],
|
public readonly tags: string[],
|
||||||
@ -49,19 +50,43 @@ export class User implements Movable {
|
|||||||
this.positionNotifier.updatePosition(this, position, oldPosition);
|
this.positionNotifier.updatePosition(this, position, oldPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
public addFollower(userId: number): void {
|
public addFollower(follower: User): void {
|
||||||
if (this.following.includes(userId)) {
|
this.followedBy.add(follower);
|
||||||
return;
|
follower._following = this;
|
||||||
}
|
|
||||||
this.following.push(userId);
|
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(userId: number): void {
|
public delFollower(follower: User): void {
|
||||||
const idx = this.following.indexOf(userId);
|
this.followedBy.delete(follower);
|
||||||
if (idx === -1) {
|
follower._following = undefined;
|
||||||
return;
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
get following(): User | undefined {
|
||||||
|
return this._following;
|
||||||
|
}
|
||||||
|
|
||||||
|
public stopLeading(): void {
|
||||||
|
for (const follower of this.followedBy) {
|
||||||
|
this.delFollower(follower);
|
||||||
}
|
}
|
||||||
this.following.splice(idx, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private batchedMessages: BatchMessage = new BatchMessage();
|
private batchedMessages: BatchMessage = new BatchMessage();
|
||||||
|
@ -844,34 +844,28 @@ export class SocketManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleFollowConfirmationMessage(room: GameRoom, user: User, message: FollowConfirmationMessage) {
|
handleFollowConfirmationMessage(room: GameRoom, user: User, message: FollowConfirmationMessage) {
|
||||||
const clientMessage = new ServerToClientMessage();
|
|
||||||
clientMessage.setFollowconfirmationmessage(message);
|
|
||||||
const leader = room.getUserById(message.getLeader());
|
const leader = room.getUserById(message.getLeader());
|
||||||
leader?.socket.write(clientMessage);
|
if (!leader) {
|
||||||
|
console.info('Could not find user "', message.getLeader(), '" while handling a follow confirmation in room "', room.roomUrl,'". Maybe the user just left.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
leader?.addFollower(user.id);
|
// By security, we look at the group leader. If the group leader is NOT the leader in the message, everybody should
|
||||||
user.addFollower(message.getLeader());
|
// stop following the group leader (to avoid having 2 group leaders)
|
||||||
|
if (user?.group?.leader && user?.group?.leader !== leader) {
|
||||||
|
user?.group?.leader?.stopLeading();
|
||||||
|
}
|
||||||
|
|
||||||
|
leader.addFollower(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleFollowAbortMessage(room: GameRoom, user: User, message: FollowAbortMessage) {
|
handleFollowAbortMessage(room: GameRoom, user: User, message: FollowAbortMessage) {
|
||||||
const clientMessage = new ServerToClientMessage();
|
|
||||||
clientMessage.setFollowabortmessage(message);
|
|
||||||
if (user.id === message.getLeader()) {
|
if (user.id === message.getLeader()) {
|
||||||
// Forward message
|
user?.group?.leader?.stopLeading();
|
||||||
room.sendToOthersInGroupIncludingUser(user, clientMessage);
|
|
||||||
|
|
||||||
// Update followers
|
|
||||||
user.group?.getUsers().forEach((user) => {
|
|
||||||
user.following = [];
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
// Forward message
|
// Forward message
|
||||||
const leader = room.getUserById(message.getLeader());
|
const leader = room.getUserById(message.getLeader());
|
||||||
leader?.socket.write(clientMessage);
|
leader?.delFollower(user);
|
||||||
|
|
||||||
// Update followers
|
|
||||||
leader?.delFollower(user.id);
|
|
||||||
user.following = [];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user