Use per-client channel and message ids

Fixes #2341
This commit is contained in:
Pavel Djundik 2018-04-27 13:16:23 +03:00
parent 92c4df6e9c
commit bf8a16b7fe
14 changed files with 50 additions and 32 deletions

View file

@ -70,6 +70,8 @@ function Client(manager, name, config = {}) {
attachedClients: {},
config: config,
id: uuidv4(),
idChan: 1,
idMsg: 1,
name: name,
networks: [],
sockets: manager.sockets,
@ -80,7 +82,7 @@ function Client(manager, name, config = {}) {
let delay = 0;
if (!Helper.config.public) {
client.messageStorage = new MessageStorage();
client.messageStorage = new MessageStorage(client);
if (client.config.log && Helper.config.messageStorage.includes("sqlite")) {
client.messageStorage.enable(client.name);
@ -109,6 +111,13 @@ function Client(manager, name, config = {}) {
}
}
Client.prototype.createChannel = function(attr) {
const chan = new Chan(attr);
chan.id = this.idChan++;
return chan;
};
Client.prototype.emit = function(event, data) {
if (this.sockets !== null) {
this.sockets.in(this.id).emit(event, data);
@ -140,6 +149,9 @@ Client.prototype.connect = function(args) {
const client = this;
let channels = [];
// Get channel id for lobby before creating other channels for nicer ids
const lobbyChannelId = client.idChan++;
if (args.channels) {
let badName = false;
@ -149,7 +161,7 @@ Client.prototype.connect = function(args) {
return;
}
channels.push(new Chan({
channels.push(client.createChannel({
name: chan.name,
key: chan.key || "",
type: chan.type,
@ -166,7 +178,7 @@ Client.prototype.connect = function(args) {
.replace(/,/g, " ")
.split(/\s+/g)
.map(function(chan) {
return new Chan({
return client.createChannel({
name: chan,
});
});
@ -189,6 +201,9 @@ Client.prototype.connect = function(args) {
channels: channels,
});
// Set network lobby channel id
network.channels[0].id = lobbyChannelId;
client.networks.push(network);
client.emit("network", {
networks: [network.getFilteredClone(this.lastActiveChannel, -1)],

View file

@ -20,11 +20,9 @@ Chan.State = {
JOINED: 1,
};
let id = 1;
function Chan(attr) {
_.defaults(this, attr, {
id: id++,
id: 0,
messages: [],
name: "",
key: "",
@ -46,6 +44,8 @@ Chan.prototype.pushMessage = function(client, msg, increasesUnread) {
const chan = this.id;
const obj = {chan, msg};
msg.id = client.idMsg++;
// If this channel is open in any of the clients, do not increase unread counter
const isOpen = _.find(client.attachedClients, {openChannel: chan}) !== undefined;

View file

@ -2,8 +2,6 @@
const _ = require("lodash");
let id = 0;
class Msg {
constructor(attr) {
// Some properties need to be copied in the Msg object instead of referenced
@ -20,7 +18,7 @@ class Msg {
_.defaults(this, attr, {
from: {},
id: id++,
id: 0,
previews: [],
text: "",
type: Msg.Type.MESSAGE,

View file

@ -43,7 +43,7 @@ exports.input = function(network, chan, cmd, args) {
}
}
const newChan = new Chan({
const newChan = this.createChannel({
type: Chan.Type.QUERY,
name: target,
});

View file

@ -33,7 +33,7 @@ module.exports = function(irc, network) {
let chan = network.getChannel(chanName);
if (typeof chan === "undefined") {
chan = new Chan({
chan = client.createChannel({
type: Chan.Type.SPECIAL,
name: chanName,
});

View file

@ -8,14 +8,6 @@ module.exports = function(irc, network) {
// If server supports CHGHOST cap, then changing the hostname does not require
// sending PART and JOIN, which means less work for us over all
irc.on("user updated", function(data) {
const msg = new Msg({
time: data.time,
type: Msg.Type.CHGHOST,
new_ident: data.ident !== data.new_ident ? data.new_ident : "",
new_host: data.hostname !== data.new_host ? data.new_host : "",
self: data.nick === irc.user.nick,
});
network.channels.forEach((chan) => {
const user = chan.findUser(data.nick);
@ -23,7 +15,14 @@ module.exports = function(irc, network) {
return;
}
msg.from = user;
const msg = new Msg({
time: data.time,
type: Msg.Type.CHGHOST,
new_ident: data.ident !== data.new_ident ? data.new_ident : "",
new_host: data.hostname !== data.new_host ? data.new_host : "",
self: data.nick === irc.user.nick,
from: user,
});
chan.pushMessage(client, msg);
});

View file

@ -11,7 +11,7 @@ module.exports = function(irc, network) {
let chan = network.getChannel(data.channel);
if (typeof chan === "undefined") {
chan = new Chan({
chan = client.createChannel({
name: data.channel,
state: Chan.State.JOINED,
});

View file

@ -42,7 +42,7 @@ module.exports = function(irc, network) {
let chan = network.getChannel("Channel List");
if (typeof chan === "undefined") {
chan = new Chan({
chan = client.createChannel({
type: Chan.Type.SPECIAL,
name: "Channel List",
});

View file

@ -63,7 +63,7 @@ module.exports = function(irc, network) {
showInActive = true;
chan = network.channels[0];
} else {
chan = new Chan({
chan = client.createChannel({
type: Chan.Type.QUERY,
name: target,
});

View file

@ -6,14 +6,13 @@ module.exports = function(irc, network) {
const client = this;
irc.on("nick", function(data) {
let msg;
const self = data.nick === irc.user.nick;
if (self) {
network.setNick(data.new_nick);
const lobby = network.channels[0];
msg = new Msg({
const msg = new Msg({
text: `You're now known as ${data.new_nick}`,
});
lobby.pushMessage(client, msg, true);
@ -32,7 +31,7 @@ module.exports = function(irc, network) {
return;
}
msg = new Msg({
const msg = new Msg({
time: data.time,
from: user,
type: Msg.Type.NICK,

View file

@ -9,7 +9,7 @@ module.exports = function(irc, network) {
let chan = network.getChannel(data.nick);
if (typeof chan === "undefined") {
chan = new Chan({
chan = client.createChannel({
type: Chan.Type.QUERY,
name: data.nick,
});

View file

@ -17,7 +17,8 @@ const schema = [
];
class MessageStorage {
constructor() {
constructor(client) {
this.client = client;
this.isEnabled = false;
}
@ -133,7 +134,10 @@ class MessageStorage {
msg.time = row.time;
msg.type = row.type;
return new Msg(msg);
const newMsg = new Msg(msg);
newMsg.id = this.client.idMsg++;
return newMsg;
}).reverse());
}
));

View file

@ -29,8 +29,9 @@ describe("Chan", function() {
describe("#findMessage(id)", function() {
const chan = new Chan({
messages: [
new Msg(),
new Msg({id: 1}),
new Msg({
id: 2,
text: "Message to be found",
}),
new Msg(),
@ -38,7 +39,7 @@ describe("Chan", function() {
});
it("should find a message in the list of messages", function() {
expect(chan.findMessage(1).text).to.equal("Message to be found");
expect(chan.findMessage(2).text).to.equal("Message to be found");
});
it("should not find a message that does not exist", function() {

View file

@ -13,7 +13,9 @@ describe("SQLite Message Storage", function() {
// Delete database file from previous test run
before(function(done) {
store = new MessageStorage();
store = new MessageStorage({
idMsg: 1,
});
if (fs.existsSync(expectedPath)) {
fs.unlink(expectedPath, done);