Skip to content

Commit d3ee1ce

Browse files
committed
chat history fix
1 parent 6a5a585 commit d3ee1ce

File tree

11 files changed

+118
-40
lines changed

11 files changed

+118
-40
lines changed

Client/scripts/chatHandlers/chatHandlers.gml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,13 @@ addHandler("chat msg", function(data) {
77
})
88

99
addHandler("chat history", function(data) {
10-
trace(data.messages)
10+
trace(data.history)
11+
})
12+
13+
addHandler("chats list", function(data) {
14+
var ids = data.chats
15+
})
16+
17+
addHandler("chat info", function(data) {
18+
trace("chat info: %", data.chat)
1119
})
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import addHandler from "#cmd/handlePacket";
2+
3+
// list of all the chats of this player
4+
addHandler('chats list', (c, data) => {
5+
c.sendChatsList();
6+
});

TypescriptServer/src/cmd/handlers/custom.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
import { addHandler } from "#cmd/handlePacket";
2-
import { PlayerInputs } from "#entities/player";
3-
import Point from "#types/point";
4-
import { clamp } from "#util/maths";
52

63
addHandler('player controls', (c, data) => {
74
if (!c.entity) return;

TypescriptServer/src/cmd/sendStuff.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import Party from '#matchmaking/party';
1313
import IClient from '#types/client_properties';
1414
import Match from '#matchmaking/match';
1515
import { ISession } from '#schemas/session';
16+
import Chat from '#concepts/chat';
1617

1718

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

43+
abstract chats: Chat[];
44+
4245
abstract bindTCP(socket: net.Socket): void;
4346
abstract bindWS(socket: WebSocket): void;
4447

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
11
import SendStuff from "#cmd/sendStuff";
2-
import { IMessage } from "#schemas/chat";
2+
import Chat from "#concepts/chat";
3+
import { IMessage, messageSerialize } from "#schemas/chat";
34

45
declare module '#cmd/sendStuff' {
56
interface SendStuff {
67
sendChatMessage(chat_id:string, message:IMessage):void
78
sendChatHistory(chat_id:string, messages:IMessage[]):void
9+
sendChatInfo(chat:Chat):void
10+
sendChatsList():void
811
}
912
}
1013

1114
SendStuff.prototype.sendChatMessage = function(chat_id:string, message:IMessage) {
12-
this.send({ cmd: 'chat msg', chat_id, message });
15+
this.send({ cmd: 'chat msg', chat_id, message: messageSerialize(message) });
1316
}
1417

1518
SendStuff.prototype.sendChatHistory = function(chat_id:string, messages:IMessage[]) {
16-
this.send({ cmd: 'chat history', chat_id, history: messages });
19+
// this.send({ cmd: 'chat history', chat_id, history: messages.map(m => ({ content: m.content, name: m.name, profile_id: null })) });
20+
this.send({ cmd: 'chat history', chat_id, history: messages.map(messageSerialize) })
21+
}
22+
23+
SendStuff.prototype.sendChatInfo = function(chat:Chat) {
24+
this.send({ cmd: 'chat info', chat: chat.serialize() });
25+
}
26+
27+
SendStuff.prototype.sendChatsList = function() {
28+
this.send({ cmd: 'chats list', chats: this.chats.map(chat => chat.chat_id) });
1729
}

TypescriptServer/src/concepts/chat.ts

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,18 @@ export function chatFind(chat_id:string) {
1313
return global.chats[chat_id];
1414
}
1515

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

2020
let chatlog = new ChatLog();
2121

2222
chatlog._id = chat_id;
23+
chatlog.private = isPrivate;
24+
2325
let chat = new Chat(chatlog);
2426

27+
2528
for(let member of members) {
2629
chat.addMember(member, null, true);
2730
}
@@ -32,6 +35,12 @@ export function chatCreate(members:IProfile[] = []) {
3235
return chat;
3336
}
3437

38+
export interface SerializedChat {
39+
chat_id: string,
40+
online_members: string[],
41+
members: string[]
42+
}
43+
3544
export class Chat {
3645
chatlog: IChatLog;
3746

@@ -100,6 +109,8 @@ export class Chat {
100109

101110
if (!client.chats.includes(this))
102111
client.chats.push(this);
112+
113+
client.sendChatHistory(this.chat_id, this.messages);
103114
}
104115

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

115-
writeMessage(client: Client, content: string) {
116-
const message:IMessage = {
117-
profile_id: client.profile.id,
118-
name: client.name,
119-
content
120-
};
126+
writeMessage(content: string, author: Client|string = 'SYSTEM') {
127+
let name:string, profile_id:string;
128+
129+
// author is not logged in/anonymous
130+
if (typeof author === 'string') {
131+
name = author;
132+
profile_id = null;
133+
}
134+
else {
135+
name = author.name;
136+
profile_id = author.profile?.id ?? null;
137+
}
138+
139+
const message = {
140+
name,
141+
content,
142+
profile_id
143+
}
144+
121145
this.messages.push(message);
122146
this.save();
123147

124148
// broadcast to all online users
125149
this.online_members.forEach(
126-
member => member.sendChatMessage(this.chat_id, message)
150+
client => client.sendChatMessage(this.chat_id, message)
127151
);
128152
}
153+
154+
serialize():SerializedChat {
155+
return {
156+
chat_id: this.chat_id,
157+
members: this.members.map(profile_id => profile_id.toString()),
158+
online_members: this.online_members.map(client => client.name)
159+
}
160+
}
129161
}
130162

131-
export default Chat;
132-
133-
// export class GlobalChat extends Chat {
134-
// constructor() {
135-
// // super(global.clients);
136-
// }
137-
// }
138-
139-
// export class DirectChat extends Chat {
140-
// constructor(client1:Client, client2:Client) {
141-
// // super([client1, client2]);
142-
// }
143-
// }
144-
145-
// export class GroupChat extends Chat {
146-
// constructor(members: Client[]) {
147-
// // super(members);
148-
// }
149-
// }
163+
export default Chat;

TypescriptServer/src/concepts/client.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export default class Client extends SendStuff implements IClient {
6262
/** @type {Match} */
6363
match: Match = null;
6464

65-
/** @type {Chat[]} */
65+
/** @type {string[]} */
6666
chats: Chat[] = [];
6767

6868

@@ -662,14 +662,23 @@ export default class Client extends SendStuff implements IClient {
662662
}
663663
}
664664

665+
chatLeave(chat_id: string) {
666+
if (!this.profile)
667+
return;
668+
669+
let chat = chatFind(chat_id);
670+
if (chat) {
671+
chat.kickMember(this.profile);
672+
}
673+
}
674+
665675
chatConnectAll() {
666676
if (!this.profile)
667677
return;
668678

669679
this.profile.chats.forEach(chat_id => {
670-
let chat = global.chats[chat_id.toString()];
671-
chat.connectMember(this);
672-
680+
let chat = chatFind(chat_id);
681+
chat?.connectMember(this);
673682
});
674683
}
675684

TypescriptServer/src/initializers/00_exit_handler.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ async function onProcessExit(exitCode:number = undefined) {
1818

1919

2020
trace('Exiting the process...');
21-
if (this.noexit === undefined)
22-
process.exit();
21+
process.exit();
2322
}
2423

2524
// do something when app is closing
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
import Chat, { chatCreate } from "#concepts/chat";
22
import ChatLog from "#schemas/chat";
33

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

1011

12+
// create a new id=0 "global" chat if it doesn't exist already
13+
if (global.chats['0'] === undefined) {
14+
let chatlog = new ChatLog();
15+
chatlog._id = '0';
16+
17+
let chat = new Chat(chatlog);
18+
global.chats['0'] = chat;
19+
}
20+
1121
// chatCreate([]);

TypescriptServer/src/schemas/chat.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,21 @@ export interface IMessage {
1010
content: string;
1111
}
1212

13+
export interface SerializedMessage {
14+
profile_id?: string;
15+
name: string;
16+
content: string;
17+
}
18+
19+
// for some reason trying to msgpack.encode message with ObjectId leads to a circular reference (???)
20+
export function messageSerialize(msg:IMessage):SerializedMessage {
21+
return {
22+
name: msg.name,
23+
content: msg.content,
24+
profile_id: msg.profile_id?.toString()
25+
}
26+
}
27+
1328
const messageSchema = new Schema<IMessage>({
1429
profile_id: { type: Schema.Types.ObjectId, ref: 'Profile', required: false },
1530
name: String,
@@ -19,6 +34,7 @@ const messageSchema = new Schema<IMessage>({
1934
export interface IChatLog extends Document {
2035
_id: string,
2136
type: ChatType,
37+
private: boolean,
2238
messages: IMessage[],
2339
members: ObjectId[]
2440
}
@@ -27,6 +43,8 @@ export interface IChatLog extends Document {
2743
const chatSchema = new Schema<IChatLog>({
2844
_id: { type: String, unique: true, index: true },
2945

46+
private: { type: Boolean, default: false },
47+
type: { type: String, default: 'group' },
3048
messages: [messageSchema],
3149
members: [
3250
{ type: Schema.Types.ObjectId, ref: 'Profile' }

0 commit comments

Comments
 (0)