Compare commits

..

No commits in common. "f52715abf31f1b30dd3124fc00da341e3cd43332" and "5d5c10d7a555d06967745d2de47a1653ea4f1890" have entirely different histories.

9 changed files with 55 additions and 175 deletions

BIN
bun.lockb

Binary file not shown.

View File

@ -25,7 +25,7 @@ interface CachedKickban {
export class Channel extends EventEmitter { export class Channel extends EventEmitter {
private settings: Partial<IChannelSettings>; private settings: Partial<IChannelSettings>;
private ppl = new Array<Participant & { uuids: string[] }>(); private ppl = new Array<Participant>();
public chatHistory = new Array<ClientEvents["a"]>(); public chatHistory = new Array<ClientEvents["a"]>();
private async loadChatHistory() { private async loadChatHistory() {
@ -55,9 +55,9 @@ export class Channel extends EventEmitter {
if (!this.isLobby()) { if (!this.isLobby()) {
if (set) { if (set) {
//this.logger.debug("Passed settings:", set); this.logger.debug("Passed settings:", set);
const validatedSet = validateChannelSettings(set); const validatedSet = validateChannelSettings(set);
//this.logger.debug("Validated settings:", validatedSet); this.logger.debug("Validated settings:", validatedSet);
for (const key of Object.keys(set)) { for (const key of Object.keys(set)) {
if ((validatedSet as any)[key] === false) continue; if ((validatedSet as any)[key] === false) continue;
@ -94,13 +94,10 @@ export class Channel extends EventEmitter {
this.logger.info("Loaded Chat History."); this.logger.info("Loaded Chat History.");
this.on("update", () => { this.on("update", () => {
//this.logger.debug("-------- UPDATE START --------");
// Send updated info // Send updated info
for (const socket of socketsBySocketID.values()) { for (const socket of socketsBySocketID.values()) {
for (const p of this.ppl) { for (const p of this.ppl) {
//if (socket.getParticipantID() == p.id) { if (socket.getParticipantID() == p.id) {
if (p.uuids.includes(socket.getUUID())) {
//this.logger.debug("sending to", socket.getUUID())
socket.sendChannelUpdate( socket.sendChannelUpdate(
this.getInfo(), this.getInfo(),
this.getParticipantList() this.getParticipantList()
@ -144,10 +141,6 @@ export class Channel extends EventEmitter {
if (msg.message.startsWith("/")) { if (msg.message.startsWith("/")) {
this.emit("command", msg, socket); this.emit("command", msg, socket);
} }
if (msg.message == "debug") {
this.logger.info(socket.getUUID(), socket.currentChannelID);
}
} catch (err) { } catch (err) {
this.logger.error(err); this.logger.error(err);
} }
@ -198,14 +191,12 @@ export class Channel extends EventEmitter {
if (set.owner_id) set.owner_id = undefined; if (set.owner_id) set.owner_id = undefined;
} }
/*
this.logger.debug( this.logger.debug(
"Dreaded color2 conditions:", "Dreaded color2 conditions:",
typeof set.color == "string", typeof set.color == "string",
"and", "and",
typeof set.color2 == "undefined" typeof set.color2 == "undefined"
); );
*/
if ( if (
typeof set.color == "string" && typeof set.color == "string" &&
@ -265,7 +256,6 @@ export class Channel extends EventEmitter {
public join(socket: Socket): void { public join(socket: Socket): void {
//! /!\ Players are forced to join the same channel on two different tabs! //! /!\ Players are forced to join the same channel on two different tabs!
//? TODO Should this be a bug or a feature? //? TODO Should this be a bug or a feature?
//this.logger.debug("join triggered");
if (this.isDestroyed()) return; if (this.isDestroyed()) return;
const part = socket.getParticipant() as Participant; const part = socket.getParticipant() as Participant;
@ -279,48 +269,26 @@ export class Channel extends EventEmitter {
// TODO Send notification for ban // TODO Send notification for ban
const chs = ChannelList.getList(); const chs = ChannelList.getList();
for (const ch of chs) { for (const ch of chs) {
const chid = ch.getID(); if (ch.getID() == config.fullChannel) {
if (chid == config.fullChannel) { return ch.join(socket);
return socket.setChannel(chid)
} }
} }
} }
// Is user in this channel? // Is user in this channel?
if (this.hasUser(part._id)) { if (this.hasUser(part._id)) {
// Already in channel, don't add to list, but tell them they're here // Alreay in channel, don't add to list, but tell them they're here
hasChangedChannel = true; hasChangedChannel = true;
this.ppl.push(part);
for (const p of this.ppl) {
if (p.id !== part.id) continue;
p.uuids.push(socket.getUUID())
}
socket.sendChannelUpdate(this.getInfo(), this.getParticipantList());
} else { } else {
// Are we full? // Are we full?
if (!this.isFull()) { if (!this.isFull()) {
// Add to channel // Add to channel
hasChangedChannel = true; hasChangedChannel = true;
this.ppl.push({ this.ppl.push(part);
_id: part._id,
name: part.name,
color: part.color,
id: part.id,
tag: part.tag,
uuids: [socket.getUUID()]
});
} else { } else {
if (socket.currentChannelID !== config.fullChannel) { // Put them in full channel
// Put them in full channel return socket.setChannel(config.fullChannel);
const chs = ChannelList.getList();
for (const ch of chs) {
const chid = ch.getID();
if (chid == config.fullChannel) {
return socket.setChannel(chid)
}
}
}
} }
} }
@ -380,7 +348,7 @@ export class Channel extends EventEmitter {
// 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 us
this.emit("update", this); this.emit("update", this);
//this.logger.debug("Settings:", this.settings); this.logger.debug("Settings:", this.settings);
} }
/** /**
@ -418,11 +386,6 @@ export class Channel extends EventEmitter {
]); ]);
this.emit("update", this); this.emit("update", this);
} else {
for (const p of this.ppl) {
if (!p.uuids.includes(socket.getUUID())) continue;
p.uuids.splice(p.uuids.indexOf(socket.getUUID()), 1);
}
} }
} }
@ -462,13 +425,7 @@ export class Channel extends EventEmitter {
* @returns List of people * @returns List of people
*/ */
public getParticipantList() { public getParticipantList() {
return this.ppl.map(p => ({ return this.ppl;
id: p.id,
_id: p._id,
name: p.name,
color: p.color,
tag: p.tag
}));
} }
/** /**
@ -649,60 +606,35 @@ export class Channel extends EventEmitter {
} }
/** /**
* Kickban a participant for t milliseconds. * Kickban a poor soul for t milliseconds.
* @param _id User ID to ban * @param _id User ID to ban
* @param t Time in millseconds to ban for * @param t Time in millseconds to ban for
**/ **/
public kickban(_id: string, t: number = 1000 * 60 * 30) { public kickban(_id: string, t: number = 1000 * 60 * 30) {
const now = Date.now(); const now = Date.now();
let shouldUpdate = false; if (!this.hasUser(_id)) return;
const part = this.ppl.find(p => p._id == _id);
if (!part) return;
this.bans.push({
userId: _id,
startTime: now,
endTime: now + t
});
const socket = findSocketByPartID(part.id);
if (!socket) return;
const banChannel = ChannelList.getList().find( const banChannel = ChannelList.getList().find(
ch => ch.getID() == config.fullChannel ch => ch.getID() == config.fullChannel
); );
if (!banChannel) return; if (!banChannel) return;
banChannel.join(socket);
let isBanned = this.bans.map(b => b.userId).includes(_id); this.emit("update", this);
let overwrite = false;
if (isBanned) {
overwrite = true;
}
let uuidsToKick: string[] = [];
for (const part of this.ppl) {
if (part._id !== _id) continue;
if (!overwrite) {
this.bans.push({
userId: _id,
startTime: now,
endTime: now + t
});
} else {
for (const ban of this.bans) {
if (ban.userId !== _id) continue;
ban.startTime = now;
ban.endTime = now + t;
}
}
uuidsToKick = [...uuidsToKick, ...part.uuids];
shouldUpdate = true;
}
for (const socket of socketsBySocketID.values()) {
if (uuidsToKick.includes(socket.getUUID())) {
socket.setChannel(banChannel.getID());
}
}
if (shouldUpdate)
this.emit("update", this);
} }
public isBanned(_id: string) { public isBanned(_id: string) {

View File

@ -16,14 +16,10 @@ export async function saveChatHistory(_id: string, chatHistory: object) {
} }
export async function getChatHistory(_id: string) { export async function getChatHistory(_id: string) {
try { const history = await prisma.chatHistory.findFirst({ where: { id: _id } });
const history = await prisma.chatHistory.findFirst({ where: { id: _id } }); if (!history) {
if (!history) {
return [];
} else {
return JSON.parse(history.messages);
}
} catch (err) {
return []; return [];
} else {
return JSON.parse(history.messages);
} }
} }

View File

@ -27,24 +27,20 @@ export async function deleteUser(_id: string) {
} }
export async function readUser(_id: string) { export async function readUser(_id: string) {
try { const data = await prisma.user.findUnique({
const data = await prisma.user.findUnique({ where: { id: _id }
where: { id: _id } });
});
if (!data) return null; if (!data) return null;
// return { // return {
// _id: data.id, // _id: data.id,
// name: data.name, // name: data.name,
// color: data.color, // color: data.color,
// flags: data.flags // flags: data.flags
// }; // };
return data; return data;
} catch (err) {
return createUser(_id);
}
} }
export async function updateUser( export async function updateUser(

View File

@ -37,7 +37,6 @@ export class Socket extends EventEmitter {
private id: string; private id: string;
private _id: string; private _id: string;
private ip: string; private ip: string;
private uuid: string;
private user: User | null = null; private user: User | null = null;
public gateway = new Gateway(); public gateway = new Gateway();
@ -49,9 +48,9 @@ export class Socket extends EventEmitter {
_id: string | undefined; _id: string | undefined;
set: Partial<IChannelSettings> | undefined; set: Partial<IChannelSettings> | undefined;
} = { } = {
_id: undefined, _id: undefined,
set: {} set: {}
}; };
public currentChannelID: string | undefined; public currentChannelID: string | undefined;
private cursorPos: Vector2<CursorValue> = { x: 200, y: 100 }; private cursorPos: Vector2<CursorValue> = { x: 200, y: 100 };
@ -65,26 +64,19 @@ export class Socket extends EventEmitter {
// User ID // User ID
this._id = createUserID(this.getIP()); this._id = createUserID(this.getIP());
this.uuid = crypto.randomUUID();
// Check if we're already connected // Check if we're already connected
// We need to skip ourselves, so we loop here instead of using a helper // We need to skip ourselves, so we loop here instead of using a helper
let foundSocket; let foundSocket;
let count = 0;
for (const socket of socketsBySocketID.values()) { for (const socket of socketsBySocketID.values()) {
if (socket.socketID == this.socketID || socket.ws.readyState !== 1) continue; if (socket.socketID == this.socketID) continue;
if (socket.getUserID() == this.getUserID()) { if (socket.getUserID() == this.getUserID()) {
foundSocket = socket; foundSocket = socket;
count++;
} }
} }
if (count >= 4) {
this.destroy();
}
// logger.debug("Found socket?", foundSocket); // logger.debug("Found socket?", foundSocket);
if (!foundSocket) { if (!foundSocket) {
@ -92,11 +84,11 @@ export class Socket extends EventEmitter {
this.id = createID(); this.id = createID();
} else { } else {
// Use original session ID // Use original session ID
this.id = foundSocket.id; // this.id = foundSocket.id;
// Break us off // Break us off
//this.id = "broken"; this.id = "broken";
//this.destroy(); this.destroy();
} }
(async () => { (async () => {
@ -468,10 +460,6 @@ export class Socket extends EventEmitter {
channel.kickban(_id, ms); channel.kickban(_id, ms);
} }
} }
public getUUID() {
return this.uuid;
}
} }
export const socketsBySocketID = new Map<string, Socket>(); export const socketsBySocketID = new Map<string, Socket>();

View File

@ -6,7 +6,6 @@ export const color: ServerEventListener<"color"> = {
id: "color", id: "color",
callback: async (msg, socket) => { callback: async (msg, socket) => {
// I'm not allowed to use this feature on MPP.net for a really stupid reason // I'm not allowed to use this feature on MPP.net for a really stupid reason
// Nevermind, fishing bot has color again
const id = msg._id; const id = msg._id;
const color = msg.color; const color = msg.color;

View File

@ -1,29 +0,0 @@
import { Logger } from "../../../../util/Logger";
import { ServerEventListener } from "../../../../util/types";
const logger = new Logger("chown");
export const chown: ServerEventListener<"chown"> = {
id: "chown",
callback: (msg, socket) => {
// Change channel ownership
if (typeof msg.id == "undefined") return;
const ch = socket.getCurrentChannel();
if (!ch) return;
if (!socket.isOwner()) return;
if (!ch.crown) {
// TODO Crown admin stuff
} else {
if (!ch.crown.canBeSetBy(socket)) return;
const heir = ch.getParticipantList().find(p => p.id == msg.id);
if (!heir) return;
ch.chown(heir);
}
}
};

View File

@ -3,9 +3,9 @@ import { ServerEventListener } from "../../../../util/types";
export const kickban: ServerEventListener<"kickban"> = { export const kickban: ServerEventListener<"kickban"> = {
id: "kickban", id: "kickban",
callback: (msg, socket) => { callback: (msg, socket) => {
// Kickbanning some asshole from channel // Kickban asshole from channel
if (typeof msg._id !== "string") return; if (!msg._id) return;
if (typeof msg.ms !== "number") return; if (!msg.ms) return;
socket.kickban(msg._id, msg.ms); socket.kickban(msg._id, msg.ms);
} }
}; };

View File

@ -15,7 +15,6 @@ import { admin_message } from "./handlers/admin_message";
import { chset } from "./handlers/chset"; import { chset } from "./handlers/chset";
import { kickban } from "./handlers/kickban"; import { kickban } from "./handlers/kickban";
import { bye } from "./handlers/bye"; import { bye } from "./handlers/bye";
import { chown } from "./handlers/chown";
// Imagine not having an "addMany" function... // Imagine not having an "addMany" function...
@ -45,8 +44,7 @@ EVENTGROUP_USER.addMany(
admin_message, admin_message,
chset, chset,
kickban, kickban,
bye, bye
chown
); );
eventGroups.push(EVENTGROUP_USER); eventGroups.push(EVENTGROUP_USER);