2024-06-03 19:23:14 -04:00
import Hyperswarm from 'hyperswarm' ;
2024-06-08 15:34:25 -04:00
import EventEmitter from 'node:events'
2024-06-10 14:09:33 -04:00
import b4a from "b4a" ;
2024-06-03 19:23:14 -04:00
2024-06-08 15:34:25 -04:00
class Client extends EventEmitter {
2024-06-09 03:51:15 -04:00
constructor ( botName ) {
2024-06-08 15:34:25 -04:00
super ( ) ;
2024-06-10 19:49:46 -04:00
if ( ! botName ) return console . error ( "BotName is not defined!" ) ;
2024-06-03 19:23:14 -04:00
this . botName = botName ;
this . swarm = new Hyperswarm ( ) ;
this . setupSwarm ( ) ;
}
setupSwarm ( ) {
this . swarm . on ( 'connection' , ( peer ) => {
2024-06-10 14:23:59 -04:00
peer . on ( 'data' , message => {
2024-06-10 19:49:46 -04:00
const messageObj = JSON . parse ( message . toString ( ) ) ;
if ( messageObj . type === "message" ) this . emit ( 'onMessage' , peer , messageObj ) ;
if ( messageObj . type === "icon" ) this . emit ( 'onIcon' , peer , messageObj ) ;
if ( messageObj . type === "file" ) this . emit ( 'onFile' , peer , messageObj ) ;
2024-06-10 14:23:59 -04:00
} ) ;
2024-06-08 16:29:51 -04:00
peer . on ( 'error' , e => {
2024-06-08 16:31:24 -04:00
this . emit ( 'onError' , e ) ;
2024-06-08 16:29:51 -04:00
console . error ( ` Connection error: ${ e } ` )
} ) ;
2024-06-03 19:23:14 -04:00
} ) ;
this . swarm . on ( 'update' , ( ) => {
2024-06-10 13:57:32 -04:00
console . log ( ` Connections count: ${ this . swarm . connections . size } / Peers count: ${ this . swarm . peers . size } ` ) ;
2024-06-10 13:46:59 -04:00
2024-06-10 14:17:16 -04:00
this . swarm . peers . forEach ( ( peerInfo , peerId ) => {
// Please do not try to understand what is going on here. I have no idea anyway. But it surprisingly works
const peer = [ peerId ] ;
2024-06-10 14:18:33 -04:00
const peerTopics = [ peerInfo . topics ]
2024-06-10 19:49:46 -04:00
. filter ( topics => topics )
. map ( topics => topics . map ( topic => b4a . toString ( topic , 'hex' ) ) ) ;
2024-06-10 13:46:59 -04:00
} ) ;
2024-06-03 19:23:14 -04:00
} ) ;
}
2024-06-09 03:51:15 -04:00
joinChatRoom ( chatRoomID ) {
2024-06-10 19:49:46 -04:00
this . discovery = this . swarm . join ( Buffer . from ( chatRoomID , 'hex' ) , { client : true , server : true } ) ;
2024-06-03 19:23:14 -04:00
this . discovery . flushed ( ) . then ( ( ) => {
console . log ( ` Bot ${ this . botName } joined the chat room. ` ) ;
2024-06-08 16:36:00 -04:00
this . emit ( 'onBotJoinRoom' ) ;
2024-06-03 19:23:14 -04:00
} ) ;
}
2024-06-09 15:55:32 -04:00
sendMessage ( roomPeers , message ) {
2024-06-03 19:23:14 -04:00
console . log ( 'Bot name:' , this . botName ) ;
const timestamp = Date . now ( ) ; // Generate timestamp
2024-06-10 19:49:46 -04:00
const messageObj = {
type : 'message' , // Add type field
name : this . botName ,
message ,
timestamp
} ;
const data = JSON . stringify ( messageObj ) ;
const peers = [ ... this . swarm . connections ] . filter ( peer => roomPeers . includes ( peer . remotePublicKey . toString ( 'hex' ) ) ) ; // We remove all the peers that aren't included in a room
2024-06-10 10:28:18 -04:00
for ( const peer of peers ) peer . write ( data ) ;
}
sendMessageToAll ( message ) {
console . log ( 'Bot name:' , this . botName ) ;
const timestamp = Date . now ( ) ; // Generate timestamp
2024-06-10 19:49:46 -04:00
const messageObj = {
type : 'message' , // Add type field
name : this . botName ,
message ,
timestamp
} ;
const data = JSON . stringify ( messageObj ) ;
const peers = [ ... this . swarm . connections ] ;
2024-06-03 19:23:14 -04:00
for ( const peer of peers ) peer . write ( data ) ;
}
destroy ( ) {
this . swarm . destroy ( ) ;
console . log ( ` Bot ${ this . botName } disconnected. ` ) ;
}
}
2024-06-08 16:31:24 -04:00
export default Client ;