#development

1 messages · Page 1974 of 1

boreal iron
#

Also they actually keep deprecated functions for many versions to increase the support for older codes

#

If those aren’t security holes

modest maple
#

They originally provided mysql_escape_string, until that caused issues because it didn't actually give a shit about character encoding

#

Then you got real_escape which did do charset logic

#

Providing you bothered to set the charset

boreal iron
#

The extension support for this was dropped far ago
The newer extension for years now is mysqli which fixes lots this bottlenecks

#

iirc here

#

But yeah there’s no native support

#

At end it means thrrre no native solution to archive this, which is why you better use prepared statements

modest maple
#

Just fyi

#

Prepared is not the same as parameterized

#

From a database world

boreal iron
#

Yeah

modest maple
#

It may be the same in php

#

But they are very diffrent worlds

boreal iron
#

Already got that the last time freerealestate

#

When you said it

#

Just didn’t think of it as well as I didn’t think of it being an extension for php and not natively being implemented

modest maple
#

Legact Php is a pretty bad example in alot of cases

boreal iron
#

Hmm I don’t agree especially not with PHP8 in mind

#

But it’s not really worth to discuss about different use cases and preferences

cinder patio
feral aspen
#

I love regexes.

#

Goodness. I was about to manually recode 650 lines but regexes are just life saving.

boreal iron
#

Wtf doesn’t your code editor support search&replace?

#

