Adding a new map to allow topics to remain open after a peer leaves, also added peer removal to ensure timeouts do not happen

This commit is contained in:
Raven Scott 2023-01-11 01:24:08 -05:00
parent 6480a73536
commit cc49b165b0
3 changed files with 105 additions and 446 deletions

199
again.js
View File

@ -1,199 +0,0 @@
const Discord = require('discord.js');
const Hyperswarm = require('hyperswarm');
const crypto = require('hypercore-crypto');
const { Client, GatewayIntentBits, Partials, messageLink } = require("discord.js");
const goodbye = require('graceful-goodbye')
require('dotenv').config()
const b4a = require('b4a')
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
const client = new Client({
'intents': [
GatewayIntentBits.DirectMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildBans,
GatewayIntentBits.GuildMessages
],
'partials': [Partials.Channel, Partials.Message, Partials.MessageContent]
});
const topicMap = new Map();
const swarmMap = new Map();
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('messageCreate', msg => {
if (msg.content.startsWith("!") && !msg.author.bot) {
const args = msg.content.split(" ");
const cmd = args.shift().slice(1);
if (cmd === "current") {
if (topicMap.has(msg.channel.id)) {
let topic_obj = topicMap.get(msg.channel.id);
msg.reply(`The current topic for this channel is: ${topic_obj.topic.toString('hex')}`);
}
else {
msg.reply(`No topic is assigned for this channel`);
}
}
if (cmd === "join-topic") {
if (!args[0]) {
msg.reply("Please provide a new topic in hexadecimal format");
return;
}
let topic = crypto.randomBytes(32);
let channel_id = args[1];
if (!channel_id) {
msg.reply("Please provide a channel_id to send this topic's messages")
return;
}
//Check if the given channel_id exists or not.
if (!client.channels.cache.get(channel_id)) {
msg.reply("The provided channel id does not exist.");
return;
}
let swarm;
let conns = [];
if (topicMap.has(channel_id)) {
topic_obj = topicMap.get(channel_id);
swarm = topic_obj.swarm;
conns = topic_obj.conns;
}
else {
swarm = new Hyperswarm();
topicMap.set(channel_id, { topic: topic, swarm: swarm, conns: conns });
// Join the new topic
swarm.join(topic, {
lookup: true,
announce: true,
timeout: 60000
});
swarm.on('connection', (conn, info) => {
console.log(`Connected to a peer`);
conns.push(conn);
conn.on('data', data => {
// Send the message from the topic to the Discord channel
client.channels.fetch(channel_id).then(channel => channel.send(data.toString()))
});
conn.on('close', () => clearInterval(checkInactiveInterval))
});
client.channels.fetch(channel_id).then(channel => {
msg.reply(`Successfully joined topic and sending messages to ${channel}`);
});
}
}
if (cmd === "set") {
let channel_id = msg.channel.id;
//Check if the given channel_id exists or not.
if (!client.channels.cache.get(channel_id)) {
msg.reply("The provided channel id does not exist.");
return;
}
let topic = crypto.randomBytes(32);
let swarm;
let conns = [];
if (topicMap.has(channel_id)) {
topic_obj = topicMap.get(channel_id);
conns = topic_obj.conns;
}
else {
topicMap.set(channel_id, { topic: topic, conns: conns });
}
if (!swarmMap.has(topic)) {
swarm = new Hyperswarm();
swarmMap.set(topic, swarm);
// Join the new topic
swarm.join(topic, {
lookup: true,
announce: true,
timeout: 60000
});
swarm.on('connection', (conn, info) => {
console.log(`Connected to a peer for topic ${topic.toString('hex')}`);
conns.push(conn);
conn.on('data', data => {
console.log(data.toString())
if (data.toString().startsWith('CLOSED:')) {
// Extract the key from the message string
const key = data.toString().split(':')[1].trim();
// Iterate through the conns array and remove the client with the matching key
console.log(`Removing peer ${key}`);
(async () => {
await sleep(5000)
conns = conns.filter(c => c !== conn);
conn.destroy();
})();
} else {
client.channels.fetch(channel_id).then(channel => channel.send(data.toString()))
}
});
});
client.channels.fetch(channel_id).then(channel => {
msg.reply(`Successfully joined topic and sending messages to ${channel}`);
});
} else {
swarm = swarmMap.get(topic);
swarm.join(topic, {
lookup: true,
announce: true,
timeout: 60000
});
client.channels.fetch(channel_id).then(channel => {
msg.reply(`Successfully joined topic and sending messages to ${channel}`);
});
}
}
if (cmd === "leave-topic") {
let channel_id = msg.channel.id;
let topic_obj = topicMap.get(channel_id);
if (topic_obj) {
topic_obj.swarm.leave(topic_obj.topic);
topicMap.delete(channel_id);
return msg.reply(`Successfully left topic ${topic_obj.topic.toString('hex')} for channel ${channel_id}`);
} else {
return msg.reply(`No topic is assigned for this channel`);
}
}
}
// Check if message is sent in a channel with a topic assigned and send it to the topic
if (topicMap.has(msg.channel.id) && !msg.author.bot) {
let topic_obj = topicMap.get(msg.channel.id);
let conns = topic_obj.conns;
for (const conn of conns) {
conn.write(`${msg.author.username}(Discord): ${msg.content}`);
}
}
});
client.login(process.env.TOKEN);

