Fix channel sending two update messages on join, delete chat history when room is destroyed

This commit is contained in:
Hri7566 2024-07-31 19:01:09 -04:00
parent b8174bb571
commit 29c3caea0e
5 changed files with 307 additions and 39 deletions

View File

@ -17,7 +17,7 @@ import Crown from "./Crown";
import { ChannelList } from "./ChannelList";
import { config } from "./config";
import { config as usersConfig } from "../ws/usersConfig";
import { saveChatHistory, getChatHistory } from "../data/history";
import { saveChatHistory, getChatHistory, deleteChatHistory } from "../data/history";
import { mixin, darken } from "../util/helpers";
import { User } from "@prisma/client";
import { heapStats } from "bun:jsc";
@ -42,7 +42,18 @@ export class Channel extends EventEmitter {
public chatHistory = new Array<ClientEvents["a"]>();
private async loadChatHistory() {
try {
this.chatHistory = await getChatHistory(this.getID());
this.sendArray([{
m: "c",
c: this.chatHistory
}]);
} catch (err) { }
}
private async deleteChatHistory() {
await deleteChatHistory(this.getID());
}
public logger: Logger;
@ -97,10 +108,8 @@ export class Channel extends EventEmitter {
// ...and, possibly, an owner, too
if (creator) {
// if (this.crown.canBeSetBy(creator)) {
const part = creator.getParticipant();
if (part) this.giveCrown(part);
// }
if (part) this.giveCrown(part, true, false);
}
} else {
this.settings = config.lobbySettings;
@ -129,14 +138,13 @@ export class Channel extends EventEmitter {
this.loadChatHistory();
this.logger.info("Loaded chat history");
this.on("update", () => {
//this.logger.debug("-------- UPDATE START --------");
this.on("update", (self, uuid) => {
// Send updated info
for (const socket of socketsBySocketID.values()) {
for (const p of this.ppl) {
//if (socket.getParticipantID() == p.id) {
if (p.uuids.includes(socket.getUUID())) {
//this.logger.debug("sending to", socket.getUUID())
const socketUUID = socket.getUUID();
if (p.uuids.includes(socketUUID) && socketUUID !== uuid) {
socket.sendChannelUpdate(
this.getInfo(),
this.getParticipantList()
@ -276,6 +284,7 @@ export class Channel extends EventEmitter {
);
}
//this.logger.debug("Update from user data update handler");
this.emit("update", this);
} catch (err) {
this.logger.error(err);
@ -328,6 +337,7 @@ export class Channel extends EventEmitter {
// probably causes jank, but people can just reload their page or whatever
// not sure what to do about the URL situation
this._id = _id;
//this.logger.debug("Update from setID");
this.emit("update", this);
}
@ -407,6 +417,7 @@ export class Channel extends EventEmitter {
}
*/
//this.logger.debug("Update from changeSettings");
this.emit("update", this);
}
@ -486,7 +497,7 @@ export class Channel extends EventEmitter {
p.uuids.push(socket.getUUID())
}
socket.sendChannelUpdate(this.getInfo(), this.getParticipantList());
//socket.sendChannelUpdate(this.getInfo(), this.getParticipantList());
} else {
// Add them to the channel
hasChangedChannel = true;
@ -534,15 +545,13 @@ export class Channel extends EventEmitter {
if (p) {
// Give the crown back
this.giveCrown(p, true);
this.giveCrown(p, true, false);
}
}
}
}
}
// Send our state data back
// TODO Does this go above?
socket.sendArray([
// {
// m: "ch",
@ -578,7 +587,9 @@ export class Channel extends EventEmitter {
part.id
);
// Broadcast a channel update so everyone subscribed to the channel list can see us
// Broadcast a channel update so everyone subscribed to the channel list can see the new user count
//this.emit("update", this, socket.getUUID());
//this.logger.debug("Update from join");
this.emit("update", this);
//this.logger.debug("Settings:", this.settings);
@ -625,6 +636,7 @@ export class Channel extends EventEmitter {
}
]);
//this.logger.debug("Update from leave");
this.emit("update", this);
} else {
for (const p of this.ppl) {
@ -789,6 +801,7 @@ export class Channel extends EventEmitter {
}
ChannelList.remove(this);
this.deleteChatHistory();
this.logger.info("Destroyed");
}
@ -819,7 +832,7 @@ export class Channel extends EventEmitter {
* @param part Participant to give crown to
* @param force Whether or not to force-create a crown (useful for lobbies)
*/
public giveCrown(part: Participant, force = false) {
public giveCrown(part: Participant, force = false, update = true) {
if (force) {
if (!this.crown) this.crown = new Crown();
}
@ -828,9 +841,13 @@ export class Channel extends EventEmitter {
this.crown.userId = part._id;
this.crown.participantId = part.id;
this.crown.time = Date.now();
if (update) {
//this.logger.debug("Update from giveCrown");
this.emit("update", this);
}
}
}
/**
* Drop the crown (reset timer, and, if applicable, remove from user's head)
@ -865,6 +882,7 @@ export class Channel extends EventEmitter {
delete this.crown.participantId;
//this.logger.debug("Update from dropCrown");
this.emit("update", this);
}
}
@ -951,6 +969,7 @@ export class Channel extends EventEmitter {
}
if (shouldUpdate) {
//this.logger.debug("Update from kickban");
this.emit("update", this);
if (typeof banner !== "undefined") {
@ -1149,7 +1168,7 @@ export class Channel extends EventEmitter {
public printMemoryInChat() {
const mem = heapStats();
this.sendChatAdmin(`Size: ${(mem.heapSize / 1000 / 1000).toFixed(2)}M / Capacity: ${(mem.heapCapacity / 1000 / 1000).toFixed(2)}M`);
this.sendChatAdmin(`Used: ${(mem.heapSize / 1000 / 1000).toFixed(2)}M / Allocated: ${(mem.heapCapacity / 1000 / 1000).toFixed(2)}M`);
}
}

View File

@ -27,3 +27,7 @@ export async function getChatHistory(_id: string) {
return [];
}
}
export async function deleteChatHistory(_id: string) {
await prisma.chatHistory.delete({ where: { id: _id } });
}

View File

@ -50,7 +50,7 @@ export async function createToken(userID: string, gateway: Gateway) {
let token = "";
if (config.tokenAuth == "uuid") {
token = crypto.randomUUID();
token = userID + "." + crypto.randomUUID();
} else if (config.tokenAuth == "jwt") {
token = generateJWT(userID, gateway);
}

View File

@ -32,6 +32,7 @@ export const hi: ServerEventListener<"hi"> = {
let token: string | undefined;
let generatedToken = false;
if (config.tokenAuth !== "none") {
if (typeof msg.token !== "string") {
// Get a saved token
token = await getToken(socket.getUserID());
@ -55,6 +56,7 @@ export const hi: ServerEventListener<"hi"> = {
token = msg.token;
}
}
let part = socket.getParticipant();

243
top Normal file
View File

@ -0,0 +1,243 @@
diff --git a/src/channel/Channel.ts b/src/channel/Channel.ts
index e33ddc6..b6072be 100755
--- a/src/channel/Channel.ts
+++ b/src/channel/Channel.ts
@@ -17,7 +17,7 @@ import Crown from "./Crown";
import { ChannelList } from "./ChannelList";
import { config } from "./config";
import { config as usersConfig } from "../ws/usersConfig";
import { saveChatHistory, [-getChatHistory-]{+getChatHistory, deleteChatHistory+} } from "../data/history";
import { mixin, darken } from "../util/helpers";
import { User } from "@prisma/client";
import { heapStats } from "bun:jsc";
@@ -42,7 +42,18 @@ export class Channel extends EventEmitter {
public chatHistory = new Array<ClientEvents["a"]>();
private async loadChatHistory() {
{+try {+}
this.chatHistory = await getChatHistory(this.getID());
{+this.sendArray([{+}
{+ m: "c",+}
{+ c: this.chatHistory+}
{+ }]);+}
{+ } catch (err) { }+}
{+ }+}
{+ private async deleteChatHistory() {+}
{+ await deleteChatHistory(this.getID());+}
}
public logger: Logger;
@@ -97,10 +108,8 @@ export class Channel extends EventEmitter {
// ...and, possibly, an owner, too
if (creator) {
[- // if (this.crown.canBeSetBy(creator)) {-]
const part = creator.getParticipant();
if (part) [-this.giveCrown(part);-]
[- // }-]{+this.giveCrown(part, true, false);+}
}
} else {
this.settings = config.lobbySettings;
@@ -129,14 +138,13 @@ export class Channel extends EventEmitter {
this.loadChatHistory();
this.logger.info("Loaded chat history");
this.on("update", [-()-]{+(self, uuid)+} => {[-//this.logger.debug("-------- UPDATE START --------");-]
// Send updated info
for (const socket of socketsBySocketID.values()) {
for (const p of this.ppl) {
[-//if (socket.getParticipantID() == p.id) {-]{+const socketUUID = socket.getUUID();+}
if [-(p.uuids.includes(socket.getUUID()))-]{+(p.uuids.includes(socketUUID) && socketUUID !== uuid)+} {[-//this.logger.debug("sending to", socket.getUUID())-]
socket.sendChannelUpdate(
this.getInfo(),
this.getParticipantList()
@@ -276,6 +284,7 @@ export class Channel extends EventEmitter {
);
}
{+this.logger.debug("Update from user data update handler");+}
this.emit("update", this);
} catch (err) {
this.logger.error(err);
@@ -328,6 +337,7 @@ export class Channel extends EventEmitter {
// probably causes jank, but people can just reload their page or whatever
// not sure what to do about the URL situation
this._id = _id;
{+this.logger.debug("Update from setID");+}
this.emit("update", this);
}
@@ -407,6 +417,7 @@ export class Channel extends EventEmitter {
}
*/
{+this.logger.debug("Update from changeSettings");+}
this.emit("update", this);
}
@@ -486,7 +497,7 @@ export class Channel extends EventEmitter {
p.uuids.push(socket.getUUID())
}
[-socket.sendChannelUpdate(this.getInfo(),-]{+//socket.sendChannelUpdate(this.getInfo(),+} this.getParticipantList());
} else {
// Add them to the channel
hasChangedChannel = true;
@@ -534,15 +545,13 @@ export class Channel extends EventEmitter {
if (p) {
// Give the crown back
this.giveCrown(p, [-true);-]{+true, false);+}
}
}
}
}
}
[- // Send our state data back-]
[- // TODO Does this go above?-]
socket.sendArray([
// {
// m: "ch",
@@ -578,7 +587,9 @@ export class Channel extends EventEmitter {
part.id
);
// Broadcast a channel update so everyone subscribed to the channel list can see [-us-]{+the new user count+}
{+ //this.emit("update", this, socket.getUUID());+}
{+ this.logger.debug("Update from join");+}
this.emit("update", this);
//this.logger.debug("Settings:", this.settings);
@@ -625,6 +636,7 @@ export class Channel extends EventEmitter {
}
]);
{+this.logger.debug("Update from leave");+}
this.emit("update", this);
} else {
for (const p of this.ppl) {
@@ -789,6 +801,7 @@ export class Channel extends EventEmitter {
}
ChannelList.remove(this);
{+this.deleteChatHistory();+}
this.logger.info("Destroyed");
}
@@ -819,7 +832,7 @@ export class Channel extends EventEmitter {
* @param part Participant to give crown to
* @param force Whether or not to force-create a crown (useful for lobbies)
*/
public giveCrown(part: Participant, force = [-false)-]{+false, update = true)+} {
if (force) {
if (!this.crown) this.crown = new Crown();
}
@@ -828,7 +841,11 @@ export class Channel extends EventEmitter {
this.crown.userId = part._id;
this.crown.participantId = part.id;
this.crown.time = Date.now();
{+if (update) {+}
{+ this.logger.debug("Update from giveCrown");+}
this.emit("update", this);
{+}+}
}
}
@@ -865,6 +882,7 @@ export class Channel extends EventEmitter {
delete this.crown.participantId;
{+this.logger.debug("Update from dropCrown");+}
this.emit("update", this);
}
}
@@ -951,6 +969,7 @@ export class Channel extends EventEmitter {
}
if (shouldUpdate) {
{+this.logger.debug("Update from kickban");+}
this.emit("update", this);
if (typeof banner !== "undefined") {
@@ -1149,7 +1168,7 @@ export class Channel extends EventEmitter {
public printMemoryInChat() {
const mem = heapStats();
[-this.sendChatAdmin(`Size:-]{+this.sendChatAdmin(`Used:+} ${(mem.heapSize / 1000 / 1000).toFixed(2)}M / [-Capacity:-]{+Allocated:+} ${(mem.heapCapacity / 1000 / 1000).toFixed(2)}M`);
}
}
diff --git a/src/data/history.ts b/src/data/history.ts
index b769e27..0b68962 100755
--- a/src/data/history.ts
+++ b/src/data/history.ts
@@ -27,3 +27,7 @@ export async function getChatHistory(_id: string) {
return [];
}
}
{+export async function deleteChatHistory(_id: string) {+}
{+ await prisma.chatHistory.delete({ where: { id: _id } });+}
{+}+}
diff --git a/src/util/token.ts b/src/util/token.ts
index 54d22af..4e7bf6f 100644
--- a/src/util/token.ts
+++ b/src/util/token.ts
@@ -50,7 +50,7 @@ export async function createToken(userID: string, gateway: Gateway) {
let token = "";
if (config.tokenAuth == "uuid") {
token = {+userID + "." ++} crypto.randomUUID();
} else if (config.tokenAuth == "jwt") {
token = generateJWT(userID, gateway);
}
diff --git a/src/ws/events/user/handlers/hi.ts b/src/ws/events/user/handlers/hi.ts
index 91067b1..964c2cb 100755
--- a/src/ws/events/user/handlers/hi.ts
+++ b/src/ws/events/user/handlers/hi.ts
@@ -32,28 +32,30 @@ export const hi: ServerEventListener<"hi"> = {
let token: string | undefined;
let generatedToken = false;
if {+(config.tokenAuth !== "none") {+}
{+ if+} (typeof msg.token !== "string") {
// Get a saved token
token = await getToken(socket.getUserID());[-if (typeof token !== "string") {-]
[- // Generate a new one-]
[- token = await createToken(socket.getUserID(), socket.gateway);-]
if (typeof token !== "string") {
{+// Generate a new one+}
{+ token = await createToken(socket.getUserID(), socket.gateway);+}
{+ if (typeof token !== "string") {+}
logger.warn(`Unable to generate token for user ${socket.getUserID()}`);
} else {
generatedToken = true;
{+}+}
{+ }+}
{+ } else {+}
{+ // Validate the token+}
{+ const valid = await validateToken(socket.getUserID(), msg.token);+}
{+ if (!valid) {+}
{+ socket.ban(60000, "Invalid token");+}
{+ return;+}
}
[- }-]
[- } else {-]
[- // Validate the token-]
[- const valid = await validateToken(socket.getUserID(), msg.token);-]
[- if (!valid) {-]
[- socket.ban(60000, "Invalid token");-]
[- return;-]
[- }-]
token = msg.token;
{+}+}
}
let part = socket.getParticipant();