Skip to content

Commit

Permalink
chat history fix
Browse files Browse the repository at this point in the history
  • Loading branch information
evolutionleo committed Dec 4, 2024
1 parent 6a5a585 commit d3ee1ce
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 40 deletions.
10 changes: 9 additions & 1 deletion Client/scripts/chatHandlers/chatHandlers.gml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,13 @@ addHandler("chat msg", function(data) {
})

addHandler("chat history", function(data) {
trace(data.messages)
trace(data.history)
})

addHandler("chats list", function(data) {
var ids = data.chats
})

addHandler("chat info", function(data) {
trace("chat info: %", data.chat)
})
6 changes: 6 additions & 0 deletions TypescriptServer/src/cmd/handlers/chat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import addHandler from "#cmd/handlePacket";

// list of all the chats of this player
addHandler('chats list', (c, data) => {
c.sendChatsList();
});
3 changes: 0 additions & 3 deletions TypescriptServer/src/cmd/handlers/custom.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import { addHandler } from "#cmd/handlePacket";
import { PlayerInputs } from "#entities/player";
import Point from "#types/point";
import { clamp } from "#util/maths";

addHandler('player controls', (c, data) => {
if (!c.entity) return;
Expand Down
3 changes: 3 additions & 0 deletions TypescriptServer/src/cmd/sendStuff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Party from '#matchmaking/party';
import IClient from '#types/client_properties';
import Match from '#matchmaking/match';
import { ISession } from '#schemas/session';
import Chat from '#concepts/chat';


// sender functions can be later called using some_client.sendThing()
Expand All @@ -39,6 +40,8 @@ export abstract class SendStuff implements IClient {
abstract halfpack: Buffer;
abstract entity: PlayerEntity;

abstract chats: Chat[];

abstract bindTCP(socket: net.Socket): void;
abstract bindWS(socket: WebSocket): void;

Expand Down
18 changes: 15 additions & 3 deletions TypescriptServer/src/cmd/senders/chat.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
import SendStuff from "#cmd/sendStuff";
import { IMessage } from "#schemas/chat";
import Chat from "#concepts/chat";
import { IMessage, messageSerialize } from "#schemas/chat";

declare module '#cmd/sendStuff' {
interface SendStuff {
sendChatMessage(chat_id:string, message:IMessage):void
sendChatHistory(chat_id:string, messages:IMessage[]):void
sendChatInfo(chat:Chat):void
sendChatsList():void
}
}

SendStuff.prototype.sendChatMessage = function(chat_id:string, message:IMessage) {
this.send({ cmd: 'chat msg', chat_id, message });
this.send({ cmd: 'chat msg', chat_id, message: messageSerialize(message) });
}

SendStuff.prototype.sendChatHistory = function(chat_id:string, messages:IMessage[]) {
this.send({ cmd: 'chat history', chat_id, history: messages });
// this.send({ cmd: 'chat history', chat_id, history: messages.map(m => ({ content: m.content, name: m.name, profile_id: null })) });
this.send({ cmd: 'chat history', chat_id, history: messages.map(messageSerialize) })
}

SendStuff.prototype.sendChatInfo = function(chat:Chat) {
this.send({ cmd: 'chat info', chat: chat.serialize() });
}

SendStuff.prototype.sendChatsList = function() {
this.send({ cmd: 'chats list', chats: this.chats.map(chat => chat.chat_id) });
}
68 changes: 41 additions & 27 deletions TypescriptServer/src/concepts/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@ export function chatFind(chat_id:string) {
return global.chats[chat_id];
}

export function chatCreate(members:IProfile[] = []) {
export function chatCreate(members:IProfile[] = [], isPrivate = false) {
let chat_id:string = getRandomId(global.chats);
if (chat_id === null) return null;

let chatlog = new ChatLog();

chatlog._id = chat_id;
chatlog.private = isPrivate;

let chat = new Chat(chatlog);


for(let member of members) {
chat.addMember(member, null, true);
}
Expand All @@ -32,6 +35,12 @@ export function chatCreate(members:IProfile[] = []) {
return chat;
}

export interface SerializedChat {
chat_id: string,
online_members: string[],
members: string[]
}

export class Chat {
chatlog: IChatLog;

Expand Down Expand Up @@ -100,6 +109,8 @@ export class Chat {

if (!client.chats.includes(this))
client.chats.push(this);

client.sendChatHistory(this.chat_id, this.messages);
}

disconnectMember(client: Client) {
Expand All @@ -112,38 +123,41 @@ export class Chat {
client.chats.splice(idx, 1);
}

writeMessage(client: Client, content: string) {
const message:IMessage = {
profile_id: client.profile.id,
name: client.name,
content
};
writeMessage(content: string, author: Client|string = 'SYSTEM') {
let name:string, profile_id:string;

// author is not logged in/anonymous
if (typeof author === 'string') {
name = author;
profile_id = null;
}
else {
name = author.name;
profile_id = author.profile?.id ?? null;
}

const message = {
name,
content,
profile_id
}

this.messages.push(message);
this.save();

// broadcast to all online users
this.online_members.forEach(
member => member.sendChatMessage(this.chat_id, message)
client => client.sendChatMessage(this.chat_id, message)
);
}

serialize():SerializedChat {
return {
chat_id: this.chat_id,
members: this.members.map(profile_id => profile_id.toString()),
online_members: this.online_members.map(client => client.name)
}
}
}

export default Chat;

// export class GlobalChat extends Chat {
// constructor() {
// // super(global.clients);
// }
// }

// export class DirectChat extends Chat {
// constructor(client1:Client, client2:Client) {
// // super([client1, client2]);
// }
// }

// export class GroupChat extends Chat {
// constructor(members: Client[]) {
// // super(members);
// }
// }
export default Chat;
17 changes: 13 additions & 4 deletions TypescriptServer/src/concepts/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export default class Client extends SendStuff implements IClient {
/** @type {Match} */
match: Match = null;

/** @type {Chat[]} */
/** @type {string[]} */
chats: Chat[] = [];


Expand Down Expand Up @@ -662,14 +662,23 @@ export default class Client extends SendStuff implements IClient {
}
}

chatLeave(chat_id: string) {
if (!this.profile)
return;

let chat = chatFind(chat_id);
if (chat) {
chat.kickMember(this.profile);
}
}

chatConnectAll() {
if (!this.profile)
return;

this.profile.chats.forEach(chat_id => {
let chat = global.chats[chat_id.toString()];
chat.connectMember(this);

let chat = chatFind(chat_id);
chat?.connectMember(this);
});
}

Expand Down
3 changes: 1 addition & 2 deletions TypescriptServer/src/initializers/00_exit_handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ async function onProcessExit(exitCode:number = undefined) {


trace('Exiting the process...');
if (this.noexit === undefined)
process.exit();
process.exit();
}

// do something when app is closing
Expand Down
10 changes: 10 additions & 0 deletions TypescriptServer/src/initializers/15_chats.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import Chat, { chatCreate } from "#concepts/chat";
import ChatLog from "#schemas/chat";

// create instances of every chat from the DB
const chatLogs = await ChatLog.find({});
chatLogs.forEach(chatlog => {
let chat = new Chat(chatlog);
global.chats[chat.chat_id] = chat;
});


// create a new id=0 "global" chat if it doesn't exist already
if (global.chats['0'] === undefined) {
let chatlog = new ChatLog();
chatlog._id = '0';

let chat = new Chat(chatlog);
global.chats['0'] = chat;
}

// chatCreate([]);
18 changes: 18 additions & 0 deletions TypescriptServer/src/schemas/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,21 @@ export interface IMessage {
content: string;
}

export interface SerializedMessage {
profile_id?: string;
name: string;
content: string;
}

// for some reason trying to msgpack.encode message with ObjectId leads to a circular reference (???)
export function messageSerialize(msg:IMessage):SerializedMessage {
return {
name: msg.name,
content: msg.content,
profile_id: msg.profile_id?.toString()
}
}

const messageSchema = new Schema<IMessage>({
profile_id: { type: Schema.Types.ObjectId, ref: 'Profile', required: false },
name: String,
Expand All @@ -19,6 +34,7 @@ const messageSchema = new Schema<IMessage>({
export interface IChatLog extends Document {
_id: string,
type: ChatType,
private: boolean,
messages: IMessage[],
members: ObjectId[]
}
Expand All @@ -27,6 +43,8 @@ export interface IChatLog extends Document {
const chatSchema = new Schema<IChatLog>({
_id: { type: String, unique: true, index: true },

private: { type: Boolean, default: false },
type: { type: String, default: 'group' },
messages: [messageSchema],
members: [
{ type: Schema.Types.ObjectId, ref: 'Profile' }
Expand Down
2 changes: 2 additions & 0 deletions TypescriptServer/src/util/names.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export class Names {
if (name.startsWith('guest')) {
return false;
}
if (name === 'system')
return false;

return true;
}
Expand Down

0 comments on commit d3ee1ce

Please sign in to comment.