98
bot.js
View File

@ -4,6 +4,13 @@ const crypto = require('hypercore-crypto');
const { Client, GatewayIntentBits, Partials, messageLink } = require("discord.js"); const { Client, GatewayIntentBits, Partials, messageLink } = require("discord.js");
const goodbye = require('graceful-goodbye') const goodbye = require('graceful-goodbye')
require('dotenv').config() require('dotenv').config()
const b4a = require('b4a')
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
const client = new Client({ const client = new Client({
'intents': [ 'intents': [
@ -17,13 +24,11 @@ const client = new Client({
'partials': [Partials.Channel, Partials.Message, Partials.MessageContent] 'partials': [Partials.Channel, Partials.Message, Partials.MessageContent]
}); });
const topicMap = new Map(); const topicMap = new Map();
goodbye(() => { const swarmMap = new Map();
for(let [channel_id, topic_obj] of topicMap)
{
topic_obj.swarm.destroy();
}
})
client.on('ready', () => { client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`); console.log(`Logged in as ${client.user.tag}!`);
@ -35,9 +40,8 @@ client.on('messageCreate', msg => {
const args = msg.content.split(" "); const args = msg.content.split(" ");
const cmd = args.shift().slice(1); const cmd = args.shift().slice(1);
if (cmd === "current-topic") { if (cmd === "current") {
if(topicMap.has(msg.channel.id)) if (topicMap.has(msg.channel.id)) {
{
let topic_obj = topicMap.get(msg.channel.id); let topic_obj = topicMap.get(msg.channel.id);
msg.reply(`The current topic for this channel is: ${topic_obj.topic.toString('hex')}`); msg.reply(`The current topic for this channel is: ${topic_obj.topic.toString('hex')}`);
} }
@ -53,43 +57,44 @@ client.on('messageCreate', msg => {
} }
let topic = crypto.randomBytes(32); let topic = crypto.randomBytes(32);
let channel_id = args[1]; let channel_id = args[1];
if(!channel_id) if (!channel_id) {
{
msg.reply("Please provide a channel_id to send this topic's messages") msg.reply("Please provide a channel_id to send this topic's messages")
return; return;
} }
//Check if the given channel_id exists or not. //Check if the given channel_id exists or not.
if(!client.channels.cache.get(channel_id)) if (!client.channels.cache.get(channel_id)) {
{
msg.reply("The provided channel id does not exist."); msg.reply("The provided channel id does not exist.");
return; return;
} }
let swarm; let swarm;
let conns = []; let conns = [];
if(topicMap.has(channel_id)) if (topicMap.has(channel_id)) {
{
topic_obj = topicMap.get(channel_id); topic_obj = topicMap.get(channel_id);
swarm = topic_obj.swarm; swarm = topic_obj.swarm;
conns = topic_obj.conns; conns = topic_obj.conns;
} }
else else {
{
swarm = new Hyperswarm(); swarm = new Hyperswarm();
topicMap.set(channel_id, { topic: topic, swarm: swarm, conns: conns }); topicMap.set(channel_id, { topic: topic, swarm: swarm, conns: conns });
// Join the new topic // Join the new topic
swarm.join(topic, { swarm.join(topic, {
lookup: true, lookup: true,
announce: true, announce: true,
timeout: 30000 timeout: 60000
}); });
swarm.on('connection', (conn, info) => { swarm.on('connection', (conn, info) => {
console.log(`Connected to a peer for topic ${topic.toString('hex')}`); console.log(`Connected to a peer`);
conns.push(conn); conns.push(conn);
conn.on('data', data => { conn.on('data', data => {
// Send the message from the topic to the Discord channel // Send the message from the topic to the Discord channel
client.channels.fetch(channel_id).then(channel => channel.send(data.toString())) client.channels.fetch(channel_id).then(channel => channel.send(data.toString()))
}); });
conn.on('close', () => clearInterval(checkInactiveInterval))
}); });
client.channels.fetch(channel_id).then(channel => { client.channels.fetch(channel_id).then(channel => {
msg.reply(`Successfully joined topic and sending messages to ${channel}`); msg.reply(`Successfully joined topic and sending messages to ${channel}`);
@ -98,47 +103,75 @@ client.on('messageCreate', msg => {
} }
} }
if (cmd === "set-topic") { if (cmd === "set") {
let channel_id = msg.channel.id; let channel_id = msg.channel.id;
//Check if the given channel_id exists or not. //Check if the given channel_id exists or not.
if(!client.channels.cache.get(channel_id)) if (!client.channels.cache.get(channel_id)) {
{
msg.reply("The provided channel id does not exist."); msg.reply("The provided channel id does not exist.");
return; return;
} }
let topic = crypto.randomBytes(32); let topic = crypto.randomBytes(32);
let swarm; let swarm;
let conns = []; let conns = [];
if(topicMap.has(channel_id)) if (topicMap.has(channel_id)) {
{
topic_obj = topicMap.get(channel_id); topic_obj = topicMap.get(channel_id);
topic_obj.swarm.leave(topic_obj.topic);
topic_obj.topic = topic;
swarm = topic_obj.swarm;
conns = topic_obj.conns; conns = topic_obj.conns;
} }
else { else {
topicMap.set(channel_id, { topic: topic, conns: conns });
}
if (!swarmMap.has(topic)) {
swarm = new Hyperswarm(); swarm = new Hyperswarm();
conns = []; swarmMap.set(topic, swarm);
topicMap.set(channel_id, {topic: topic, swarm: swarm, conns: conns});
// Join the new topic // Join the new topic
swarm.join(topic, { swarm.join(topic, {
lookup: true, lookup: true,
announce: true, announce: true,
timeout: 30000 timeout: 60000
}); });
swarm.on('connection', (conn, info) => { swarm.on('connection', (conn, info) => {
console.log(`Connected to a peer for topic ${topic.toString('hex')}`); console.log(`Connected to a peer for topic ${topic.toString('hex')}`);
conns.push(conn); conns.push(conn);
conn.on('data', data => { conn.on('data', data => {
// Send the message from the topic to the Discord channel console.log(data.toString())
if (data.toString().startsWith('CLOSED:')) {
// Extract the key from the message string
const key = data.toString().split(':')[1].trim();
// Iterate through the conns array and remove the client with the matching key
console.log(`Removing peer ${key}`);
(async () => {
await sleep(5000)
conns = conns.filter(c => c !== conn);
conn.destroy();
})();
} else {
client.channels.fetch(channel_id).then(channel => channel.send(data.toString())) client.channels.fetch(channel_id).then(channel => channel.send(data.toString()))
}
}); });
}); });
client.channels.fetch(channel_id).then(channel => {
msg.reply(`Successfully joined topic and sending messages to ${channel}`);
});
} else {
swarm = swarmMap.get(topic);
swarm.join(topic, {
lookup: true,
announce: true,
timeout: 60000
});
client.channels.fetch(channel_id).then(channel => {
msg.reply(`Successfully joined topic and sending messages to ${channel}`);
});
} }
msg.reply(`Successfully set topic ${topic.toString('hex')} for channel ${channel_id}`);
} }
if (cmd === "leave-topic") { if (cmd === "leave-topic") {
let channel_id = msg.channel.id; let channel_id = msg.channel.id;
let topic_obj = topicMap.get(channel_id); let topic_obj = topicMap.get(channel_id);
@ -157,6 +190,7 @@ client.on('messageCreate', msg => {
let topic_obj = topicMap.get(msg.channel.id); let topic_obj = topicMap.get(msg.channel.id);
let conns = topic_obj.conns; let conns = topic_obj.conns;
for (const conn of conns) { for (const conn of conns) {
conn.write(`${msg.author.username}(Discord): ${msg.content}`); conn.write(`${msg.author.username}(Discord): ${msg.content}`);
} }
} }

View File

@ -1,176 +0,0 @@
const Discord = require('discord.js');
const Hyperswarm = require('hyperswarm');
const crypto = require('hypercore-crypto');
const { Client, GatewayIntentBits, Partials, messageLink } = require("discord.js");
require('dotenv').config()
const client = new Client({
'intents': [
GatewayIntentBits.DirectMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildBans,
GatewayIntentBits.GuildMessages
],
'partials': [Partials.Channel, Partials.Message, Partials.MessageContent]
});
const topicMap = new Map();
const swarmMap = new Map();
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('messageCreate', msg => {
if (msg.content.startsWith("!") && !msg.author.bot) {
const args = msg.content.split(" ");
const cmd = args.shift().slice(1);
if (cmd === "current-topic") {
if (topicMap.has(msg.channel.id)) {
let topic_obj = topicMap.get(msg.channel.id);
msg.reply(`The current topic for this channel is: ${topic_obj.topic.toString('hex')}`);
}
else {
msg.reply(`No topic is assigned for this channel`);
}
}
if (cmd === "join-topic") {
if (!args[0]) {
msg.reply("Please provide a new topic in hexadecimal format");
return;
}
let topic = crypto.randomBytes(32);
let channel_id = args[1];
if (!channel_id) {
msg.reply("Please provide a channel_id to send this topic's messages")
return;
}
//Check if the given channel_id exists or not.
if (!client.channels.cache.get(channel_id)) {
msg.reply("The provided channel id does not exist.");
return;
}
let conns = [];
if (topicMap.has(channel_id)) {
topic_obj = topicMap.get(channel_id);
topic = topic_obj.topic;
conns = topic_obj.conns;
}
else {
topicMap.set(channel_id, { topic: topic, conns: conns });
}
if (!swarmMap.has(topic.toString('hex'))) {
let swarm = new Hyperswarm();
swarmMap.set(topic.toString('hex'), swarm);
// Join the new topic
swarm.join(topic, {
lookup: true,
announce: true,
timeout: 30000
});
swarm.on('connection', (conn, info) => {
console.log(`Connected to a peer for topic ${topic.toString('hex')}`);
conns.push(conn);
conn.on('data', data => {
// Send the message from the topic to the Discord channel
client.channels.fetch(channel_id).then(channel => channel.send(data.toString()))
});
});
client.channels.fetch(channel_id).then(channel => {
msg.reply(`Successfully joined topic and sending messages to ${channel}`);
});
} else {
let swarm = swarmMap.get(topic.toString('hex'));
swarm.join(topic, {
lookup: true,
announce: true,
timeout: 30000
});
client.channels.fetch(channel_id).then(channel => {
msg.reply(`Successfully joined topic and sending messages to ${channel}`);
});
}
}
if (cmd === "set-topic") {
let channel_id = msg.channel.id;
//Check if the given channel_id exists or not.
if (!client.channels.cache.get(channel_id)) {
msg.reply("The provided channel id does not exist.");
return;
}
let topic = crypto.randomBytes(32);
let swarm;
let conns = [];
if (topicMap.has(channel_id)) {
topic_obj = topicMap.get(channel_id);
conns = topic_obj.conns;
}
else {
topicMap.set(channel_id, { topic: topic, conns: conns });
}
if (!swarmMap.has(topic)) {
swarm = new Hyperswarm();
swarmMap.set(topic, swarm);
// Join the new topic
swarm.join(topic, {
lookup: true,
announce: true,
timeout: 30000
});
swarm.on('connection', (conn, info) => {
console.log(`Connected to a peer for topic ${topic}`);
conns.push(conn);
conn.on('data', data => {
// Send the message from the topic to the Discord channel
client.channels.fetch(channel_id).then(channel => channel.send(data.toString()))
});
});
client.channels.fetch(channel_id).then(channel => {
msg.reply(`Successfully joined topic and sending messages to ${channel}`);
});
} else {
swarm = swarmMap.get(topic);
swarm.join(topic, {
lookup: true,
announce: true,
timeout: 30000
});
client.channels.fetch(channel_id).then(channel => {
msg.reply(`Successfully joined topic and sending messages to ${channel}`);
});
}
}
if (cmd === "leave-topic") {
let channel_id = msg.channel.id;
let topic_obj = topicMap.get(channel_id);
if (topic_obj) {
topic_obj.swarm.leave(topic_obj.topic);
topicMap.delete(channel_id);
return msg.reply(`Successfully left topic ${topic_obj.topic.toString('hex')} for channel ${channel_id}`);
} else {
return msg.reply(`No topic is assigned for this channel`);
}
}
if (topicMap.has(msg.channel.id) && !msg.author.bot) {
let topic_obj = topicMap.get(msg.channel.id);
let conns = topic_obj.conns;
for (const conn of conns) {
conn.write(`${msg.author.username}(Discord): ${msg.content}`);
}
}
}
});
client.login(process.env.TOKEN);