deekchat_renachan/client.js

979 lines
21 KiB
JavaScript
Executable File

const fs = require("fs");
const websocket = require("ws");
const fetch = require("node-fetch");
const formdata = require("form-data");
const he = require("he");
const cheerio = require("cheerio");
const ddg = require("duckduckgo-images-api");
const yt = require("ytsr");
var mmm = require("mmmagic");
var Magic = mmm.Magic;
const emitter = require("events");
const deek = new emitter();
const name = "rena_chan";
const password = "renachanlovesyou";
const userid = 12;
var channels = [];
var ws = [];
var ddg_cache = [];
var ddg_mod = true; // dont show porn in .img
var global_page = 1; // .img page
var raid = false; // raid?
var img_headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/110.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate",
"DNT": "1",
"Connection": "keep-alive"
};
var headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0",
Origin: "https://deek.chat"
};
/*
Helper functions
*/
async function getmime(file){
return new Promise(function(resolve, reject){
var magic = new Magic(mmm.MAGIC_MIME_TYPE);
magic.detect(file, function(err, result){
if(err){
resolve([
"image/png",
"png",
false
]);
}else{
resolve([
result,
result.split("/")[1],
true
]);
}
});
});
}
function removehtml(html){
return he.decode(html.replace(/<[^>]+>/ig,""));
};
async function serveddg(msg, results, page){
page--;
try{
var res = await fetch(
results[page].image,
{headers: img_headers}
);
var res_get = await res.buffer();
var m = await getmime(res_get);
if(
m[2] === false ||
m[0].split("/")[0] != "image"
){
var res = await fetch(
results[page].thumbnail,
{headers: img_headers}
);
var res_get = await res.buffer();
}
}catch(err){
var res = await fetch(
results[page].thumbnail,
{headers: img_headers}
);
var res_get = await res.buffer();
}
send(
msg,
"Page " + (page + 1) + "/" + (results.length) + "\n[" + results[page].width + "x" + results[page].height + "] " + results[page].title + "\n" + results[page].url,
res_get
);
}
/*
Websocket functions
*/
async function send(channel, text, file = null){
if(typeof channel == "object"){
channel = channel.channel;
}
for(var i=0; i<channels.length; i++){
if(channels[i].id === channel){
var arraypos = i;
break;
}
}
if(file === null){
channels[arraypos].ws.send(JSON.stringify({
type: "messageEnd",
data: {
message: text
}
}));
return;
}
/*
Send file
*/
var mimetype = await getmime(file);
var form_data = new formdata();
form_data.append("text", text);
form_data.append(
"files[]",
file,
{
contentType: mimetype[0],
name: "file",
filename: "file." + mimetype[1]
}
);
var headers_copy = headers;
headers_copy["Content-Type"] = form_data.getHeaders()["content-type"];
fetch("https://deek.chat/message/send/" + channel, {
method: 'POST',
body: form_data,
headers: headers_copy
})
}
/*
Handshake
*/
async function handshake(name, password){
/*
Get cookie
*/
console.log("logging in as " + name);
const form = new formdata();
form.append("name", name);
form.append("password", password);
form.append("submit", "log+in");
try{
var login = await fetch(
"https://deek.chat/login/submit",
{
method: "POST",
redirect: "manual",
body: form,
headers: headers
}
);
}catch(err){
console.log("Could not login. Trying again in 10 seconds...");
setTimeout(function(){
fs.utimesSync(__filename, Date.now(), Date.now());
}, 10000);
return;
}
var cookie = await login.headers.get("set-cookie");
var api_token = cookie.match(/api_token=([^;]+)/);
var session_id = cookie.match(/session_id=([^;]+)/);
if(
typeof api_token[1] != "string" ||
typeof session_id[1] != "string"
){
deek.emit("error", "Could not get api_token or session_id !!");
return;
}
headers.cookie = "session_id=" + session_id[1] + "; api_token=" + api_token[1];
/*
Scrape channel list
*/
console.log("getting subscribed channels");
var subscribed = await fetch(
"https://deek.chat/rooms/fetch/subscribed",
{
method: "GET",
headers: headers
}
);
var res = await subscribed.buffer();
res = JSON.parse(res.toString("utf8"));
shittierloop:
for(var i=0; i<res.length; i++){
for(var k=0; k<channels.length; k++){
if(channels[k].id === res[i].room.id){
continue shittierloop;
}
}
channels.push({
name: res[i].room.name,
id: res[i].room.id,
users: []
});
}
for(var i=0; i<channels.length; i++){
/*
Scrape users
*/
console.log("getting users for " + channels[i].name + " (id:" + channels[i].id + ")");
var users = await fetch(
"https://deek.chat/users/" + channels[i].id,
{
method: "GET",
headers: headers
}
);
var res = await users.buffer();
res = JSON.parse(res.toString("utf8"));
if(res === null){
res = [];
}
for(var k=0; k<res.length; k++){
channels[i].users.push({
name: res[k].name,
id: res[k].id,
country: {
name: res[k].countryName,
code: res[k].countryIso.toUpperCase()
},
picture: res[k].profilePicture == "" ? null : "https://deek.chat/storage/profilePictures/" + res[k].profilePicture
});
}
/*
Connect to websocket serbers
*/
channels[i].ws = new websocket(
"wss://deek.chat/ws/" + channels[i].id,
{
protocolVersion: 13,
encoding: "utf8",
headers: headers
}
);
var pass = i;
channels[i].ws.once("open", function(){
deek.emit("login", channels[pass]);
});
channels[i].ws.once("close", function(){
deek.emit("close", channels[pass]);
});
channels[i].ws.on("message", function(message, isbin){
if(isbin){ return; }
var m = JSON.parse(message.toString("utf8"));
if(typeof m.type == "undefined"){
return;
}
switch(m.type){
case "messageEnd":
for(var k=0; k<m.data.message.mentions.length; k++){
m.data.message.mentions[k].id = m.data.message.mentions[k].userId;
delete m.data.message.mentions[k].userId;
}
for(var k=0; k<m.data.message.replies.length; k++){
m.data.message.replies[k].id = m.data.message.replies[k].userId;
m.data.message.replies[k].message = m.data.message.replies[k].replyMessageId;
delete m.data.message.replies[k].userId;
delete m.data.message.replies[k].replyMessageId;
}
m.data.message.files = m.data.message.files === null ? [] : m.data.message.files;
var files = [];
for(var k=0; k<m.data.message.files.length; k++){
files.push("https://deek.chat/storage/files/" + m.data.message.files[k].name);
}
deek.emit(
"message",
{
text: removehtml(m.data.message.text),
id: m.data.message.id,
files: files,
mentions: m.data.message.mentions,
replies: m.data.message.replies,
channel: m.roomId
},
{
name: m.data.message.name,
id: m.userId,
picture: m.data.message.profilePicture == "" ? null : "https://deek.chat/storage/profilePictures/" + m.data.message.profilePicture
}
);
break;
case "files":
m.message.files = m.message.files === null ? [] : m.message.files;
var files = [];
for(var k=0; k<m.message.files.length; k++){
files.push("https://deek.chat/storage/files/" + m.message.files[k].name);
}
deek.emit(
"message",
{
text: removehtml(m.message.text),
id: m.message.id,
files: files,
mentions: m.message.mentions,
replies: m.message.replies,
channel: m.roomId
},
{
name: m.message.name == "" ? null : m.message.name,
id: m.userId,
picture: m.message.profilePicture == "" ? null : "https://deek.chat/storage/profilePictures/" + m.message.profilePicture
}
);
break;
default:
//console.warn(m);
break;
}
});
}
}
/*
User defined FUN-ctions!!!
*/
deek.on("login", function(channel){
console.log("connected to channel " + channel.name + " (id:" + channel.id + ")");
});
deek.on("message", async function(msg, user){
if(
(
user.id === 13 ||
raid === false
) === false
){
return;
}
if(
user.id === userid ||
user.name == name
){
return;
}
switch(msg.text.toLowerCase()){
case "hello rena":
case "hi rena":
case "what's up rena":
case "whats up rena":
send(msg, "hi " + user.name);
return;
case "/help":
send(msg, "lmao newfag");
break;
}
/*
shitty embed support
*/
if(link = msg.text.match(/https?:\/\/[^ \n\r'>]+/)){
link = link[0];
try{
if(tweet = link.match(/https?:\/\/(?:www\.)?twitter\.com\/[A-Za-z0-9_]+\/status\/([0-9]+)/)){
tweet = tweet[1];
var res = await fetch("https://cdn.syndication.twimg.com/tweet-result?id=" + tweet);
var json = await res.json();
var title = json.user.name + " (@" + json.user.screen_name + ") " + " on twatter";
var description = json.text;
}else{
var res = await fetch(
link,
{headers: img_headers}
);
var headers_arr = [...res.headers];
var headers = [];
for(i=0; i<headers_arr.length; i++){
headers[headers_arr[i][0]] = headers_arr[i][1];
}
if(
!headers["content-type"] ||
headers["content-type"].split(";")[0] != "text/html" ||
(
!headers["content-length"] &&
parseInt(headers["content-length"]) > 10485760 // 10MB
)
){
var text = "This thingy^ ";
if(headers["content-type"]){
var format = headers["content-type"].split("/");
format = format[format.length - 1].split(";")[0];
text += "is a " + format + " file ";
}else{
text += "is uhh... something.. err.. "
}
if(headers["content-length"]){
var filesize = Math.round(parseInt(headers["content-length"]) / 1048576);
text += "that weighs " + (Math.round(parseInt(headers["content-length"]) / 1048576)) + "MB!!";
}else{
text += "that uhh weighs something probably idk!!!";
}
text += " lol thats all i know fuck you";
send(msg, text);
return;
}
// cancerous code ahead
var buffer = await res.buffer();
const parser = cheerio.load(buffer);
// get title
var title = "Unknown title lol, shit website";
var tag_title = parser("title");
var tag_name_og_title = parser("meta[name='og:title']");
var tag_property_og_title = parser("meta[property='og:title']");
if(tag_title.length !== 0){ title = tag_title.text(); }
if(tag_name_og_title.length !== 0){ title = tag_name_og_title.attr("content"); }
if(tag_property_og_title.length !== 0){ title = tag_property_og_title.attr("content"); }
// get description
var description = "Unknown description lol, stupid website do not click";
var tag_name_description = parser("meta[name='description']");
var tag_name_og_description = parser("meta[name='og:description']");
var tag_property_description = parser("meta[property='description']");
var tag_property_og_description = parser("meta[property='og:description']");
if(typeof tag_name_description.attr("content") != "undefined"){description = tag_name_description.attr("content"); }
if(typeof tag_name_og_description.attr("content") != "undefined"){description = tag_name_og_description.attr("content"); }
if(typeof tag_property_description.attr("content") != "undefined"){description = tag_property_description.attr("content"); }
if(typeof tag_property_og_description.attr("content") != "undefined"){description = tag_property_og_description.attr("content"); }
if(typeof tag_name_description.attr("value") != "undefined"){description = tag_name_description.attr("value"); }
if(typeof tag_name_og_description.attr("value") != "undefined"){description = tag_name_og_description.attr("value"); }
if(typeof tag_property_description.attr("value") != "undefined"){description = tag_property_description.attr("value"); }
if(typeof tag_property_og_description.attr("value") != "undefined"){description = tag_property_og_description.attr("value"); }
}
var text = "";
description = description.split("\n");
for(var i=0; i<description.length; i++){
text += "\n>" + description[i];
}
send(msg, title + text);
}catch(err){
send(msg, "Stupid retarded website alert!!!! I got an error accessing this shit...\n>" + err);
}
return;
}
/*
Commands
*/
var regex = msg.text.match(/^\.([^ ]+)(?: (.*))?/);
if(
regex === null ||
typeof regex[1] == "undefined"
){
return;
}
var cmd = regex[1];
if(typeof regex[2] != "undefined"){
var value = regex[2];
}else{
var value = "";
}
switch(cmd){
case "raid":
if(user.id !== 13){
break;
}
if(raid === false){
raid = true;
send(msg, "Ignoring all messages from now on, fuck you lol!!");
}else{
raid = false;
send(msg, "Now listening to messages!!!");
}
break;
case "rc":
case "reconnect":
if(user.id !== 13){
break;
}
send(msg, "brb");
setTimeout(function(){
fs.utimesSync(__filename, Date.now(), Date.now());
}, 1000);
break;
case "ping":
send(msg, "Pong!!!!");
break;
case "dice":
case "roll":
case "d":
case "r":
value = parseInt(value);
if(isNaN(value)){
value = 6;
}
if(value <= 1){
send(
msg,
"Rolling a " + value + " faced dice...\nWait what?? " +
"You fucking shit, a black hole just appeared!!!!!! Oh my fucking shit!!!!!"
);
return;
}
send(
msg,
"Rolling a " + value + " faced dice...\nAnd you got " +
(
Math.floor(Math.random() * value + 1)
) + "!!!"
);
break;
case "mumble":
case "m":
var port = 64738;
if(value == ""){
var ip = "lolcat.ca";
}else{
var value = value.split(":");
if(value.length >= 2){
var port = value[1];
}
var ip = value[0];
}
try{
var res = await fetch("https://lolcat.ca/api/mumble/?ip=" + ip + "&port=" + port);
var res_get = await res.json();
if(res_get.status != "ok"){
send(msg, "An error occured... " + res_get.status);
return;
}
res_get = res_get.server;
var servername = res_get.name === null ? res_get.domains[0] : res_get.name;
var website = res_get.website === null ? "No website available" : res_get.website;
send(
msg,
">Server information for " + servername + ":\n" +
"Known domains => " + res_get.domains.join(", ") + "\n" +
"Ping => " + res_get.ping + "\n" +
"Users => " + res_get.online + "/" + res_get.max + "\n" +
"Bandwidth => " + res_get.bandwidth + "\n" +
"Country => " + res_get.country.name + " (" + res_get.country.code + ")\n" +
"Version => " + res_get.version + "\n" +
"Website => " + website
);
}catch(err){
send(msg, "lolcat.ca api sucks and is offline and dead");
}
break;
case "prop":
try{
var res = await fetch("https://www.hamqsl.com/solarn0nbh.php");
var res_get = await res.buffer();
send(msg, "Good news: the sun has not yet exploded", res_get);
}catch(err){
send(msg, "Could not fetch image!!! FUCK!!!!111\n" + err);
}
break;
case "img":
case "im":
case "i":
if(value.trim() == ""){
send(msg, "You need to search for something cum licker!!!");
return;
}
global_page = 1;
ddg.image_search(
{
query: value,
moderate: ddg_mod
}
).then(async results => {
ddg_cache = results;
if(results.length === 0){
send(msg, "No results found for " + value + "!!");
return;
}
await serveddg(msg, results, 1);
});
break;
case "boobs":
case "boob":
case "nsfw":
switch(value.toLowerCase()){
case "yes":
case "y":
case "1":
case "yea":
case "true":
case "yup":
send(msg, "I will now show boobs when using .img");
ddg_mod = false;
break;
case "no":
case "n":
case "nae":
case "false":
case "no":
case "off":
case "nope":
case "nah":
case "0":
send(msg, "I will now prevent eagle from jacking off in main chat");
ddg_mod = true;
break;
default:
var active = ddg_mod ? "NOT " : "";
send(msg, "I will " + active + "show boobs. Use .boobs <yes:no> to toggle");
break;
}
break;
case "page":
case "p":
value = parseInt(value);
if(
isNaN(value) ||
value == ""
){
send(msg, "You didn't enter a valid number you dumbass!!");
return;
}
if(ddg_cache.length === 0){
send(msg, "Search buffer doesn't contain any links you horse fucker!!");
return;
}
if(
value > ddg_cache.length ||
value <= 0
){
send(msg, "Page offset must be between 1 and " + ddg_cache.length + " you dumbass!!");
return;
}
global_page = value;
await serveddg(msg, ddg_cache, value);
break;
case "pp":
global_page++;
if(global_page > ddg_cache.length){
send(msg, "You reached the end of results stupid kike sucker!!");
return;
}
await serveddg(msg, ddg_cache, global_page);
break;
case "youtube":
case "jewtube":
case "yt":
if(value.trim() == ""){
send(msg, "You need to search for something cum licker!!!");
return;
}
var ytsearch = await yt(value);
if(ytsearch.items.length === 0){
send(msg, "No results found for " + value + "!!");
return;
}
var text = "";
var k = 0;
for(var i=0; i<ytsearch.items.length; i++){
if(k === 3){
break;
}
if(ytsearch.items[i].type != "video"){
continue;
}
if(typeof ytsearch.items[i].badges != "undefined"){
var items = ytsearch.items[i].badges;
}else{
var items = [];
}
if(
typeof ytsearch.items[i].duration != "undefined" &&
ytsearch.items[i].duration !== null
){
items.push("Duration: " + ytsearch.items[i].duration);
}
if(
typeof ytsearch.items[i].uploadedAt != "undefined" &&
ytsearch.items[i].uploadedAt !== null
){
var tmp = "";
if(!ytsearch.items[i].uploadedAt.includes("Streamed")){
tmp = "Posted ";
}
items.push(tmp + ytsearch.items[i].uploadedAt);
}
if(
typeof ytsearch.items[i].views != "undefined" &&
ytsearch.items[i].views !== null
){
items.push("Views: " + ytsearch.items[i].views);
}
if(
typeof ytsearch.items[i].author != "undefined" &&
typeof ytsearch.items[i].author.name != "undefined" &&
ytsearch.items[i].author.name !== null
){
items.push("Author: " + ytsearch.items[i].author.name);
}
if(items.length !== 0){
text += ">" + items.join(", ") + "\n";
}
text +=
ytsearch.items[i].title + "\n" +
"â–¶ https://www.youtube.com/watch?v=" + ytsearch.items[i].id + "\n\n";
k++;
}
send(msg, "Search results for \"" + ytsearch.correctedQuery + "\"\n\n" + text.trim());
break;
case "help":
case "h":
send(
msg,
"== help menu ==\n\n" +
".help => lol idk\n" +
".img/.im/.i => search duckduckgo for birds\n" +
".boobs <yes:no> => Boobs?\n" +
".page/.p => get page offset for image search\n" +
".pp => get next page\n" +
".yt/.youtube => search the jewish propaganda catalog\n" +
".roll/.r => Because deekchat was too slow\n" +
".mumble/.m <[optional]ip:port> => check if lolcat died\n" +
".prop => check if the sun has exploded or smth\n" +
".ping => spam deekchat"
);
break;
}
});
deek.on("close", function(channel){
console.log("It's over. Disconnected from channel " + channel.name + ". Attempting reconnection in 10 seconds");
setTimeout(function(){
fs.utimesSync(__filename, Date.now(), Date.now());
}, 10000);
});
deek.on("error", function(message){
console.error("Serber error: " + message + ". Attempting reconnection in 10 seconds");
setTimeout(function(){
fs.utimesSync(__filename, Date.now(), Date.now());
}, 10000);
});
// connect to serber
handshake(name, password);