From 6480a7353631a3f851a0fb000fb089a0da12a8f7 Mon Sep 17 00:00:00 2001 From: Raven Scott Date: Wed, 11 Jan 2023 01:23:20 -0500 Subject: [PATCH] Adding a new map to allow topics to remain open after a peer leaves, also added peer removal to ensure timeouts do not happen --- again.js | 199 +++++++++++++++++++++++++++++++++++++++++++++++++++++ testing.js | 176 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 375 insertions(+) create mode 100644 again.js create mode 100644 testing.js diff --git a/again.js b/again.js new file mode 100644 index 0000000..7668be8 --- /dev/null +++ b/again.js @@ -0,0 +1,199 @@ +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); diff --git a/testing.js b/testing.js new file mode 100644 index 0000000..bd31bff --- /dev/null +++ b/testing.js @@ -0,0 +1,176 @@ +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);