#development
1 messages · Page 250 of 1
i think so?
if you're writing a wrapper then presumably you have ownership of the resource the whole time so there's no way for it to escape
like your wrapper won't give other parts of the code access to the raw db underneath
ofc i love yapping about c# <3

I am honestly getting more interested in C#
dk if you saw me yapping about it, but I have recently taken on the hobby of writing rust plugins (the game not the language)
so C# has become my new cup of tea, only thing is my code is hardly performant
I wrote something that while worked, was definitely the worst possible way to code it
It used multiple loops, some even nested, a lot of if statements that caused other loops

i dont think c# has a borrow checker from what ive heard
C# is great
I’m going to be primarily a C#/ASP.NET developer for my new job and I’m so glad they don’t use dogshit frameworks
const Topgg = require("@top-gg/sdk")
const express = require("express")
const app = express()
const webhook = new Topgg.Webhook("your webhook auth")
app.post("/dblwebhook", webhook.listener(vote => {
// vote will be your vote object, e.g
console.log(vote.user) // 395526710101278721 < user who voted\
// You can also throw an error to the listener callback in order to resend the webhook after a few seconds
}))
app.listen(80)
how i can get my webhook auth
no
don't ask me for click unknow links please !
I don't know, your profile is strange, your server is strange, everything is strange. Thank you for your help
No, I just have a mind that thinks someone sent me a server with about 70 people, the same pfp and the same name, and you also sent a strange link asking me to enter the server? Look if you wanna help help
do not contact them @naive pulsar
@oak cliff scammer @gray plume
deleting your messages won't do anything you realise we have logs? @gray plume
i will
they're a scammer, suit yourself
Dont think thats what they meant
Also, i already pinged a mod about that exact person
how are they still here
💀
insane
crazy
reported internally, someone will see
We need more mods 
Only by reviewing his account do you find that he is a scammer of the degree of stupidity
lmao
Let me scare them out of the server 👀
no
they'll be banned anyway no point
Hm
http://yourserverip:port/dblwebhook so if i using hosts service etc how i can get then server ip i'm still confused
From your vps
but if you’re not using vps, you have to configure your windows host bs
shi
i can't use my api ?
like api.bot.xyz/dblwebhook
you can
Mine is setup like https://oliverbot.xyz/api/dblwebhook
My nginx points to my api
do you have docs or something to how i can do like this
currently not at this moment because im currently at school and i don’t have my laptop with me
Wait
Wait
np dude when you back or anytime you can send it take you time : )
location /api/ {
proxy_redirect http://localhost:8000 https://oliverbot.xyz/api/;
proxy_pass_header Server;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_connect_timeout 5;
proxy_read_timeout 240;
proxy_intercept_errors on;
proxy_pass http://127.0.0.1:8000;
}
My nginx config
this is
Ye
If you want @real rose if he wants to, he can help you with nginx
i see ill use youtube ig he will not respond
He’s currently doing stuff in irl probably
this guy dm me also and ask me how to get top.gg api
where is your api hosted?
vercel
yep i did't do anything wrong ig
also not top.gg
api
then you can create a route there for topgg webhook
but your bot is not running there is it?
yep
this make me wondreing
i must to move
all
daliy coins code
what do you want to do with the vote?
give the user some coins
where is the bot's database?
moongoose i can do it at api but api at vercel goes to sleep
after no request for like 5m
local mongo or mongo atlas?
atlas
then you can connect to atlas from the api directly
topgg webhook -> vercel api -> mongo atlas
dont need to access the bot
yeah but vercel host goes sleep after no request for 5m
so if you vote you will not get a coins
oh !
So I need to add my api to topgg webhook then by express.js get a post of vote ?
Does vercel even support express?
Turns out it does.
https://vercel.com/guides/using-express-with-vercel
neato
you dont need express
you dont need topgg lib either
a vote webhook is an http request like a page view or route access
you just create a route in your vercel app, and put the url in topgg
and your vercel app will receive the request in that route
yes
ye
export async function POST(req) {
const voteData = await req.json()
}
Yep ig it wasn't possible then I found a way to use it was so useful for me
yeah, that should get the everyone role
so now what happend if someone fake a post
app.post('/vote', async function(req, res) {
const VoteDate = req.body
console.log(VoteDate)
});
i mean now anyone can get a unllimit votes
use postman
then fake posts
how i can fix it
scam
I think that's what the "Authorization" field is for
yeah ig this soo
but
how i can get it
amm
i can't see ip while post
you're the one who defines what the authorization is
thats what authorization is for
nvm tons of people already said it lmao
Your message has an extra aura
lmao
the authorization by ip
or token
i didn't get it yet
hey guys my brain is literally not braining today,
// calculate timestamp of log,if it is within 24h, stop,
// if it is within 48h, give points. Outside 48, lose streak.
is this valid logic for achieving the following:
- user daily streaks.
idk, like suppose the timestamp is within 24h compared to the past one, it is still the same day right. So we just break.
But if the timestamp is within 48h, it is the next day, and we then update timestamp.
Buuutttt, if the timestamp is outside 48h the user forgot to maintain their streak right?
check request headers
topgg sends an "authorization" header
the value of the authorization header is the string that you put in your topgg settings (url + auth)
for example:
url = api.nuvex-bot.xyz/vote
authorization = abc1234
code (pseudocode):
if(request.headers.authorization !== "abc1234") {
return request.send("invalid request")
}
i see
thanks dude
you helped
me so much
all respect 🫡
sounds correct
but you want to count 24h from where? since last timestamp or something fixed like midnight UTC?
EST
i log each time a user performs a certain action
that is when the "timer" starts.
What are u trying to do? There might be a better way
I have 4 cases, they all work based on a previous timestamp i saved:
user does action x at timestamp t2 -> owh no, t2 is still on the same day! -> error
user does action x at timestamp t3 -> t3 is the next day, Yaaay!
user does action x at timestamp t4 -> t4 is 2 days later, nooooo!
why not store timestamp on database?
i do
then simply compare with current date
yeah i calculate the difference in hours
i was just figuring if my logic was correct
it's best if u work with millis, this way u dont go into float shenanigans
ah yeah that's true
to get length it's just current_millis - previous_millis
yeah i got everything setup already, but indeed i might move to millis instead of hours
question! so what’s a good way for me to get players feedback?
basically what i’m thinking
i have some responses that the bot sends based on certain keywords via event listener
but i want players to have a chance at submitting some funny responses
so i was thinking maybe i can send an embed at the end of my clickwar game for ppl to click and submit, but how can i do that and actually get their responses?
in the console log?
oh
I have this to detect if someone votes on my bot, But it doesn't work..
I just added the topgg webhook, I don't have a custom website.
I just want to see who voted on my bot, and give them rewards
where is your bot hosted? what did you put in your topgg bot settings?
also, why are you creating an Api instance if you're not using it anywhere?
meaning link them to create a ticket in my server?
no, like having a ticket command that people use to submit feedback
but you can always link them your server and tell them to go there
I honestly don't know
but how would i receive the feedback? in the console log?
webhook-topgg and having your own webhook listener doesnt work.
You can choose 1 or the other
you are using a third party website that redirects votes to discord, not to your bot
idk you decide
can be console.log, can be fs.writeFile, can be database
fs.WriteFile?
hm
you can also just have your bot post on some channel in your server
i like this
How do I redirect it to my bot?
where is your bot hosted?
It's hosted on a panel
what panel?
The way webhooks will be handled will often depend on the host.
like, at home?
contact the owners of that host
ask about ip address and port
i have ip adress and port
then your URL is http://ipaddress:port/vote
yeah but i saw this when i looked it up too
but i thought it was for websites with custom vote page
webhooks, and webhook urls are not for websites.
The way I like to explain it, is it uses the same communication methods as a website, but its for computer to computer communication.
I see
It's weird to explain but basically we have a online PC (i forgot what that's called) and it's just made into a nice panel
I also forgot what that panel is called
alright then just do that, ip address and port, plus whatever path you have in your express listener
how do I know where my express listener path is
i dont have access to the server
only the panel
/vote is the path
The port in code, in your url needs to be the same.
If the server has any firewalls it must be allowed
you're freaking awesome man. so i did this, i even added an "Accept" button that will DM the user who submitted the suggestion to tell them it's be accepted.
but now i'm thinking about when i have to restart the bot
the accept button wouldn't work anymore
why shouldnt it work.
so i'm guessing i can add this to the database, adding a table to keep it working
because i didn't make a table for it in sql
it's just in the bots memory
so if i restart it wouldn't work (i think)
im new to databases so idk
i can restart my bot. And the buttons still work after. No DB
@solemn latch sorry for the tag
let me try
you give them custom IDs? right.
This looks like sftp, not http.
Should be required
Its saying SFTP
I've seen some panels say weird things due to poor configuration by the owner.
So I try not to assume 😄
ouf
I'm not sure what that is, since we dont know what panel software you're using.
It might work? I'm not sure.
I'd suggest reaching out to whoever set it up tbh.
Or reinstall it. When you are the owner
it sounds like the panel is a group thing, with multiple people using it. another person might know.
Sadly, its just a guessing game without more information.
yessir
I will try to find out what kinda host it is
@solemn latch omg after long searching
PufferPanel
VPS connected to PufferPanel
that doesnt really help
you need to see which ports are open for you to use
and whether there is any internal redirection
does the panel show any "public url"?
or public ip port?
Right so im using lmdb, but I am not sure the approach I want to go for.
I can either go nosql route like mongo and it basically just be a json table, or I can go the postgres route and have rows / columns and eventually support relations
although if you have access to sftp, then it might be a full vps, and not an app hosting panel thing
if you have access to the full vps, then the port is the one you define inside your code, in express
you just need to check if there are any firewalls installed
well the host is closed off since it's a panel you need to login to
the master url is the website
try creating a basic express app
just a single app.get("/")
and run it on some random port, like 3000
then try to access it and see if it works
both with ip:3000 and with website:3000
the website port is 8080 tho
you cant use a port that is already used
ohhhh
i see
does an offline port work?
If I take a port of one of the servers that is offline
you can, but you can chose a port that is not used by anything
the program will create the port for you
unless there is a firewall that blocks ports that are not configured
yeah there is a firewall which he had to manually add so it could work
good website to upload terms of service for bot verification?
github is a free website host
You could technically use pastebin
free meaning that github can cutely feed your source code to train an LLM
Yummy data
mmmmmmmmmm
Yummy api secrets I'm going to use as examples for others
mmmmmmmmmmmm
console.log("current", timestamp)
console.log("previous", user[0].last_logged_timestamp)
const differenceInMs = timestamp - user[0].last_logged_timestamp;
console.log("difference", differenceInMs)```
is this an overflow that is happening?
numbers don't make sense
timestamp is Date.now() ?
It depends on the type of timestamp it is
Sometimes they are in seconds, other milliseconds
that 000 one is a unix timestamp
Its in milliseconds
As you can see
current & difference are in milliseconds
previous is in seconds
Its not overflow its just different formats of timestamps
Depends if they really want to train their model on my shitty code 
the more shit code the better, so that ai cant steal our jobs
:^)
I just created this Auth page for my program and then i noticed that i cant use it because of Spotify copyright and stuff
cant u just remove the logo?
Isnt the name copyrighted too?
thats not how copyright works
sure i can
it just means the name is "claimed", you can still use it yourself as long as its clear its not related to you
I mean, spotify also has a trademark, you cant use the name Spotify anywhere without permission
BUT this only applies to things you make
I wanted to make the program public. Thats why i ask
if you're using spot's oauth2 then this doesnt apply to that, because it's their site
i use that. But the auth page that you see is coded by me
Not by spotify
just to make it clear, you're not using oauth2?
I use this.
this is oauth2 i guess
and when you link my app with the program
you get redirected to the page youve seen
yes that's oauth
I added it because otherwise nothing would be displayed
you can make references to their name as you've just came from their site
okay
basically, you're only allowed to use their logo/name if it's linking to their site in some way
or if they give you permission for other purposes
Okay. Thanks for you help!
i mean
just publish it
the most it will happen, if anything, is they ask you to remove it
once i was working on a website for a friend, he had a shop and sold some products
and wanted to mention that his shop accepts payment throguh payoneer
and he got a c&d email from them
lmao
or you get a c&d
i replied to that email asking for more details about it, but they never responded. after a month of waiting we just removed the payoneer payment method from the shop
they never replied, nor followed up
they just use automated bots and scanning shit for copyrighted words
and send automated email threats
spoofify
Spot!fy
Goofify
What is the best you to make OTP for my website ? Use nodemail I just wanna a way to block him to send many OTP also if he write many wrong Password and rech limits got ban for like 5m I just will use a Cokies to save times of send and last send was when but if you guys have a better way please say it
i wouldnt use cookies for that
use the user account in the database
track login attempts there
music bot.. is it hard to do? 👀
Unique*
this is Fr3e server
Nah, we pay Tim monthly to send messages on this channel
Lol
yes
same thing
if i defer a button with deferUpdate, could a channel message be the interaction acknowledgement?
the acknowledge is the deferUpdate itself
so what would i use to have the button acknowledged and a channel message send as a result of that button tap?
basically in click war, the players have lives. i have a “swap lives” button but i don’t want it to send an ephemeral.i want them to tap it and the bot sends a channel message who the user swapped with. it does that, but it also gives interaction failed, no errors in console logs. so i assume the button works fine, just dk the best way to have it respond without interaction failed.
import EventEmitter from 'events';
export interface PlaneWebhookEvent {
event: 'issue';
action: 'deleted' | 'updated';
webhook_id: string;
workspace_id: string;
data: Record<string, unknown>;
activity?: Record<string, unknown>;
}
const webhookEvents = new EventEmitter<{
'eventHere.actionHere': [PlaneWebhookEvent];
}>();
export default webhookEvents;
How can I make the types on eventemitter like that?
dynamic..
ok wait
got it nvm
you're using a followup? you have to use at least one reply
ohhh
so i don’t need to defer
because follow-up
you just have to remember this rule:
interaction -> reply -> followup
interaction -> defer -> reply -> followup
@quartz kindle hey tim i need your help here
may i slide you a invite real quick, i need you teach a friend how ports 443 and 80 works
What are they having problems with
he think you cant use same port for different websites
Nginx works based off a technique called "virtual hosting"
Specifically name based virtual hosting
Right I got it partially wrong
When a user visits a domain example.com the browser will perform a dns lookup to resolve the IP address behind that domain, it will then send a HTTP request to that ip with the domain in the Host header. Nginx then examines this header to determine which server block to route the request to. It does this by comparing the value in the Host header and the one defined in server_name in your blocks. Once it finds the right one it will serve the content at that location
thanksss
The reason everything is able to seemingly run on one port is because all of those aren't actually running on a single port
Well they are, its just not in the sense you think
nginx as the service is listening on port 80 & 443
otherwise there would be no need to proxy pass your stuff, and what not.
when you are doing listen 80; you are essentially saying have this website listen on the nginx port 80
thanks misty
thats what a webserver software does
listen to X port, examine requests that come in, and do somegthing with them
you could literally run nodejs on port 80 and check headers yourself, and handle multiple websites with a single nodejs program
or redirect them elsewhere if you prefer
yeah nginx is better at it because it was made expecially for it
ye
btw tim
while you are here
I has a question regarding my db
Since I am using lmdb, I figured why not just try and make a relational database.
Problem is, how exactly should I keep track of table structures & relations properly
should I just use indexing and what not?
Create an additional file alongside the db files that keep track of relations?
many ways you could do that, but in general you use and abuse lmdb's key-value
store everythign as a key value
table structures, relations, indexes, etc

How would that work?
Seems like it would be a pain in the ass to make sure everything stays where it should & look it up appropriately
tables -> array of table names
tables:name -> structure for table
index:table:col:value -> index for table col
index:table:col:value2 -> index for table col
index:table:col:value3 -> index for table col
etc
you can also create seperate lmdb databases for some of those
create keys like this
const eloKey = ({rating_type, leaderboard, versus, teamSize, id}) => {
if (rating_type === 'distinct_team') {
return [rating_type, id, leaderboard, versus].join("|")
}
if (rating_type === 'combined_team') {
return [rating_type, id, leaderboard, teamSize].join("|");
}
if (rating_type === 'distinct_player') {
return [rating_type, id, leaderboard, versus].join("|");
}
if (rating_type === 'combined_player') {
return [rating_type, id, leaderboard, teamSize].join("|");
}
if (rating_type === 'overall_player') {
return [rating_type, id, leaderboard].join("|");
}
return 'error_invalid_rating_type';
};
module.exports = eloKey;

store keys in the key
["settings", guildId, userId].join("|");
like the guild and user ids
foreign key
if you store it this way it's the fastest lookup
since you lookup by key
it's like a composite key
Try now done a bunch of improvements to design and performance tweaks including a neat loading section 🙂 https://devspace.fluxpoint.dev/
looking great
loads pretty nicely now

Some stuff is a little broken with the design changes but it's gonna be a lot better in the long run
Gets better when u start using intellij or one of the other ides
Cuz u get all of datagrip on top of the ide
I've been using it to edit in-db scrips with intellisense since forever, couldn't go back to other tools even if I tried
IntelliJ stuff is bussin bussin, really has everything you need and doesn’t cost much
little confused on this actually, what is this -> index for table col
Does that not defeat the point of the key being an index:table:col:row
it's so you can paginate through the table in addition to lookups by key
yeah i didnt write it correctly, i meant you can use lmdb's key-value for the indexes
for example you want an index in table users, column id
you can do it like index:users:id:374958739487 -> table row

wait
isn't the numbers after id the value of that row?
Im a little confused on your thought process
the numbers would be the user id
the user id is indexed, so it has to be fast to query
so it needs to be part of an lmdb key

and the value for that key is the row you are querying
or some sort of unique row id
something that links to the desired row
basically, database indexes are just a key->value map
and it links to keys in the other one
you could create a separate database for this
but lmdb is made to handle data like this
similar to redis
to separate it from other types of keys that are stored in the same database
icic
for example table structures
or whatever else shares the same db
you basically create namespaces inside a single db to separate the data
and lmdb can do range queries
so you can query all keys that start with said prefix, for example
so
index:users(table_name):id(column):11231231233(valueOfId) -> 11231231233
index:users:name:11231231233 -> Jane Doe
Actually working with it all will make sense
I assume appending the id would make it faster to query since i can look it up based off id
since its an index, the purpose of it is to quickly find a row in a table, to prevent having to scan the table to find it
so the value that is being stored has to resolve to the full table row
so it has to resolve to everything for that entry?
yes
if I am storing a name, phone number, email, etc
if I look it up, it has to return all that?

you dont create an index in a db to find only that column
I wonder how that will work code wise
you create an index to find the row based on that column
is that the point of primary keys?
yes
interesting
but primary keys are also unique row ids
which by themselves alrewady are an index
so they have to be unique
just stored in a different namespace
for example
rows:999999 -> [john doe, 78798942342, abc@xyz.com]
index:users:id:78798942342 -> 999999
yes
interesting
the names of the columns would be defined in yet another namespace
yknow, that makes sense if you look at a db viewer
the full thing can be something like
I assume the order of the values put into the array matter
else they will get mixed up
what should be the phone number column, ends up having a value from the name column
or smth like that
tables:1 -> [id, name, email]
rows:1:79287349823 -> [111111, john doe, abc@xyz.com]
indexes:1:id:111111 -> 79287349823

yeah it has to match the structure of the columns
the columns are always ordered
icic
Well, this gave me some guidance
thanks a lot
Hopefully I will have smth to show you at the end of the week
good luck!
Im still debating on whether or not to make my own sql language
or just pull an EF Core and make a wrapper around the database
not even sure where i'd begin writing my own sql language 💀
Whats the difference between IAsyncDisposeable vs IDisposeable? I see some sources recommend using it together but not sure why.
asyncdisposable is newer and there's a big warning on the page so
real
HI, i have question possible can we make the embed like this
Name : Test
Detail : Hello world
what do you mean?
like this?
yea but it like got a square
around the word
or like use any custom character to do
Name : Test
Detail : Hello world
``` like this?
nope wait
?
like this but the box outlike replace with -----------------
yea
that's what I did lul
something like this
not the XX
it's the same thing, it's just that embeds make the black bg smaller
what can i decoration with it?
le olde ascii graphics
how to do it like that then
if you're on windows, press Win key and search "charmap"
oooooor there's a site for that ofc
theres always an app for that
:^)
it still not show for the bot did i miss something?
how could i put in the middle line?
you cant do that
uh
if you want to make it in a single block, you must use description
fields must always have a name and a value, and they are disposed in a 3-column (1-column for mobile) way
ok
Does Discrod API support the new guild system?
Like is it possible to fetch somebody's current guild tag?
oooo browserling
i love opening trojan and malware sites there
Okay for anybody wondering in the future, neither Discord API or any Discord.js versions support it yet
it'll probably support eventually, it's just that it's still in thanos-beta stage
banners took a long time to be documented in the api
i sometime got bug
some time no error
is tere a way to fix? the problem only start with when the command was use for 2 time
the first run notthing problems
is there like completely remove the cooldown? if remove does it will impact anything
my friend do it for me
after i edit the last part which is the photo i send before then it crashes
ask your friend to fix the error, you can't really attempt to fix something like that without understanding what the code is doing
ah, fortune, I remember you
usally like for discord api what is the minimum timeout for the bot
replace command.cooldown to command?.cooldown
async function calculateBet(data: any, sportsBook: string): Promise<number> {
const probability_winning: number = 1 / data.previous_price;
const probability_losing: number = 1 - probability_winning;
const bet_return: number = data[sportsBook + "_price"] - 1;
const base_price: number = (
(probability_winning - probability_losing / bet_return) *
100
).toFixed(2);
const recommended = (base_price * (1 / 3)).toFixed(2);
return recommended;
}
huh base_price is a string according to ts?
owh damn that's intersting
for example, 2.0 doesn't have 1 decimal place
cuz 2 == 2.0 == 2.000000000000
it only has a fixed decimal count when viewed as a string
if you want to truncate to a certain precision, you have to multiply, truncate and then divide
((value * 100) | 0) / 100 will truncate to 2 decimal places for example
add/remove zeroes to 100 to change how many decimals are kept
why dont you type the data argument
async function calculateBet<Book extends string>(data: Record<'previous_price' | `${Book}_price`, number>, sportsBook: Book): Promise<number> {
holy hell that's big
thats not big
i see!
the data is a big object
way too big to parse it so i just defined it as any
yea this accepts any object that contains these things
wait really?
yes
new to ts so this is awesome to learn
i like ts as it combines 2 things i like, js and java
okay not really java but idk i find it similar tbf
like the whole type system, the objects and classes
@quartz kindle how would you speed this up?
for (const entry of entries) {
const reversed = Buffer.from(entry.bytes_buffer).reverse();
for (const e of entries) {
if (e.bytes_buffer.compare(reversed) === 0) {
console.log("Duplicate found!");
process.exit(1);
}
}
}
this function basically goes through each entry, clones & reverses the buffer (since you cant reverse without making a copy of the buffer) and then goes through each entry to see if the reverse matches any other buffer
with 100k elements this takes very very very long
im guessing its mainly from the buffer copying with Buffer.from and the reverse method
i'll try to substitute that first
const reversedMap = new Map()
for (const entry of entries) {
const reversed = Buffer.from(entry.bytes_buffer).reverse()
if (reversedMap.has(reversed.toString('hex'))) {
console.log("Duplicate found!")
process.exit(1)
}
reversedMap.set(entry.bytes_buffer.toString('hex'), true)
}
could help
(will help)
sender.ts:
module.exports = { sendData };```
receiver.ts:
```tsconst { sendData } = require("./sender.js");```
is this allowed/possible?
i know ts mainly uses import from
its a war crime
yeah that is much faster lmao

only in javascript can you convert bytes to a string and use a map and it becomes much faster
although its probably because this only iterates 100k times as opposed to 100k*100k
I mean previous solution was O(n²)
i see, but is it possible? Cuz when i hover over to it it doesn't display the function signature
this is O(n) yeah
also, should i require from the .ts or the compiled .js
typings wont work
why would you want to use require
cuz import from gives me this problem:
sender.ts(7, 16): 'sendData' is declared here.
import sendData
why are you importing the js file
module.exports = { sendData };```
i might be ugly and retar3ded though
really? I never knew that was a thing
wow i deadass suck
or export { sendData }
i always though that you MUST use module.exports = {...}
instead of just export {..}
well if you are using cjs yes
but cjs is a curse that nodejs brought upon us many years ago
const reversedSet = new Set();
for (const entry of entries) {
const reversedHex = entry.bytes_buffer.toString('hex').split('').reverse().join('');
if (reversedSet.has(reversedHex)) {
return "Duplicate found!";
}
reversedSet.add(entry.bytes_buffer.toString('hex'));
}
return "No duplicates found.";
i did the same thing just now but without the splitting
const reversedSet = new Set();
for (const entry of entries) {
const reversed = Buffer.from(entry.bytes_buffer).reverse().toString();
if (reversedSet.has(reversed)) {
console.log("Duplicate found!")
process.exit(1);
}
reversedSet.add(entry.bytes_buffer.toString());
}
you can actually just convert the buffer to a string and you can use it as a key for the set/map
no need to convert it to hex or anything special
it will still hash the same
did you test if thats faster?
didnt see if its faster but i can benchmark
Im late to the party, but why exit the process if a reversed has been found.
Also, sets can't take in duplicates anyway right, so why check if it already exists?
I could imagine sha1 hashing the buffer may also be fast
since map lookups need less chars
this is "code to fulfil a specific purpose for only this instance which i will never use again" type of code
and theres code later on that i dont wanna comment out
which two do you want to benchmark
i want to benchmark four
hold on, let me rewrite it in zig
great
no
ben,me,you,me but with sha1
sha1 should be much slower since it also calls openssl and adds an extra step but sure
plus theres a very small chance of collision which would make this unfit for purpose because of the risk
hold up lemme just write an sha1 function in pure js
ok this is not sha1 but its good enough i think
function rotateLeft(n, s) {
return (n << s) | (n >>> (32 - s));
}
function toHexStr(n) {
let s = "", v;
for (let i = 7; i >= 0; i--) {
v = (n >>> (i * 4)) & 0x0f;
s += v.toString(16);
}
return s;
}
function sha1(buffer) {
let words = [];
let message = new Uint8Array(buffer);
let messageLen = message.length;
for (let i = 0; i < messageLen - 3; i += 4) {
words.push(
(message[i] << 24) |
(message[i + 1] << 16) |
(message[i + 2] << 8) |
message[i + 3]
);
}
let remainingBytes = (messageLen % 4);
let lastWord = (remainingBytes === 3 ? (message[messageLen - 3] << 16) : 0) |
(remainingBytes >= 2 ? (message[messageLen - 2] << 8) : 0) |
(remainingBytes >= 1 ? message[messageLen - 1] : 0);
words.push(lastWord << 8 | 0x80);
while ((words.length % 16) !== 14) {
words.push(0);
}
let h0 = 0x67452301;
let h1 = 0xefcdab89;
let h2 = 0x98badcfe;
let h3 = 0x10325476;
let h4 = 0xc3d2e1f0;
words.push(0);
words.push(messageLen * 8);
for (let i = 0; i < words.length; i += 16) {
let w = words.slice(i, i + 16);
for (let t = 16; t < 80; t++) {
w[t] = rotateLeft(w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16], 1);
}
let a = h0;
let b = h1;
let c = h2;
let d = h3;
let e = h4;
for (let t = 0; t < 80; t++) {
let temp;
if (t < 20) {
temp = (rotateLeft(a, 5) + ((b & c) | (~b & d)) + e + w[t] + 0x5a827999) | 0;
} else if (t < 40) {
temp = (rotateLeft(a, 5) + (b ^ c ^ d) + e + w[t] + 0x6ed9eba1) | 0;
} else if (t < 60) {
temp = (rotateLeft(a, 5) + ((b & c) | (b & d) | (c & d)) + e + w[t] + 0x8f1bbcdc) | 0;
} else {
temp = (rotateLeft(a, 5) + (b ^ c ^ d) + e + w[t] + 0xca62c1d6) | 0;
}
e = d;
d = c;
c = rotateLeft(b, 30);
b = a;
a = temp;
}
h0 = (h0 + a) | 0;
h1 = (h1 + b) | 0;
h2 = (h2 + c) | 0;
h3 = (h3 + d) | 0;
h4 = (h4 + e) | 0;
}
return toHexStr(h0) + toHexStr(h1) + toHexStr(h2) + toHexStr(h3) + toHexStr(h4);
}```
ill have to benchmark it manually because the benchmark tool i use is only browser js and browser js doesnt have buffer
it has uint8array but the .toString() method works differently and likely much slower
this is the improvised benchmark
function chloe() {
const reversedSet = new Set();
for (const entry of entries) {
const reversed = Buffer.from(entry.bytes_buffer).reverse().toString();
if (reversedSet.has(reversed)) {
console.log("Duplicate found!")
}
reversedSet.add(entry.bytes_buffer.toString());
}
}
function ben() {
const reversedSet = new Set();
for (const entry of entries) {
const reversedHex = entry.bytes_buffer.toString('hex').split('').reverse().join('');
if (reversedSet.has(reversedHex)) {
console.log("Duplicate found!")
}
reversedSet.add(entry.bytes_buffer.toString('hex'));
}
}
function hex_username_man() {
const reversedMap = new Map()
for (const entry of entries) {
const reversed = Buffer.from(entry.bytes_buffer).reverse()
if (reversedMap.has(reversed.toString('hex'))) {
console.log("Duplicate found!")
}
reversedMap.set(entry.bytes_buffer.toString('hex'), true)
}
}
chloe();
console.time("Chloe Function");
chloe();
console.timeEnd("Chloe Function");
ben();
console.time("Ben Function");
ben();
console.timeEnd("Ben Function");
hex_username_man();
console.time("Hex Username Man Function");
hex_username_man();
console.timeEnd("Hex Username Man Function");
@neon leaf surprisingly your map function performs faster consistently
Ben Function: 128.123ms
Hex Username Man Function: 82.781ms
Chloe Function: 94.153ms
i have no idea why, just doing toString and using a set which has less overhead should be much faster than using a map and converting it to hex twice
slowest?
yeah what thats the slowest
@quartz kindle please explain
makes perfect sense
what do you mean slowest
biggest number = bad
yes i posted the benchmark
bens split function is slowest
const crypto = require('crypto');
// Generate test data
function generateTestData(size) {
return Array.from({ length: size }, () => ({
bytes_buffer: crypto.randomBytes(32)
}));
}
// Original function
function originalFunction(entries) {
for (const entry of entries) {
const reversed = Buffer.from(entry.bytes_buffer).reverse();
for (const e of entries) {
if (e.bytes_buffer.compare(reversed) === 0) {
return "Duplicate found!";
}
}
}
return "No duplicates found.";
}
// Optimized function
function optimizedFunction(entries) {
const reversedSet = new Set();
for (const entry of entries) {
const reversedHex = entry.bytes_buffer.toString('hex').split('').reverse().join('');
if (reversedSet.has(reversedHex)) {
return "Duplicate found!";
}
reversedSet.add(entry.bytes_buffer.toString('hex'));
}
return "No duplicates found.";
}
// Performance test
function runPerformanceTest(size) {
const testData = generateTestData(size);
console.log(`Testing with ${size} entries:`);
console.time('Original Function');
originalFunction(testData);
console.timeEnd('Original Function');
console.time('Optimized Function');
optimizedFunction(testData);
console.timeEnd('Optimized Function');
console.log('---');
}
// Run tests with different sizes
[100, 1000, 10000].forEach(runPerformanceTest);
that's the test i ran
robert ~/projects node sha1.js
Chloe Function: 122.715ms
Ben Function: 144.211ms
Hex Username Man Function: 83.672ms
Hex Username But With SHA1 Function: 277.187ms
woops
everything about js is opposite
something that should logically be faster is actually slower
i mean the results make perfect sense to me
doing 2 array actions instead of 1 is obv slower
Buffer.from doesnt actually clone the data
it just points it to the old position and slices modified data
well bens benchmark yes but yours one convert the string to hex and uses a map which has extra steps but its much faster
i tried it in repl and using .reverse() on the new slice makes a clone and doesnt modify the original
but it doesnt matter here
well in js you wont see that
v8 doesnt clone though
thats why you always use the offsets when converting to ArrayBuffers
since those are not building on top of the original
helpers/parsing.ts:1:20 - error TS2732: Cannot find module '../config.json'. Consider using '--resolveJsonModule' to import module with '.json' extension.
1 import config from "../config.json";
~~~~~~~~~~~~~~~~```
huh why error men waddafuck men
hold on ill convert yours to a set and see how it performs
about 2ms faster
how would you do it then without reversing
are you just comparing it backwards?
i just directly compare
all are reversed anyway
so if none are reversed its the same effect
lmao i specified the encoding in my toString() and its faster than yours
not by much though
and if I dont reverse I can use the v8 object id
function hex_username_man() {
const reversedMap = new Map()
for (const entry of entries) {
if (reversedMap.has(entry.bytes_buffer)) {
console.log("Duplicate found!")
}
reversedMap.set(entry.bytes_buffer, true)
}
}```
try this
but the value isnt used anywhere?
with this youre just seeing if theres any duplicates
i want to see if the reverse of any of the buffer bytes matches each one
or are the entries themselves reversed
so if you have an array [[1,2,3], [3,2,1]]
the function should return duplicate found
because 1,2,3 reversed is 3,2,1
robert ~/projects node sha1.js
Duplicate found!
works fine
ah wait
i called the wrong fn
why does my tsc add .default to each imported value?
function chloe() {
const reversedSet = new Set();
for (const entry of entries) {
const reversed = Buffer.from(entry.bytes_buffer).reverse();
if (reversedSet.has(reversed.toString("ascii"))) {
console.log("Duplicate found!")
}
reversedSet.add(entry.bytes_buffer.toString("ascii"));
}
}
function hex_username_man() {
const reversedMap = new Map()
for (const entry of entries) {
const reversed = Buffer.from(entry.bytes_buffer).reverse()
if (reversedMap.has(reversed.toString('hex'))) {
console.log("Duplicate found!")
}
reversedMap.set(entry.bytes_buffer.toString('hex'), true)
}
}
Chloe Function: 71.578ms (from 95.693ms)
Hex Username Man Function: 80.589ms
all i changed was that in my .toString() i specified the encoding of ascii and now it performs faster than hex mans, does v8 try to guess the encoding by any chance if i dont specify it as a parameter which could make it slower? @quartz kindle
default encoding is utf8
specifying utf8 makes it much slower now
that makes sense then
although im not sure why utf8 is much slower
ascii and utf8 arent too different
both buffers should be able to be represented in a single byte with little conversion
anyways ive had enough of this language for a day
uh wtf
function chloe() {
const reversedSet = new Set();
for (const entry of entries) {
const reversed = Buffer.from(entry.bytes_buffer).reverse();
if (reversedSet.has(reversed.toString("ascii"))) {
console.log("Duplicate found!")
}
reversedSet.add(entry.bytes_buffer.toString("ascii"));
}
}
function hex_username_man() {
const set = new Set()
for (const entry of entries) {
// also check for reverse
const reversed = Buffer.from(entry.bytes_buffer).reverse().toString('ascii');
if (set.has(reversed)) {
console.log("Duplicate found!")
}
set.add(entry.bytes_buffer.toString('ascii'))
}
}```
robert ~/projects node sha1.js
chloe: 1.376ms
hex_username: 1.233ms
robert ~/projects node sha1.js
chloe: 1.189ms
hex_username: 1.207ms
robert ~/projects node sha1.js
chloe: 1.009ms
hex_username: 0.832ms
robert ~/projects node sha1.js
chloe: 1.162ms
hex_username: 1.689ms
robert ~/projects node sha1.js
chloe: 1.299ms
hex_username: 0.873ms
this is cursed
if all of this was written in Rust™️ we wouldnt be having this discussion
function reverse() {
const arr = entries // ffs
const len = arr.length
for (let i = 0, l = len / 2; i < l; i++) {
const reflex = (len - 1) - i
arr[i] += arr[reflex]
arr[reflex] = arr[i] - arr[reflex]
arr[i] -= arr[reflex]
}
}
idk ask chloe
set cant store a value though, its a few ms faster than using a map in this case but yeah not a big difference
sets can store a value in fact
since when
sets are just an abstracted map
since always, sets are literally maps that have a fixed value
usually null
still faster though since you dont deal with the value anymore from the javascript perspective so the native code can do all of that stuff
but performance suggests so
the performance difference is probably from js typecheck
@lyric mountain ive had a look at v8 internal code and v8 does differentiate between them
they are technically 2 separate classes but they do extend from the same classes
both extend from JSCollection which extends from JSObject so basically both are objects
i feel deceived
is there anything in js that isn't an object?
isnt undefined not an object
hashmaps in js are clearly a scam theyre just objects
yeah undefined isnt an object
checked the internals its a standalone class
dw we can fix that
null also isnt an object
NaN isnt one either but its a very unique type
theres different variations of NaN which appear identical in js
typeof NaN === 'number' // true smh
v8 source code is so modular you have to go through like 20 different functions to find what you need
from the looks of it v8 determines the result of typeof using "tags"
each thing in js is assigned a tag so the nan type is probably assigned a tag of number
which is why you need to use isNaN method
hold on NaN might actually be a number
isNaN checks if something is a number and then does the c++ isNaN on its value
hey is my logic correct?
function getDatePart(timestamp) {
const date = new Date(timestamp);
return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
}
const timestamp = estDate.getTime();
let previous = Number(user[0].last_logged_timestamp);
const differenceInMs = timestamp - previous;
const currentDatePart = getDatePart(timestamp);
const previousDatePart = getDatePart(previous);
const oneDayInMs = 86400000;
const differenceInDays = (currentDatePart - previousDatePart) / oneDayInMs;
if (differenceInDays >= 1 && differenceInDays < 2) {
// it is the next day!
}else if (differenceInMs < 1){
// it is still the same day
} else if (differenceInMs >= 2){
//it is 2 days later..
}
what is going on lmao
i don't know 😭
what is the data input for these? like what is entries
sorry i was reading 5 hours of chat where i wa smentioned multiple times exdee
...why
actually why are u constraining to the same day, instead of 24h?
timezones exist, you'll lock your bot to a specific region of the globe
switch ((differenceInMs / oneDayInMs)|0) { // to int
case 0: // within 1 day (not inclusive)
...
break;
case 1: // within 2 days (not inclusive)
...
break;
default: // anything else
...
break;
}
yeah ascii is faster than utf8 since you can skip all checks and just convert charcode to char
still love this overly complex ipv6 code https://github.com/0x7d8/rjweb-utils/blob/aeb1d348e58937bf9acc07553743d771ecd8165e/src/network.ts#L415
why wouldn't it be
it's an IEEE 754 thing
overexaggeration it was only 3 times
lmao
but what exactly were you doing
i still dont get it
why reverse the buffers?
3,2,1 should also be a duplicate of 1,2,3
why?
idk
what about 3,1,2 or 2,1,3?
omg, this dude keeps dming me about how to use may api, he claims to be a developer who's building a system for a client
but everything he does is ai+nocode
"developer" smh
nop
well
the benefit of openapi is that ai coders can feed it to the llm
and get real output
it was me checking for possible duplicates in reverse over a dataset in case there were duplicate ids but in reverse
my initial no sleep solution was to do it in a squared time complexity because i overestimated the computing capacity of my cpu
what is entries exactly tho?
how large are the buffers?
Lmao
The client probably goes "yeah we need a bit of ai and some of that API"
Both equally stupid
an object which contains a 32 byte buffer
im benchmarking this :^)
oh not again
btw, i copied the functions you guys posted so far, but apparently they are not finding any duplicates? let me douple check my data set lol
whats your data
make sure its not a buffer array and not a pure 2d number array
function generateTestData(size) {
return Array.from({ length: size }, () => ({
bytes_buffer: crypto.randomBytes(32)
}));
}```
nvm its just ben's function is not detecting duplicates
okay
this is the best I can do
function best_possible_optimizations() {
const set = new Set()
const buffer = Buffer.allocUnsafe(32)
for (const entry of entries) {
for (let i = 0; i < 32; i++) {
buffer[i] = entry.bytes_buffer[31 - i]
}
const reversed = buffer.toString('binary')
if (set.has(reversed)) {
console.log("Duplicate found!")
}
const str = entry.bytes_buffer.toString('binary')
set.add(str)
}
}```
hex_username: 65.929ms
best_possible_optimizations: 42.636ms```
this only works if the data is proper though (32 bytes)
bros converting it to text binary
7ms faster
if js sets/maps supported buffers as keys i wouldnt even convert it to a string at all but ascii encoding is the closest i can get
they do support any object as key
i tried using a buffer and it seems to be by reference
but comparing only works if its the same reference
the keys should just be hashes under the hood so it shouldnt matter whether you give it a string or number or anything
but js just chooses to hash the reference address likely
robert ~/projects node sha1.js
chloe: 62.837ms
hex_username: 62.182ms
best_possible_optimizations: 19.6ms
mmmmmmm
looks like i found a way
function generate_unique_int_from_32_bytes(buffer) {
let result = 0;
for (let i = 0; i < 32; i++) {
result = (result << 8) | buffer[i];
}
return result;
}
function best_possible_optimizations() {
const set = new Set()
const buffer = Buffer.allocUnsafe(32)
for (const entry of entries) {
for (let i = 0; i < 32; i++) {
buffer[i] = entry.bytes_buffer[31 - i]
}
const reversed = generate_unique_int_from_32_bytes(buffer)
if (set.has(reversed)) {
console.log("Duplicate found!")
}
set.add(generate_unique_int_from_32_bytes(entry.bytes_buffer))
}
}```
ok this is probably actually it
Its the same as why [] !== []
I dont see any reason why anything could be more than 5ms faster than that
@quartz kindle
reusing the same buffer is a good idea
but your generate unique int i would imagine wouldnt be guaranteed to be unique 100% of the time
it is always unique
unless its over 32 bytes
it just bitshifts a number from the 32 bytes
function generate_unique_int_from_32_bytes(buffer) {
let result = 0;
for (let i = 0; i < 32; i++) {
result = (result << 8) | buffer[i];
}
return result;
}
wont that simply cut off most of the bytes?
lemme look at it again
you're just taking the last 4 bytes basically
o wait yeah
function generate_unique_int_from_32_bytes(buffer) {
let result = 0;
for (let i = 0; i < 32; i++) {
result = result * 256 + buffer[i];
}
return result;
}```
thats basically a hashing approach, you need a good number hasher for that
that will exceed number limit
hex_username: 1.029s
best_possible_optimizations: 661.657ms```
1000000 entries
hmm
now it looks like the output hash can exceed the js 64 bit limit
but you can try a number hasher like djb2 or fnv
so the numbers cant be reliable
but its not guaranteed to be unique
yeah no hash is
with something like this id want it to be guaranteed to always be unique
if one hash happens to collide with one entry and have a false positive thats already not acceptable for 90% of use cases
then this is the fastest i have rn
looks like a set supports bigints too
so you can should be able to feed the buffer into a big int
bigint was 100% slower than my other code
thats guaranteed to always be unique
yeah because they use strings under the hood
theyre very slow
🤔
what did you change
different approach, no strings
function tim2() {
debugger
const rope = Array(255);
for(let i = 0; i < entries.length; i++) {
const buffer = entries[i].bytes_buffer;
let current = rope;
for(let n = 0; n < buffer.length; n++) {
const entry = current[buffer[buffer.length - n - 1]];
if(Buffer.isBuffer(entry)) {
if(n < buffer.length -1) {
const next = Array(255);
next[entry[n+1]] = entry;
next[buffer[n+1]] = buffer;
current = current[buffer[n]] = next;
} else {
console.log("duplicate found");
}
} else if(Array.isArray(entry)) {
current = entry;
} else {
current[buffer[n]] = buffer;
break;
}
}
}
}
basically a byte rope
not sure how reliable it is, ropes are hell to work with (as you can see from the debugger statement lmao)
i got 3ms faster by converting my for const loop to for i
gonna see if i can get rid of converting to strings or sets
for..of is bad, avoid at all costs
(unless you use fancy things that implement Symbol.iterator)
if you dont mind having your code a bit slower :)
still faster than forEach
tbh i do use for..of quite a lot
wonder what this does under the hood https://www.npmjs.com/package/buffer-map
for non-performance critical work
converts to string
in binary format
yeah to binary
this npm package is useless
you can implement everything it does in just a few more characters of code
not even extra lines
this is basically the is-odd package
if you wanna squeeze some extra mileage from converting buffers to strings
use node's built in string_decoder
sort of
node:string_decoder is basically the decoder that is used under the hood for both buffer.toString and TextDecoder
but you get better performance if you use it directly for course, less checks and overhead
although is mostly focused on utf8, since its a more complex format
tf
chloe: 69.182ms
best_possible_optimizations: 41.754ms
best_possible_optimizations_2: 24.044ms
tim2: 34.596ms
js just died for a sec
its now same as the first again
fluctuations :)
yeah string decoder made it ~5ms faster