searching interaction.followUp({ embeds: as text string does the same as your regex KEKW

#

You over complicate something damn simple

feral aspen
#

The value of the index in embeds: is not the same.

#

It can sometimes be embed, embeds, lol, idiot, authorEmbed, etc.

earnest phoenix
#

i have a question, can I use markdown for my top.gg bot page?

#

It is my first time using top.gg and I want to write the description of my bot in Markdown instead of plain text.

feral aspen
feral aspen
earnest phoenix
quartz kindle
lyric mountain
#

ye, prepared stats are compiled sql

#

while parametrized is not

cinder patio
#

I see

#

so what's the point of parameterized queries then?

quartz kindle
#

you use them when your lib/db doesnt support prepared statements, or when your query is not repeatable

#

if your query is not repeatable, theres no point in building a precompiled query if you're not gonna reuse it

cinder patio
#

ah alright. Good to know.

eternal osprey
#
let pointchannel = message.guild.channels.cache.find(
    (channel) => channel.id === "community-posts" //809659997423796247
  );
  if (!pointchannel ) {
     channel1 = await message.guild.channels.create("community-posts", {
      type: "text",
      permissionOverwrites: [
        {
          id: message.guild.id,
          deny: ["VIEW_CHANNEL"],
        },
        {
          id: client.user.id,
          allow: ["VIEW_CHANNEL"],
        },
      ],
    });
    channel1.send(
      "test"
    );
  }``` why the fuck does this create millions of channels
lyric mountain
#

why wouldn't it actually

last crow
#

Hello, is this json in the body of the request? (Webhook)

eternal osprey
#

dang i am a fucktard

lyric mountain
#

happens to everyone

eternal osprey
#

haha yeah, thanks for the help kuu!

lyric mountain
#

yw

last crow
solemn latch
#

looks like you need to get the value

last crow
#

get the valeu?

eternal osprey
#

how do i actually ping a message in the way of <@${id}>

solemn latch
#

ping a message?

eternal osprey
#

yeah

solemn latch
#

I'm pretty sure you can only link to messages, not ping them 👀

eternal osprey
#

owh how would i link to it usin an id?

solemn latch
#

youll need the guild id, channel id, and message id.

https://discord.com/channels/GuildIDHere/ChannelIDHere/MessageIDHere

last crow
#

with harmony as discord api client

solemn latch
#

can you show your code for receiving the webhook then?

last tapir
#

hi everyone, i have pm2 and when an error occurs, it restarts the application why so?

#

i want it so if it errors, it doesn't auto restart the application

real phoenix
#
@client.command()
async def verify(ctx):
  if str(ctx.message.channel) == 'verify':
    role = 839159549260333121
    roleTag = 839159549260333126
    oldRole = 940251830980603975
    # Change roles
    await ctx.message.author.add_roles(role)
    await ctx.message.author.add_roles(roleTag)
    await ctx.message.author.remove_roles(oldRole)
    await ctx.send("Success!")

I'm making a verify command that changes your roles. However its not working. Heres the error

aise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'int' object has no attribute 'id'

From what I know I'm doing this correctly. Is there any reason why this happens?

last crow
solemn latch
#

so you are using the oak library?

last crow
#

yeah

solemn latch
#

looks like you just need to parse the value

last crow
#

JSON.parse()?

solemn latch
#

const value = JSON.parse(JSON.stringify(await ctx.request.body()));
I would presume

#

or just json.parse would probably work

#

grabbed that from a tutorial 👀
ive never used oak, not sure what's required.

last crow
#

thx

lyric mountain
solemn latch
#

Does that work for parsing json?

lyric mountain
#

no, I mean, you're transforming something to string then transforming back to json

#

it's like x / 5 * 5

last tapir
#

hi everyone, i have pm2 and when an error occurs, it restarts the application why so?
i want it so if it errors, it doesn't auto restart the application

spark flint
#

Try pm2 logs and see what error

last tapir
#
0|attitude  | /root/bot/node_modules/discord.js/src/rest/RequestHandler.js:350
0|attitude  |       throw new DiscordAPIError(data, res.status, request);
0|attitude  |             ^
0|attitude  | DiscordAPIError: Cannot send an empty message
#

Something like that

#

im a helper of @feral aspen and he kind-of got fedup

lyric mountain
#

show the full stacktrace

feral aspen
#

👋

spark flint
#

Add a handler for errors

feral aspen
#

Hello.

#

I have a handler for errors, although, why would it crash when it errors?

lyric mountain
#

cuz that's a great thing they added on newer node versions

feral aspen
lyric mountain
#

and I'm not even being sarcastic

feral aspen
#

Wait, the new node crashes the application on errors?

lyric mountain
#

ye

feral aspen
#

HUH?

lyric mountain
#

as it's supposed to be

feral aspen
#

WHY.

lyric mountain
#

because crashes aren't really that evil

#

better a crash than a silent error slowly consuming your soul

#

you CAN make a global error handler tho, which would prevent crashes on any error

#

but you should always treat exceptions

spark flint
#

I have one of those it just logs errors

feral aspen
#

That's the full one.

lyric mountain
spark flint
#

process.on('unhandledRejection', error => {
console.log(error);
});

#

That’s what I have

lyric mountain
#

you just leaked the webhook's path

feral aspen
#

Oh my god.

lyric mountain
#

you can spam with the url alone

feral aspen
#

Well...

lyric mountain
#

redact the url, then show again

lyric mountain
spark flint
#

There

#

Ignore the .yaml

#

Fuck

#

Wait

#

Fucking Hastebin

feral aspen
lyric mountain
#

no content at all

#

do you happen to know WHERE that's happening?

feral aspen
#

Could be the logs, I guess.

feral aspen
#

I don't want it to keep crashing, but I will soon read the errors and fix them without having the bot to crash.

lyric mountain
#

you can, but treat all the exceptions whenever they occur

feral aspen
#

Indeed, I will.

#

How can I achieve this, please.

lyric mountain
#

put that exact code in ur index

feral aspen
#

Even if I have sharding?

last crow
feral aspen
solemn latch
lyric mountain
#

yes, that's regarding process errors

lyric mountain
#

regardless of what u have in the code

last crow
#
import { Application, Context } from "https://deno.land/x/oak@v10.2.0/mod.ts";
import { jsonParser } from "https://raw.githubusercontent.com/gjuoun/oak-json-parser/master/mod.ts"
const app = new Application();
app.use(async (ctx:Context) => {
    if(ctx.request.headers.get("authorization") == "---"){
        console.log(JSON.parse(JSON.stringify(await ctx.request.body())))
    }
    await delay(20)
    ctx.response.body = "Hello world!";
});

async function delay(ms:number) {
    await new Promise((resolve) => setTimeout(resolve, ms));
}

await app.listen({ port: 8000 });
``` is my code
feral aspen
solemn latch
last crow
#

706526290181619775

solemn latch
#

The thread button appears out of nowhere sometimes topggAngry

spark flint
boreal iron
# feral aspen The value of the index in `embeds:` is not the same.

Why should that matter in any kind?
Searching for interaction.followUp({ embeds: and replacing it by interaction.editReply({ embeds: does exactly the same as you RegEx.
Which does exactly means you over complicate things...
Search and replace works fine here.
The content of your embeds array doesn't matter as you don't wanna replace that, or do you?

lyric mountain
#

what makes it restart is pm2

last crow
solemn latch
#

👀

last crow
#

._.

#

i'll try without oak

solemn latch
boreal iron
#

nvm then

feral aspen
candid lance
#

1

quaint rampart
#

anybody working on anything cool they wanna share i wanna see some new projects or something idk

split hazel
#

im making an among us machine learning bot

#

it finds things that look like amogus in an image and puts squares around them

hexed garnet
#

So more working

split hazel
#

@quaint rampart

cinder patio
#

sus

quaint rampart
quaint rampart
#

i’m currently working on a sharex cdn with a dashboard i have everything done and working i just need one last thing which is a button to remove all your ss’s from the cdn pretty simple but just need to get around to doing it

boreal iron
hexed garnet
#

Gimme inv

simple stump
#

How would you calculate 1300 weighted towards 1105 by 50%?

marsh bluff
wheat mesa
#

Math

wheat mesa
simple stump
wheat mesa
#

Still doesn’t make sense though

cinder patio
#

More like meth

#

My guess is they want a random weighted number

#

Where there's a 50% chance of getting 1105 and 50% any other number up to 1300

#

but I could be wrong

solemn latch
marble juniper
#

How to make an ai to classify images

#

but in javascript with deno

sudden geyser
#

step 1. find api that does ai image classification
step 2. interface with it
step 3. profit

split hazel
#

step 1. dont use deno
step 2. dont use deno
step 3. dont use deno
step 4. idk man use some ml library

marble juniper
#

Also my question is serious

#

If I send a question here im not joking

split hazel
#

who said i was joking

marble juniper
#

Incase anyone thought that

split hazel
#

but i dont know if deno has any libraries like that

#

for node youd kind of just import tensorflow with mobinet and train a custom model

marble juniper
#

yeah ik how to do it for nodejs already

split hazel
#

deno has tensorflow so uh

#

good luck?

marble juniper
#

Idk why people even shit on deno

#

like whats wrong with it

eternal osprey
#

How do i let a function run in js each monday?

cinder patio
sudden geyser
marble juniper
#

I didn't specifically mean speedy

#

forgot to say that

sudden geyser
#

Ah

#

Me personally, I haven't seen any hate towards Deno.

#

I personally don't like it.

#

But it was very trendy and popular

#

But not something I'd ever seen in production

marble juniper
#

Wanna start a discussion about what deno / node does better than deno / node

#

aka what 1 runtime does better than the other

#

in certain aspects

cinder patio
#

Deno has better security measures... and that's pretty much it

sudden geyser
#

Sure, though I probably won't be able to name many.

#

I think "security" as its biggest advantage is just false.

marble juniper
#

although nodejs is getting that soon

cinder patio
#

I wouldn't really say that's an advantage tho

marble juniper
#

That was kinda also the reason I loved using deno

sudden geyser
#

As it's just saving the developer from accidentally doing X during development, but probably has no application in production with end-users.

marble juniper
#

because of its native fetch

#

that didn't require me to install a dependency

sudden geyser
#

And the security only accounts for a small fraction of all the security that actually goes into apps.

eternal osprey
#
cron.schedule('* * * Monday', () => {
  console.log('running on ondayr');
});``` is this the correct cron-way of handling a function each monday
cinder patio
#

with node.js there are no guarantees

sudden geyser
cinder patio
#

yes but we're comparing two js runtimes

marble juniper
#

those aint languages

#

lol

sudden geyser
#

Yet we don't block that because it's really just saving the developer, unless you got the user to somehow evaluate arbitrary code that would try to write a file

#

But you have more things to worry about if that's happening

sudden geyser
marble juniper
#

I think its good that there isn't just a single and only runtime you can use

split hazel
#

i think its 0 0 * * MON

cinder patio
#

As long as the program isn't writing to disk during development then it's not going to during production, either.

marble juniper
#

What if

#

you program needs all perms

sudden geyser
#

You're not Google though

marble juniper
#

But what if I am

#

jk

sudden geyser
#

then you can cry in c plus plus

cinder patio
#

Maybe the biggest feature I dislike about Deno is that it has typescript support out of the box. It hides the JS output from you 😩

#

like why

lyric mountain
sudden geyser
#

You can still write JS though

cinder patio
#

My problem is that it hides the JS output

split hazel
#

you can make it text or numbers

#

like 1 for monday i think not sure

lyric mountain
#

Ye, 1 to 7

cinder patio
#

why 6

#

Does cron go to church on sunday

lyric mountain
#

Oh true, confused with 0-based system

marble juniper
#

so maybe deno has a JIT for typescript too idk

cinder patio
sudden geyser
cinder patio
#

there isn't much

lyric mountain
#

Oh fck

marble juniper
#

sad

lyric mountain
#

It's actually 0 to 6

#

0 Sunday, 6 Saturday

marble juniper
#

cringe

#

random but

#

I wonder if british people have ever seen the sun on a sunday

#

ok bye

split hazel
final mica
#

h

simple stump
#

Can I require 2FA to be enabled for certain slash commands or text commands specifically?
Ex.

if (interaction.member.has2FA() && isStaff()) {
  // allow cmd
} else {
  // disallow cmd
}

The isStaff() is a placeholder for checking if the user has a Discord role.

sudden geyser
#

I don't believe so.

#

A server owner can enable 2FA on servers

#

But I don't think bots can check if a user has 2FA enabled

simple stump
#

If I were to check if an user has a specific permission (since 2FA blocks the user from utilizing actions that require BAN_USER, ADMINISTRATOR, etc.) could I theoretically check this?

#

Cause on my server I do have 2FA enabled.

split hazel
#

that way you can check if they have 2fa enabled via a flag

simple stump
#

Ah. I see

#

ty

sharp saddle
#

How i delete collection in mongodb?

I'm using the lib: Mongoose

split hazel
#

would be cautious with it though since mongoose might bug if you have active connections or models

earnest phoenix
#

How can I effectively destroy a express session when logging out

#

The last time I did so the session still existed and caused problems when logging in again(cause I thought it actually did get destroyed)

lyric mountain
#

You technically don't

#

All you can do is null the reference so the GC collects it on next pass

#

You can too forcefully free the port before starting the process

#

I do that for my spring api

quartz kindle
#

pretty sure thats not what hes talking about?

lyric mountain
#

Idk then

quartz kindle
#

well im assuming its about express.js and express-session

#

express-session has a session.destroy() method, but it also has third party session stores you need to check with their own store.destroy()

earnest phoenix
#

Mmm I see

#

Well when I called session.destroy it removed all the added stuff to the session and removed it from the session store but when I went to go to a route that requires a session to be there it told me I was already logged in

#

and logging in again just caused even more issues such as the new session not being saved to the store

#

Also the session never expired like it should have

quartz kindle
#

well i saw this on SO

#

you can try that

#

nvm that answer is from 8 years ago lol

plucky lion
#

how can dis apear (luca)

solemn latch
#

posting via the api

gilded plankBOT
earnest phoenix
#

Cause it is right it only deleted it in the db

#

so maybe setting the entire session to null as well might work?

earnest phoenix
#

[Nest] 42667 - 02/07/2022, 6:09:04 PM ERROR [ExceptionsHandler] null value in column "key" of relation "users" violates not-null constraint
So I keep getting this error even tho I have made sure that the key being generated is not null/undefined and it is returning a hash like it should so key should not be null when setting it

#
  async generateKey(): Promise<string> {
    const nanoid = customAlphabet("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0987654321", 32)
    return await nanoid()
  }
  async registerUser(user: SignupDto){
    const existingUser = await this.usersService.findOneWithEmail(user.email);
    if (existingUser) throw new BadRequestException('Email is already linked to another account.');
    let u = await this.usersService.insert({
      ...user,
      key: await hash(await this.generateKey())
    });

    return {
      id: u.id!,
      email: u.email,
      role: u.role,
      createdAt: u.createdAt!,
      updatedAt: u.updatedAt!,
      key: u.key,
    };
  }
sudden geyser
#

isn't it insertOne

earnest phoenix
#

No

#

this isn't mongo

#

I am using typeorm + pg

#

also insert is a custom method on usersService

#
  async insert(data: Partial<Users>): Promise<Omit<User, 'password'>> {
    const user = await this.usersRepository.findOne({ where: { email: data.email } });
    if (user) throw new BadRequestException('Email already is linked to another account.');
    if (this.sequence > 4194303) this.sequence = 0;
    const newUser = new Users();
    newUser.id = ((BigInt(Date.now()) << 22n) + BigInt(this.sequence++)).toString();
    newUser.email = data.email;
    newUser.password = await hash(data.password);
    await newUser.save();

    return {
      id: newUser.id,
      email: newUser.email,
      createdAt: newUser.createdAt,
      updatedAt: newUser.updatedAt,
      role: newUser.role,
      key: newUser.key
    };
#

Actually I realized an error in my registerUser thing I am already checking for an email in the insert so no need to do so there as well :^)

#

But anyway for some reason the key is becoming null when trying to set it

wheat mesa
#

simple

#

don't make it null

earnest phoenix
#

Hmmm I wonder

#

cough async insert(data: Partial<Users>): Promise<Omit<User, 'password>> {}

#

It is TS if you can't tell by me defining the types

#

So I found the issue actually

sudden geyser
#

to learn?

earnest phoenix
#

MMm but fuck

#

key is empty

#

Okay there we go

earnest phoenix
#

since I want to delete the cookie on logout and also destroying the session at the same time helps as well

#

Now the only thing I need to do is instead of giving the hashed key in the cookie I should probably change it to the plaintext key

quartz kindle
#

👍

feral aspen
#

I was ghost pinged?

sudden geyser
#

who knows

quartz kindle
#

the ghost knows

sudden geyser
#

ghosts aren't real

quartz kindle
#

they are if they can ping people

sudden geyser
#

gasps

#

so you live in brazil right

quartz kindle
#

ye

sudden geyser
#

sending someone to pick you up

#

you know too much

quartz kindle
#

oh my

#

are you with the illuminates?

sudden geyser
#

No but I'm with the CIA and NSA

#

which is practically the illuminati

quartz kindle
#

oh so you're nothing but a lapdog

#

pitty

sudden geyser
#

don't make me come for you personally

quartz kindle
#

tell your bosses i said hi

lament rock
#

I had a vague suspicion

earnest phoenix
earnest phoenix
#

why my bot not starting bruhhh

#

it took like 2hours

#

same thing shows

#

can someone help ;-;

#

;-;

#

no reply

feral aspen
#

Unless you don't have the skill to understand what I'm saying. ;-;

earnest phoenix
lament rock
#

seems like everyone is so cut throat at each other. Geez

earnest phoenix
feral aspen
feral aspen
#

Please be patient.

lament rock
#

idk. Can I?

#

All jokes aside, idk what the error is. The screenshot you posted literally shows nothing helpful. Therefor, I cannot help you

earnest phoenix
#

just shows this

lament rock
#

why are you using npx

earnest phoenix
#

hmm

#

why?

lament rock
#

why not just have the start command be just node .

#

if your package.json already links the main file as the index, then node . will work

earnest phoenix
#

if i start with node index.js token invid it shows

lament rock
#

Then there's your actual error. The token you're providing to your bot is invalid

earnest phoenix
#

becuase i have changed my bot token sevral times

#

can it be wifi issue??

lament rock
#

Have you tried console logging the value of what you supply to the login to make sure you're not supplying it with undefined or anything unintentional

earnest phoenix
#

package is empty

#

bruh

lament rock
#

Seems like you have more issues then if your package.json is empty. Good luck sorting that out

earnest phoenix
#

hm

#

i have backup

#

by the way

#

i can just copy paste

#

hehe

dry imp
#

good 4 u

slow terrace
#

Why it's not saving when i try to edit a value in the object???

        console.log(data.progress.quests.find(x => x.id == 1).current) // Prints 3
        data.progress.quests.find(x => x.id == 1).current += 1;
        console.log(data.progress.quests.find(x => x.id == 1).current) // Prints 4
        await data.save() // Not saving
lament rock
#

what is data. An entry from a database?

#

is it raw json?

earnest phoenix
#

same thing bruh

lament rock
#

I told you to remove npx

slow terrace
earnest phoenix
#

idid

#

bro

#

token invaild

lament rock
#

Then why does it say npx on your console

lament rock
#

mongoose or other wrappers are weird imo

lament rock
#

Now you're getting somewhere. This actually helps me realize that you are not using node 16

earnest phoenix
#

jhmm

lament rock
#

the ?? operator only exists in node 16

earnest phoenix
#

idk

lament rock
#

you don't have to know. I'm telling you

earnest phoenix
#

oh

#

ok

earnest phoenix
lament rock
#

npx is an npm package runner that can execute any package that you want from the npm registry without even installing that package.

earnest phoenix
lament rock
#

No. I'm not gonna do work for you. Or anyone

earnest phoenix
#

...

dry imp
#

i love this kind of guys

earnest phoenix
#

help?

lament rock
#

Upgrade to node 16

#

thats the solution

earnest phoenix
#

how?

lament rock
earnest phoenix
#

ok

hallow shell
#

the node npm package comes with a binary i believe

#

you could use that

round cove
#

Was curious.

      intents: [
        Discord.Intents.FLAGS.GUILDS,
        Discord.Intents.FLAGS.GUILD_MESSAGES,
        Discord.Intents.FLAGS.GUILD_MEMBERS,
        Discord.Intents.FLAGS.GUILD_MESSAGE_REACTIONS,
      ],```
Because I have `GUILDS` intents at the top that just implicitly means to include everything within the GUILDS intent group right? If so I want to be very picky about what events I get then to reduce the amount of events are emitted to my bot.
lunar palm
#

I believe so yeah

earnest phoenix
#

From my knowledge it does mean you will get all events related to guilds

round cove
#

I think I legit just need reactions because interactions will always be sent lmao

earnest phoenix
#

You might also need members if you will be dealing with members

#

cause no matter if its message commands or interaction commands members aren't always cached

round cove
#

I mean I'll get member objects to give/take roles but that's it.

#

Ah.

earnest phoenix
#

Yea

round cove
#

I think I always fetch anyway.

#

Xddd

earnest phoenix
#

That is a general good idea now a days

#

fetching is what you generally wanna do

round cove
#

Yeah just query Discord for info.

#

I wonder what the global ratelimit is.

earnest phoenix
#

Good rule of thumb is to not even attempt to do anything every x amount of time imo

round cove
#

The bot is pretty basic in terms of handling events.

earnest phoenix
#

I just don't like the idea of possibly hitting a ratelimit

round cove
#

User reacts -> give/take role

earnest phoenix
#

I think reactions you won't generally have to worry about I could be wrong cause discord will ratelimit them if they react too quickly

round cove
#

It's in >2k servers at the moment but I haven't seen any complaints so far from Discord.

earnest phoenix
#

Again tho I could be wrong

round cove
#

I'll just go as ham as possible until hammered

earnest phoenix
#

Just make sure you notice before you get api banned for a few hours

round cove
#

Lmao

#

I should be good.

#

Hopefully

#

Users can't complain if they hit the confirm button now.

lament rock
round cove
#

I spent too much money on building my server to NOT use all ram and cpu process power

earnest phoenix
#

I just figured out how to use redis for the first time

#

Idk why some people say it is hard to implement took me 5m

#
{
    "cookie": {
        "originalMaxAge": 60000,
        "expires": "2022-02-08T06:39:02.200Z",
        "httpOnly": false,
        "path": "/",
        "sameSite": true
    },
    "passport": {
        "user": {
            "id": "6896703353510690816",
            "role": 1,
            "key": "hgOhCiwSHL29dRBVDwJAgms1YYjYkN5e"
        }
    }
}

I get the key from a redis store

lament rock
lament rock
lament rock
earnest phoenix
#

I can't store this in the processes memory

#

it is important information that if stored in a map and the map gets emptied im fucked

#

It is the only way to keep the api keys persistent so I can re add them to sessions when they expire for users

lament rock
#

redis doesn't have reliable persistence and it shouldn't be used

earnest phoenix
#

Wdym

#

Isn't redis literally meant for this

lament rock
#

No. Redis is a cache. "cache" implies volatile. If you wanted to store something persistently, you'd be better off using postgres or the likes. Data you need for a short amount of time, sure; Use Redis.

earnest phoenix
#

Mmm I see

#

So I just implemented redis for no reason

lament rock
#

Literally

earnest phoenix
#

Well I can still make use of it

#

I will need to cache some stuff

#

I will keep it implemented

lament rock
#

I used to dump all of my Discord gateway data onto it, but since I moved to slash commands, I do not need any cache anymore

earnest phoenix
#

I am making a platform so I kind of need cached data sometimes

lament rock
#

sitting at a nice 170MB consistently at 7k guilds and most of the heapdump is require.cache

earnest phoenix
#

I guess what I can do is make a table in my postgres db that just gets the plaintext key

#

tho I really don't like storing plaintext stuff in a db

lament rock
#

JWTs can be stored in redis

earnest phoenix
#

I didn't like the idea of using JWTs for this project

lament rock
#

that's valid

earnest phoenix
#

JWTs are nice for a smaller scale project i'd say but for something like this I want persistent logins and more flexibility

lament rock
#

Persistent and permanent logins usually are a security vulnerability

earnest phoenix
#

well not persistent per say

#

But I don't want them to have to login every day

round cove
#

I use psotgres and just query for the data for each command.

#

No reason for in memory.

earnest phoenix
#

help

round cove
#

Postgres is fast enough.

lament rock
earnest phoenix
earnest phoenix
lament rock
#

Okay. So, how do you remedy the fact that a module isn't installed

lament rock
#

You would install it, no?

earnest phoenix
#

can you run npm

#

there should be an npm dependency in the file too

#

Well looks like my best option is to save a plaintext version of the api key so I can readd it to the session's cookie to compare against the hashed version every new login

earnest phoenix
#

try doing npm i discord.js

#

k

lament rock
earnest phoenix
#

Yea I will

lament rock
#

good lad

earnest phoenix
earnest phoenix
# lament rock good lad

Actually that will be a bit hard since I am signing the plaintext key to the session's cookie

lament rock
earnest phoenix
#

it should work now

rigid lark
earnest phoenix
#

Unless there is a better way to authenticate things internally since a lot of the endpoints will be key protected

rigid lark
earnest phoenix
#

erors

rigid lark
#

read :/

earnest phoenix
#

i am using nix(beta) for node v16

#

send your package.json

#

what does discord.js need python for

#

{ "dependencies": { "@discordjs/builders": "^0.6.0", "@discordjs/opus": "^0.6.0", "@discordjs/voice": "^0.6.0", "@distube/soundcloud": "^0.2.2", "@distube/spotify": "^0.6.3", "@ksoft/api": "^3.1.9", "body-parser": "^1.19.0", "colors": "^1.4.0", "cpu-stat": "^2.0.1", "discord.js": "^13.1.0", "distube": "^3.0.0-beta.37", "ejs": "^3.1.6", "enmap": "^5.8.7", "express": "^4.17.1", "express-session": "^1.17.2", "ffmpeg-static": "^4.4.0", "http": "^0.0.1-security", "https-proxy-agent": "^5.0.0", "libsodium-wrappers": "^0.7.9", "memorystore": "^1.6.6", "os": "^0.1.2", "passport": "^0.4.1", "passport-discord": "^0.1.4", "session": "^0.1.0", "url": "^0.11.0" }, "devDependencies": { "node": "^16.6.1" }, "name": "music-bot-4", "description": "", "version": "1.0.0", "main": "index.js", "scripts": { "start": "node .", "node-update": "npm i --save-dev node@16 && npm config set prefix=$(pwd)/node_modules/node && export PATH=$(pwd)/node_modules/node/bin:$PATH", "node-clean": "rm -rf node_modules && rm package-lock.json && npm cache clear --force && npm cache clean --force && npm i", "node-update-then-clean": "npm run node-update && npm run node-clean" }, "repository": { "type": "git", "url": "git+https://github.com/Tomato6966/Musicium.git" }, "keywords": [], "author": "", "license": "ISC", "bugs": { "url": "https://github.com/Tomato6966/Musicium/issues" }, "homepage": "https://github.com/Tomato6966/Musicium#readme" }

#

Oh god

#

why does any package ever use python

lament rock
rigid lark
earnest phoenix
rigid lark
#

also, it says your package-lock is old

earnest phoenix
earnest phoenix
earnest phoenix
rigid lark
#

i would suggest deleting it and rerunning everything

earnest phoenix
#

thos is simple node

#

rm package-lock.json && npm i

#

in this is dopsent even start

rigid lark
lament rock
#

The server should store plain text so it can compare when the user logs in. The hash is for the cookie. When there is a cookie, you check if the hash from the cookie is equal to a hash of the password.

The checks should always be performed by the server

earnest phoenix
lament rock
#

Please don't meme about security. People might take you seriously

earnest phoenix
earnest phoenix
earnest phoenix
#

npm install would redownload every package

lament rock
earnest phoenix
#

argon2 has a verify function that takes in a hash and plaintext

earnest phoenix
lament rock
#

Then that should be fine if that's to compare

earnest phoenix
#

Tho I still need to store the hashed version anyway since I want to sign the hashed api key to a new session when old ones expire

#

I am now realizing how annoying making apis with api key protected routes can be

#

Unless I am just doing this in a dumb way which btw ophidian if you have a better suggestion I am all ears

lament rock
#

You should not do that unless you're doing like how Discord does it with tokens.

The first string before the . is the ID of the User. The second is the time the token was created. The third is random garbage

earnest phoenix
#

Well how do you suggest I manage this then

#

Actually

lament rock
#

Like how I suggested or do it "the discord way"

earnest phoenix
#

I can just rehash on every new session can't I

lament rock
#

Theoretically

earnest phoenix
#

As long as the plaintext is stored it doesn't matter what the hash is in the new session

lament rock
#

If the hash can decrypt to the plain text, then yes

earnest phoenix
#

I don't think you can decrypt a hash can u?

#

I am very iffy on my knowledge on encryption and hashing

lament rock
#

You can. It might take for-fucking-ever

earnest phoenix
#

Oh I see

#

I was told you can't decrypt a hash

lament rock
#

By decrypt, I meant if the hash is they plaintext before encryption. Idk how libs verify

earnest phoenix
#

Ah I see

#

Honestly I might just rework this entire system

lament rock
#

password 1234 might encrypt to abcd

if you have multiple hashes of 1234 which aren't equal, so long as the plaintext is 1234 and the lib can verify that the hash is just an encrypted version of 1234, then you're all good

#

But I would suggest the Discord way if you want multiple tokens

#

Like, I can get the first part of any bot's token just by the ID. The timestamp and the random garbage, you cannot

earnest phoenix
#

Mmm

#

How exactly does discord handle it internally tho

#

Like I am logged in rn right and I assume the token is stored in a cookie/localstorage right?

#

Do they use that token in the cookie to get my data from different endpoints?

#

and then how do they verify that token is valid

lament rock
earnest phoenix
#

they just base64 the token?

lament rock
#

No. The token is base64 of the client's id, the timestamp the token was created and then some random garbage

earnest phoenix
#

Mmm

lament rock
#

My bot's might look like
NzA5OTA3NjQ2Mzg3MzIyOTMy.jf62.jWbffK1b672

#

not a real token

earnest phoenix
#

ye

woeful pike
earnest phoenix
#

Wendy coming in with the lurk

lament rock
#

if you split the string by . the first entry is my client's ID

woeful pike
#

nice token I just logged into ur bot and downloaded all ur credit cards

lament rock
#

which is 709907646387322932

#

i dont remember giving my bot my credit cards

earnest phoenix
#

I wonder what that random garbage at the end is probably some randomly generated string

lament rock
#

I guess the rule: "Forfeit all mortal possessions to the cat girl" still applies

#

it is randomly generated

#

hence why I said random garbage

earnest phoenix
#

So I understand the creation of the token

lament rock
#

mfa tokens are all random garbage

earnest phoenix
#

I assume they then sign that token to a cookie and what do you think they store in the db?

lament rock
#

they store the token in the db

#

nothing plaintext

earnest phoenix
#

Oh I see

lament rock
#

the token provides all the info necessary

earnest phoenix
#

So they just compare token to token

#

So basically they just leave it up to the user if you share your token that is your fault

#

finally my bot is online now ooooof

lament rock
#

you can create relations from user name/email to user ID and then check if the token corresponds with that ID

#

the token contains the user ID in it

earnest phoenix
lament rock
#

so you can get user info by ID

earnest phoenix
#

Hmmmm

#

I think I understand

#

So basically if I do it that way I have no need to really sign my userID to the cookie?

#

i can just sign the token

#

and then decode it to get their userID and query the db that way right?

lament rock
#

Pretty much

#

of course, verify the token matches

earnest phoenix
#

can i have a script for music bot 24/7 in vc??

lament rock
#

because they have the user ID, which can be predictable, but they also need the random garbage from the rest of the token to verify it is actually them

earnest phoenix
#

Yea

pale vessel
#

might be useful

lament rock
#

thanks flaze

#

I was looking for that

earnest phoenix
#

HMAC?

#

wtf is that

pale vessel
#

yeah same I was looking through my archive channel for that

earnest phoenix
#

What is that HMAC shit

pale vessel
#

"random garbage"

lament rock
#

google says

In cryptography, an HMAC (sometimes expanded as either keyed-hash message authentication code or hash-based message authentication code) is a specific type of message authentication code (MAC) involving a cryptographic hash function and a secret cryptographic key.

earnest phoenix
#

Yea i dont get it

#

I will just generate random garbage and base64 encode it

lament rock
#

just random garbage to verify since you can't reliably guess random garbage

earnest phoenix
#

ye

woeful pike
#

so I'm guessing tokens are

id + time + hmac(id + time)
lament rock
#

no. The last part is literally just random that follows no trend

#

asides from pseudo-random logic

#

but like I said earlier, multi factor authentication tokens are all random

pale vessel
#

do tokens reset if you change your password?

#

I'm guessing they do

lament rock
#

Yup. All of them are invalidated

earnest phoenix
#

Oh god how do I manage that.

lament rock
#

mfa tokens also expire every month

pale vessel
#

doesn't it mean you'd have to relogin every month?

earnest phoenix
#

Ima just follow my own method to my madness

#

I can't be bothered to do all that

pale vessel
#

or does it just regenerate

lament rock
#

on PC, that's what I have to do

earnest phoenix
#

I don't have ot login every month

lament rock
#

there might be a refresh_token involved

#

but Discord always prompts me

woeful pike
#

I don't think it would be called an hmac if it wasn't some sort of digest of the rest of the token + a secret value though

earnest phoenix
#

Well discord uses oauth2 doesn't it?

woeful pike
#

unless they're using that term loosely

earnest phoenix
#

can i have 24/7 script for music bot like !join to join that vc in which person is in... then !leave to leave that vc like this
but 24/7

#

in my code i m like filled with errors

lament rock
#

It doesn't have to be the rest of the token because it's not useful on its own. It can just be a secret token that's hashed or just random bytes

woeful pike
#

write your own code bro

earnest phoenix
woeful pike
#

the only person in the channel begging for copy paste

earnest phoenix
#

-_-

earnest phoenix
#

this is a joke obv

woeful pike
lament rock
#

tempting

woeful pike
#

or just don't do auth and leave it to something like firebase

#

epic gamer

earnest phoenix
#

But that takes the fun out of coding wendy

#

you were on my ass before cause I didn't wanna do something like a json parser

lament rock
#

Whatever works for you. You don't have to be an expert in cryptology to have a secure setup. I'm not an expert, but I guess I put on a decent facade. Just thinking logically and from the perspective of what issue experts are trying to fix

#

For instance, if a hmac isn't useful on its own, then it can't reference anything else

earnest phoenix
#

Honestly I want something secure as well but I am not that smart when it comes to understanding some stuff so It takes me a bit to fuly understand

lament rock
#

Some libs do everything for you which is okay. My setup isn't secure. I just have permanent tokens the user inputs themselves and could theoretically share with others if they so desired

#

not that its a security concern since the resources they're accessing with the token hold very little weight

earnest phoenix
#

I just want something that will protect the user to a point where if their account gets compromised its not my fault its theirs mmLol

lament rock
#

sending plaintext to the client is definitely your fault

earnest phoenix
#

Yea I realize that now

lament rock
earnest phoenix
#

I do like the idea of doing what discord does

#

its where I got my idea for the ids I use

#

I am just still a bit iffy on how to actually implement it properly so as to make it as secure as possible

lament rock
#

now you can definitely hash the IDs for the first part of the token. The rest is up to you

woeful pike
earnest phoenix
#

Ayo uncalled for

woeful pike
#

actually that's not even true depending on the kind of bug I suppose

earnest phoenix
#

I will just make something that has bugs everywhere ez

lament rock
#

I probably couldn't write a JSON parser. Too much unexpected tokens

#

or more like a lot to account for

earnest phoenix
#

So Ophidian this is my thought process

  1. Generate a token (base64) of their ID + Timestamp + Some random garbage
  2. Store that token in the cookie and database
  3. Authenticate requests using the decoded ID from the token and compare tokens from DB to cookie
  4. Let the request through if successful else throw error
lament rock
#

looks a-o-good to me

earnest phoenix
#

why not use discord oauth

#

Cause I am stepping away from discord related dev stuff

lament rock
#

oauth is also a pain in the ass to dev

earnest phoenix
#

At some point I might integrate the ability to login via discord

#

But that won't be for a good while

#

as I have no need as of now

#

isn't it better to always use a third party provider so you don't fuck up the security yourself

cinder patio
earnest phoenix
#

I am also doing this entire project on my own so if I don't talk here in a few days send help cause i've likely gon insane

lament rock
#

What happens if that provider gets hacked

earnest phoenix
#

What provider

lament rock
#

Security is not hard to do

earnest phoenix
#

If i fuck up the security myself that is obv a me problem and i need to be better

#

and it also means i am not ready to make a large scale app that quickly

lament rock
#

Finally, someone who understands

#

"You are not ready"

earnest phoenix
#

Oh I know i am not ready

woeful pike
#

security is like super hard to do wdym

earnest phoenix
#

which is why I have no dead line for a release

#

I estimate it will take at least the entire summer to finish just the backend maybe even longer

lament rock
earnest phoenix
#

Come do it for me /s

lament rock
#

assuming I wanted to

earnest phoenix
#

you will be paid in water and bread

#

and daily hugs

#

:^)

lament rock
#

I need money and sanity since I already maintain some Discord libs which is already a pain in the ass and also my bot. I basically manage my bot's entire stack. I even remade lavalink in js

earnest phoenix
#

😢

#

why put yourself through that pain

#

Tho I am probably about to experience hell with this project as well

#

Especially when frontend comes

#

😔

cinder patio
#

frontend's easyyy

earnest phoenix
#

HTML sure

#

css no

#

My designing quality is a 0/10

#

I have no taste

pale vessel
#

I could do CSS but I'm not great at designing whatsoever

earnest phoenix
#

portfolio

#

Like the design ?

#

I was meming that description tho I didn't know what ot put

#

But anyway the design sucks

lament rock
# earnest phoenix why put yourself through that pain

because a lot of other's people's solutions are too expensive on system resources. Back when I was hosting on heroku, I made a plugin for Discord.js to disabled presence caches because gateway v6 was indiscriminate.

When that stopped being the end all solution, I just decided to migrate to the libs I now maintain, cloudstorm and snowtransfer and made a rest only cacheless Discord.js

#

I also didn't like how much lavalink consumed, so I remade that as well

earnest phoenix
#

Damn

#

Ima do this backend stuff tmrw as it is 12am

woeful pike
#

rewrite it in rust but use .clone() to solve all lifetime issues instead of managing memory properly highIQ

earnest phoenix
#

no ty

#

rust hurts my brain

lament rock
#

Rust did not look appealing to me at all. The syntax was too much for my brain to process

woeful pike
#

it has a huge learning curve, very daunting I agree

cinder patio
#

The syntax is the best thing about it

lament rock
earnest phoenix
#

It makes my brain hurt

#

but I do admit it is a nice lang

lament rock
#

Their ambitions are admirable

earnest phoenix
#

I just find a lot of it is confusing

lament rock
#

thats all ill say

woeful pike
#

the community is so nice

#

has nothing to do with the language but

cinder patio
#

A statically typed lang where everything is an expression 🤩

earnest phoenix
#

community has everything to do with a language imo

slender thistle
#

Yeah comparing it to py or js, rust has it better with its userbase

lament rock
#

I can imagine a lot of rust devs are like c devs and wear pink thigh highs

woeful pike
#

compared to "learn to code js idiot ahhahaha" it's a breath of fresh air talking to people in the rust community about code stuff

earnest phoenix
#

If it has a bad community I am less likely to use it as I can't get any good support on it

earnest phoenix
#

😉

woeful pike
#

who's leaking our uniforms

lament rock
earnest phoenix
#

I have inside intel

#

I wont give up my source

#

My plan this summer is to get everyhting I need to make custom clothing

#

and make my own custom top.gg socks

earnest phoenix
lament rock
#

compiling a list of voice regions my bot comes across. If any of you have seen any not on this list, please tell me

pale vessel
#

can't you check through the rest API?

#

filter out deprecated ones

lament rock
#

No. The rest api doesnt show all of them

#

for instance, only people in south-korea can see south-korea

#

this was a while back obviously, but not much has changed

earnest phoenix
#

idiots usually have blue usernames/weeb pics

woeful pike
#

written by an idiot who could use it

#

like me

lament rock
#

There are certainly a lot more voice regions than that

earnest phoenix
#

why so many us

lament rock
#

because I live in the us

#

and the us is first world

#

people complain about audio quality

earnest phoenix
#

corona isn't real yk

lament rock
#

ur such a sussy baka

spark flint
#

Wait wrong reply

#

Fuck

spark flint
earnest phoenix
#

4k weeb pic

dry imp
#

what about green name and weeb pics?

lament rock
#

most likely idiots like myself

earnest phoenix
lament rock
#

lord have mercy on no colors

earnest phoenix
slender thistle
lament rock
#

I don't mess with libs that offer console colors. Just a waste of disk space

slender thistle
#

I see you there, green looking bastard!

lament rock
#

It wasn't an insult. All I said was god have mercy

slender thistle
#

Tbh I could use some mercy indeed

#

Thanks for keeping us nocolors in your thoughts brother 🙏

lament rock
woeful pike
#

living rent free

slender thistle
#

The only place where I can spend the night in peace

earnest phoenix
slender thistle
#

What are their matters? Do they lead foreign relations?

south elk
#

How to do in javascript addrole command?

#

@earnest phoenix

earnest phoenix
#

idk

south elk
#

why

south elk
woeful pike
#

I don't understand why I need to be pinged for this question

#

or anyone for that matter

spark flint
#

Get the role, give the role

#

Bam

earnest phoenix
#

give blue name role

#

the dark one

small tangle
earnest phoenix
boreal iron
#

Good joke smirk

woeful pike
#

bruh I need to move my db over to a managed db but I'm using a custom image

#

how do I solve this dilemma

onyx socket
#

how do you check whether the bot is present with application.commands scope enabled...
I have system where the stored data is deleted when bot leaves the server...
But i have added slash commands now, it would required invite from the new links....but to invite using new links, servers will kick the bot first, and that will delete their data...
If there was a way, where if bot leaves with app.commands scope, it will deleted the data else not, hoping that the kick was for reinvite

opaque acorn
#

No

boreal iron
#

you’re officially speaking for 190000 guild members?

spark flint
#

woah fake has pfp again??

boreal iron
#

Of course there are but don’t ask to ask.
Ask your question and wait for a response.

boreal iron
spark flint
#

lol

spark flint
spark flint
#

am trying rust now

#

how do i make a string an int

cinder patio
#

.parse

#

string.parse::<i32>()

spark flint
#

alr

woeful pike
#

bruh why waste your time with this stuff

#

but also, haskell

spark flint
#

they think js and py and c# are the only langauges

woeful pike
cinder patio
#

you sure

spark flint
#

very

#

she hardly knows python

eternal osprey
#

Hey i have a json file that looks like this: ```js
if(!test[message.member.id]) test[message.member.id] = {
name: [],
points: [0]

}``` How would i now get the top 7 entries that have the highest points?
spark flint
#

she didn't know py for <variable> in <array>: existed

cinder patio
#

All uni courses at least teach you the basics of C / C++

#

so like

spark flint
#

my college course i'm doing next year teaches c#

eternal osprey
#

And like, put them in an order of:

  1. Highest points
  2. 2nd place
  3. 3rd place
    etc etc
cinder patio
#

.sort and then .slice

eternal osprey
#

i was looking through the docs as i never really used sort that much

#
const array1 = [1, 30, 4, 21, 100000];
array1.sort();
console.log(array1);
// expected output: Array [1, 100000, 21, 30, 4]``` How does it sort?
#

ascending, but how can this be ascending?

#

we go from 1 to 100000 to 21"?

spark flint
cinder patio
#

parse returns a result

spark flint
#

oh ok

cinder patio
#

You need to check if it's ok before doing anythign else

#
if Ok(val) = string.parse::<i32>() {
   // val is guaranteed to be i32 here
}
woeful pike
#

YOU ARE WEAK

cinder patio
#

or if you're sure that it's going to be a i32 you can just do .ok()

woeful pike
#
let val = string.parse::<i32>().unwrap();
// val is guaranteed to be i32 here
#

REAL MEN

spark flint
#

lmao

#

rust wars

woeful pike
#

NO FEAR

cinder patio
#

imagine panicking 🤭

spark flint
#
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ParseIntError { kind: InvalidDigit }', main.rs:7:8```
woeful pike
#

certified skill issue

cinder patio
#

you imagined panicking

spark flint
#

idk if you can tell but i don't use rust KEKW

woeful pike
#

yeah you just have to learn what a number is you idiot

spark flint
#

ah yeah i'm just stupid

woeful pike
#

I love this about rust tho

#

you can't just ignore errors

#

I mean you can but when you do, you know exactly where

#

and your program doesn't just log an unhandled exception, it completely dies

cinder patio
#

🤤

woeful pike
#

if you know you have an error you know it's not a usable value and vice versa. Unlike stupid go

spark flint
#

ok fixed it

#
fn main() {
    use std::io::{stdin,stdout,Write};
    let mut s=String::new();
    print!("What is your age? ");
    let _=stdout().flush();
    stdin().read_line(&mut s).expect("Invalid input");
    if s.trim().parse::<i32>().unwrap() < 15 {
      println!("Sorry, you cannot watch this film")
    } else {
      println!("You are old enough to watch this film!")
    }
}```
#

ignore shit code

woeful pike
#

real unwrap hours

spark flint
#

i added .trim()

woeful pike
#

scoped use directive oh my

spark flint
#

it works so iara_shrug

cinder patio
#

s.trim().parse::<i32>().expect("Invalid input")

woeful pike
#

at what point would read_line fail anyways?

#

This function has the same error semantics as read_until will also return an error if the read bytes are not valid UTF-8. If an I/O error is encountered then buf may contain some bytes already read in the event that all data read so far was valid UTF-8.
hmm

cinder patio
#

If the bytes are not valid utf-8

#

yeah

woeful pike
#

I don't like this kind of interface tho

#

just feels like C

cinder patio
#

How would you design it?

woeful pike
#

I guess it's a bit tricky because the function can fail partially

#

maybe something like this?

enum ReadLineResponse {
  Success { bytes: usize, buf: String },
  Fail { error: io::Error, buf: String }
}

also not really pretty tbh

cinder patio
modest maple
woeful pike
#

mutate parameters yuck, but at least it's all documented in types unlike C

modest maple
#

pithink I mean the whole point is because its a stream

#

you dont want to be creating a new buffer every time potentially

#

far easier just to provide a mutable reference for that to fill the buffer instead a) for flow control and b) performance

woeful pike
#

yeah rust takes some shortcuts in the name performance like with these cases but it's still safe because of the language semantics

#

just ugly

modest maple
#

I mean it's also because its good practice

#

imagine if you wanted to read a line and a user passed you a 4GB line

#

and you have no control over how much you want to read into memory

#

thats what you'd have if you had it just internally do it

#

bearing in mind exposing it like this also allows us to use like virtual memory etc... without re allocating and/or having to first load into memory entirely anyway

cinder patio
#

yeah that's reasonable. Maybe the interface could be a little different though... like maybe have readline return a struct which you can .collect(), or .append(&mut buf)

modest maple
#

well by convention append affects self mutably not the other way around

#

and collect generally implies an iterator which can be drained and merged into a type without erroring

#

also for the most part in the real world, you just dont read console input like ever

cinder patio
#

well yeah you could think of the console input like an iterator, just throwing ideas around

modest maple
#

that would probably be quite in efficient

cinder patio
#

Just as an abstraction, ex. doing .next() would just read a single byte

#

until it hits EOF

eternal osprey
#

Feud, it is not possible what you stated.

#

The sort isn't applicable on nested objects right?

#
let database = {"key1": {points: [5]}, "key2": {points: [3]},"key3": {points: [4]}}
for (const key in database){
let g= database.sort(function(a, b) { return a[key].points - b[key].points});
console.log(g)
}```
cinder patio
#

It works only for arrays

#

You could do Object.values(database)

#

Also get rid of that loop

#

also this is your daily reminder to stop using a json database.

#

makes it a lot harder and inefficient

#

with a proper database you could to this with a single query

modest maple
woeful pike
#

order by gang

modest maple
#

cluster keys gang

woeful pike
#

all I know is when I have a knee jerk reaction to a design choice made on something as fundamental as doing IO, I know the people working on it have spent like 50x more time thinking over it than I have criticizing it

#

so there's almost certainly a good reason for it if it doesn't feel super optimal

cinder patio
#

If I had to read from console once or twice I'd just use read_line, but if I had to read very very often at many different places I'd probably use an interface which makes it easier. It's a balance between memory and io calls. .next could read a chunk of bytes and save them into memory. When it runs out of bytes, get another chunk. until EOF.

modest maple
#

but how much buffer? What if the buffer read returns an error?

#

generally also allocations like that are better to be explicit rather than implcit

cinder patio
#

If it strictly has to implement the Iterator trait, if the buffer read returns the error then .next would return None as if it ran out of bytes to read, maybe a custom method to tell what exactly happened. If a custom implementation, .next would return an Empty / Err / Ok enum. As for the size of the buffer, /shrug

cinder patio
#

maybe the max size of the buffer is something the user could define?

#

With a default if they don't

spark flint
#
main = do  
    putStrLn "What is your age?"  
    inputtedage <- getLine
    let age = read inputtedage :: Integer
    if age < 15 then print ("Sorry, you cannot watch this film") else print("You are old enough to watch this film!")```
#

am i stupid

#

what is wrong with that

#

ok wait i fixed it

modest maple
#

well whats the error

spark flint
#

main.hs:5:71: error: parse error on input `then'

woeful pike
#

you don't use parentheses to call functions in haskell

spark flint
#

oh ok

woeful pike
#

normally you'd write this as

putStrLn $ if age < 15 then "Sorry you cannot watch this film" else "You are old enough"
#

equivalent to

putStrLn (if age < 15 then "Sorry you cannot watch this film" else "You are old enough")
#

the () is being used to group the big expression, not to call the function

#
getAge :: IO Int
getAge = read <$> (putStrLn "What is your age?" >> getLine)

decision :: Int -> String
decision age
  | age < 15 = "Sorry, you cannot watch this film"
  | otherwise = "You are old enough to watch this film!"

main :: IO ()
main = putStrLn =<< decision <$> getAge

kekw

lyric mountain
#

that's so shitty but...oddly readable

woeful pike
#

once you understand what all the symbols mean it's actually really pleasant

lyric mountain
#

what is <$> for?

woeful pike
#

f <$> a is the same as fmap f a where a is some kind of container and f is a function that converts the contents of the container to some other thing

#

it's a generalized version of array.map

#

or promise.then which are both the exact same thing conceptually

#

so you take a Promise<number> aka IO Int in haskell and convert it to IO String by applying Int -> String over it with fmap

#

getAge().then(decision).then(console.log) except in js >>= and <$> are both the same method .then for some reason

lyric mountain
#

ELI5 pls

#

oh wait

#

fmap stands for flatmap right?

woeful pike
#

no but they are very similar concepts