#development

1 messages · Page 151 of 1

rustic nova
#

bashtop is overkill

sharp geyser
#
udp        UNCONN      0           0                154.12.246.30:28015                  0.0.0.0:*
udp        UNCONN      0           0                154.12.246.30:28017                  0.0.0.0:*

So I seem to have an issue of it being UNCONN and not LISTEN/ESTAB

#

Anybody can help me out here? its preventing me from connecting to my game server

#

or is it even possible for a UDP to be LISTEN?

delicate zephyr
#

only TCP can

#

UDP is connectionless

sharp geyser
#

I see

spark flint
#

have you added meta tags

viral vale
spark flint
#

you need to add open graph meta tags

#

thats how Discord knows what to embed

viral vale
spark flint
#

this should help

#

fill in the lil form on the right with what you want to show in the embed

viral vale
radiant kraken
#

Go is not that bad tbh

#

it's just mid

#

i would use it if i really have to

prisma nebula
#
import discord
from discord.ext import commands
from discord_slash import SlashCommand

intents = discord.Intents.default()
intents.messages = True
intents.guilds = True

bot_token = "dirty"  

bot = commands.Bot(command_prefix=None, intents=intents)
slash = SlashCommand(bot, sync_commands=True)

@bot.event
async def on_ready():
    print(f"Logged in as {bot.user.name}")
    print(f"Bot ID: {bot.user.id}")

@slash.slash(name="create_embed", description="Create a custom embed.")
async def create_embed(ctx, title: str, description: str, color: str, url: str = None, image: str = None, footer: str = None):
    embed = discord.Embed(
        title=title,
        description=description,
        color=int(color, 16),  # Convert hexadecimal color to integer
        url=url,
    )
    if image:
        embed.set_image(url=image)
    embed.set_footer(text=footer)

    await ctx.send(embed=embed)

bot.run(bot_token)
#

Why

spark flint
#

rip domain

#

anmyways

#

read the error

radiant kraken
#

This domain may be for sale!

#

imagine using domains for everything

spark flint
radiant kraken
#

imagine paying all just for that

spark flint
#

oh this was fre lol

radiant kraken
#

.dev is free?

spark flint
#

shows $10 but go to checkout with that code, it works

radiant kraken
#

First year free

spark flint
#

yes

#

every free domain does that

#

still, free for a year is not bad

winged linden
#

Yo

#

Any good & budget friendly vps service u guys could recommend?

quartz kindle
#

galaxygate is also alright (1gb ram, 20gb hdd, 1 cpu), 2.75 USD per month if you pay yearly

#

hetzner has really good performance on their vms, but they are a bit more expensive (4-5 EUR per month for 2 cpu 2gb ram)

#

also contabo, they are known for their ridiculously cheap prices for the bang they offer

winged linden
quartz kindle
#

also oracle has a free tier with 20gb ram on their ARM servers

#

but they randomly terminate your account for no reason

#

so stay away

spark flint
winged linden
spark flint
#

wtf

#

yeah most big name hosting providers like namecheap have expensive VPS servers

#

so they can market it to businesses

winged linden
quartz kindle
winged linden
#

for the past 3 months it never was offline

quartz kindle
#

neither are most other actual vps providers

winged linden
#

what do you personally use?

quartz kindle
#

almost every single vps provider has a 99.99% SLA guarantee

#

i have 3 of them atm, google, galaxygate and hetzner

#

google has my old api, galaxygate has my bots, hetzner has my new api which is WIP

winged linden
#

where can i get the google vps, i wanna test it

quartz kindle
#

but somewhere in the future im gonna move my bots to google and terminate the galaxygate one

winged linden
#

and for upgrade what are the prices?

quartz kindle
#

google is expensive af outside of the free tier, so dont even think about it

winged linden
#

oh lol

#

its pretty small and minimal so idk

quartz kindle
#

you will need a credit card to register tho

winged linden
#

thats cool

quartz kindle
#

when you create the vm, use these settings:

winged linden
#

100% free? for that package

quartz kindle
#

it has to be e2-micro and it has to be in one of those 3 regions

winged linden
#

dont want a 100+ $ payment on my card next month💀

quartz kindle
#

its

#

300 free USD of credits valid for 1 year

#

then after 1 year, you only pay for excess network usage

winged linden
#

ah dope dope

quartz kindle
#

i pay about 10 cents per month

#

or something

winged linden
#

ah lol

quartz kindle
#

1 GB network egress from North America to all region destinations (excluding China and Australia) per month

winged linden
#

and what is the traffic on your api like? it can handle it normally?

quartz kindle
#

i havent measured much lately but its around 10-20 reqs per minute

#

so its more than fine

spark flint
#

i would use Hetzner personally

#

I use 3 diff providers for my API

#

between 3 nodes, it handles like 7M requests a month

#

and thats increasing KEKW

winged linden
#

thanks alot!

quartz kindle
#

nice

#

im moving to hetzner too, with my new api version

spark flint
#

its usually 2m a month but some changes mean its increased a lot

quartz kindle
#

hetzner is better for commercial/pro things

spark flint
quartz kindle
#

google is better for dev and testing

spark flint
#

Node 1: UK - Oracle
Node 2: Canada - OVH
Node 3: Canada - Xenyth

quartz kindle
#

ew oracle

#

xD

spark flint
#

it handles well lol

#

im hosting one of my new projects on there

winged linden
#

range^

spark flint
#

and i'll migrate to Hetzner when i get money

quartz kindle
#

are those 3 nodes different parts of your system? like a microservice arch?

#

or are they 3 copies of the same system

spark flint
#

they all run the same API code

quartz kindle
#

ah

spark flint
#

just different VPS servers

quartz kindle
#

why two in canada then

spark flint
#

idk

quartz kindle
#

woud be better to get regional servers around the world no?

spark flint
#

my plan for the nodes is geo distrubuted but i had to move one of them quickly due to a provider downtime and never fixed it

quartz kindle
#

ah

spark flint
#

I have 4 origins allowance on CF Load Balancer for free

#

so i can add a 4th if i want and I might eventually

quartz kindle
#

nice

spark flint
#

its not that it can't handle it, but because its growing a lot and redundancy >>>

quartz kindle
#

is the cf loadbalancer dns-based? it can fallback automatically if one domain does down?

spark flint
#

yeah

quartz kindle
#

cool

spark flint
#

it pings the API every 30s

#

and auto marks as down

#

i just realised node3 is down

quartz kindle
#

im not using cf yet, im still thinking about it

spark flint
#

but its auto disabled it

#

so gonna go fix now mmLol

quartz kindle
#

xD

spark flint
#

🗿 what

#

wut

quartz kindle
spark flint
#

@winter pasture ads in every channel

#

well 3 channels

#

close enough

spark flint
quartz kindle
#

lmao

spark flint
#

lol

#

perfect node3 back, cloudflare should detect in a sec 🙏

deft wolf
#

Sus

spark flint
#

just removed the old node4, i should probably adjust the weight load balancing lol

quartz kindle
#

1: advertising on this server and posting links for your bot here = ban
2: your bot link will only work after its approved. if its not approved, it only works for you
3: you need to have an actual working bot with actual functions before you add it to top.gg

spark flint
#

perfect

#

i think i use sticky nodes too, so if you use one node it should keep directing similar requests to the same node

winged linden
#

critical question, actual crypto gambling discord bot would be illegal right?

spark flint
#

yes

#

well against TOS

#

and would probably get you terminated

winged linden
#

ok we stay away from that then💀

deft wolf
#

Ogarnij się chłopie i nie klnij już bo mute'a dostaniesz jak tak dalej pójdzie

quartz kindle
#

yes we know

winged linden
#

are you ok?😂

deft wolf
#

I am ashamed to be Polish in such moments

spark flint
#

@harsh nova

#

hi

#

all channels

harsh nova
#

No

harsh nova
frosty gale
#

more commonly used to say fuck than whore

#

poles often use "kurwa mać" to clarify theyre saying fuck than something else

#

fun fact

deft wolf
#

Not really, "kurwa mać" is more like english ffs

frosty gale
#

please state your credentials which authorise you to make such a claim

deft wolf
#

I'm Polish

frosty gale
#

okay

#

send a copy of your polish passport

#

just confirming

deft wolf
#

I don't have one

quartz kindle
#

ja pierdole

#

how come

pale vessel
deft wolf
#

I probably still have a photo of the ID card somewhere that I used to verify my bot

#

Holy shit, I'm old af angeryBOYE

frosty gale
#

bro actually did it 😭

#

fine you win

quartz kindle
#

:^)

frosty gale
#

i swear more and more websites are adding these stupid annoying "before you go" full screen popups when it detects youre moving your mouse towards the close button

#

didnt used to be like this

rustic nova
#

pov

#

sites I block on my pihole

#

they dont deserve getting visits from me anymore

eternal osprey
#

i am using canvas to display text on an image:

the one above is on my own pc, the one below is my vps. What the fuck is happening

#
async function addTextToImage(canvas, ctx, text, message, x, y, size, color) {
    try {
      
      ctx.font = size+'px Arial';
      ctx.fillStyle = color;
      ctx.strokeStyle = 'black';
      ctx.lineWidth = 0.3;
      ctx.shadowColor = 'black';
    ctx.shadowOffsetX = 2;
    ctx.shadowOffsetY = 2;
    ctx.shadowBlur = 5;
  
      const textWidth = ctx.measureText(text).width;
      
     
      ctx.fillText(text, x, y);
      ctx.strokeText(text, x, y);
  
    } catch (error) {
      console.error('Error:', error.message);
    }
  }
quartz kindle
#

linux by default does not include standard fonts

#

you have to install it

eternal osprey
#

owjhh wow i see

#

currently trying to install the microsoft package which should come with arial

#

only problem is, is that i cannot click fukcing okay

#

any hotkey i am missing??

quartz kindle
#

enter?

#

idk try esc, space

eternal osprey
#

Oowh on mac it's control

#

thank you

lyric mountain
#

there are a bunch of similar fonts out there

#

like open-sans

rustic nova
#

mfw heart almost dropped

#

Turns out, MobaXTerm allows passing through your ssh key to the machine you're connecting

#

so I wanted to ssh to my main server through a small local server in my home network through mobaxterm, wondering why it didnt request any passwords or deny access through missing pubkey

sharp geyser
rustic nova
#

ez fix

#

block whole size

#

site

sharp geyser
#

size

#

smh

rustic nova
#

shush

peak drum
#

Hey guys how do I get the timestamp like #auctions-status ? I want to use it in my bot (discord.js)

wheat mesa
#

There’s different forms that you can look up, but for example <t:unix timestamp:R> is one of them iirc

#

Like <t:170000000:R>

deft wolf
#

Yea, It's something ago

peak drum
#

alright thank you thumbs_up_parrot

#

<t:1689969719:R>

deft wolf
rustic nova
#

also documented on discord's developer docs

peak drum
#

xD sorry

deft wolf
#

Yes, I remembered that I already sent something like this

rustic nova
#

there is a

#

fuckin

#

uber-cli

#

pls

narrow vault
#

#play tum ho

rustic nova
peak drum
unborn silo
#

Sune nhi aaraha meko

quartz kindle
#

@earnest phoenix

#

nvm

#

lol

#

yes my chrome was outdated

#

still shows this tho

#

but timeline works now

earnest phoenix
# quartz kindle still shows this tho

That error usually occurs if the performance profiling tool is either incompatible with your web browser version, or some extension could be interfering with it, or some security settings might be disallowing it from accessing the web browser's main thread

slender wagon
slender wagon
#

simple

#

give me the ip so i can connect into it

pale vessel
slender wagon
#

lol

radiant kraken
#

down bad

radiant kraken
#

does discord intentionally strip U+202E characters from messages as they are sent?

#

try paste U+202E, type something afterwards, and hit enter

light ravine
#

i have a webhook for vote rewards but i have backlisted every ip except a few so i wanted to ask if top.gg ip will remain static for a long time or not?

#

current ip i am getting requests from 159.203.105.187

rustic nova
#

Glhf

small tangle
frosty gale
#

though you should also use the secret to verify its from them

frosty gale
light ravine
#

also thanks for the ss :)

frosty gale
#

:)

radiant burrow
#

it seems as though the CSS style tag is not registering at all in my bot page, but I used a few html checker/ viewers and they all seem to show it just fine. Do I need to do something specifically for top.gg for it to work?

body {
        color: #1c1933;
        background-color: #246847;
        font-family: Jua;
        font-size: 28px;
        padding: 96px;
      }

for example, none of this is applying. When I paste the whole bot description it goes as message.txt so that's what that is

rustic nova
#

remove the html and head

radiant burrow
#

oh

rustic nova
#

only have the style tag in it and the content

#

and make sure to save, preview is broken

radiant burrow
#

i see i think i went too offical with the html LMAO thanks!

spark flint
#

if i am inserting 100 items at a time with Mongo, how can I best ensure every _id is unique

#

since its not liking it atm

earnest phoenix
# rustic nova remove the html and head

Wouldn't it be a good idea to put some sort of disclaimer in the long description editor to tell the users to not put html and/or body tags if they want the style tag to work?

rustic nova
#

probably

earnest phoenix
spark flint
#

not the best

#

it just stops the database from crashing lol

earnest phoenix
#

You're generating the IDs yourself? May I ask why?

spark flint
#

because i keep getting duplicate object IDs

#

very unique IDs 👍

earnest phoenix
#

Weird, MongoDB should always create a completely unique ID at all times by default, though you can use UUIDs instead which is almost impossible for them to have any duplicates

spark flint
#

i would refer to my old code for how i used to do it

#

but i accidentally deleted it oop

#

well no it was on my old ssd before it died

earnest phoenix
rustic nova
#

I have a backup-like tunnel between 2 servers: one is where the backups are generated, the other where they are stored
I wanna connect both using sshfs. What sounds better: Mount the sshfs on the server generating the backups or mount the sshfs on the server with the backups, so

server -> backup_server
or backup_server -> server

both will require providing ssh keys

earnest phoenix
#

Make sure to set the disableEntropyCache option to true

spark flint
#

ooo ok

#

i tried this

#

same error uhh

rustic nova
#

perhaps generate a hash from the data you're providing?

spark flint
#

i have a feeling its because its trying to add the data multiple times

#

because it loops so quick

rustic nova
#

the date.now will likely only provide the same date for everyone, depending on how much quick this is being handled

rustic nova
#

yeah date.now wont help

spark flint
#

lol

rustic nova
#

unless you wanna go to a millisecond to nanosecond time

spark flint
#

well domain + Date.now() should work?

#

because the domains array has duplicates removed

rustic nova
#

can you try printing out the domain and the then date.now its trying to add

#

or you're getting hash collisions, which shouldn't be the case

#

especially not with sha256

spark flint
rustic nova
#

looks fine yeah

#

excuse the offtopic but

spark flint
#

might overengineer this

spark flint
rustic nova
#

ohhh

#

how about reading /etc/random from linux? does that help?

spark flint
#

im on windows

rustic nova
#

oh

spark flint
#

it will use ubuntu but not atm

#

the unique part isn't the issue now i dont think

#

i think its because its attempting to add multiple times

rustic nova
#

but you are definitely getting date-collisions

spark flint
#

because it doesn't know if another loop is handling the >= 100 add

#

but that wont matter for keys because the domain causes it to be diff

#

hm i might use bull queue system

#

add to queue, handle there

rustic nova
#

yeah its probably better to queue them up

rustic nova
#

mongo should handle it

spark flint
#

some of the stuff caught in my current scanner is funny

#

this looks for keywords before logging, whilst this new ssl scanner will basically do a DNS lookup and store the resolved records

#

and there will be an API to query and find info based on ip, hostname, etc

earnest phoenix
#

@spark flint can you run this in your if statement in that loop before calling insertMany()?

console.log(toInsert.find((doc, idx) => toInsert.some((doc_, idx_) => doc_._id === doc._id && idx !== idx_)));
spark flint
#

oki doki

earnest phoenix
#

It logged undefined all the time?

spark flint
#

when it hit that

#

oop

#

i increased the threshold to 2500 from 100 so less possible collisions and then it logged the duplicates

earnest phoenix
#

Yeah somehow that entry is duplicated

spark flint
#

@earnest phoenix works poggies

#

i remembered my fix from last time

earnest phoenix
#

Very nice

spark flint
#

NVM jinxed it

#

i managed to get 10k records before crash

earnest phoenix
spark flint
#

at least storing data works poggies

earnest phoenix
#

But note that you can set the ordered option to false in the insertMany() method to continue writing the entire batch while ignoring errors

#

If that's something you'd use

spark flint
spark flint
#

much better 🔥

#

using bee-queue

#

handles it as a queued job now

#

and prevents duplicates

rustic nova
#

very swag

spark flint
#

🔥

rustic nova
#

how much space do you have

spark flint
#

8tb

rustic nova
#

fair enough

spark flint
#

last server had 100gb and died because out of storage

#

this won't run out for a while

#

its an OVH soyoustart server iirc

#

someone pays for it for me KEKW

#

32gb ram, intel xeon 8 core, 8tb hdd

plucky hearth
#

Hi

light ravine
#

any endpoint for checking if user can vote or not?

found it 👍

#

https://top.gg/api/bots/:bot_id/check

this is for checking last 12 hours vote right?

warm surge
#

try tbis

#

const Topgg = require('@top-gg/sdk')

const uId = message.author.id;
const topgg = new Topgg.Api(client.config.TopggToken) //top.gg token
let voted = await topgg.hasVoted(uId)

#

it should help

deft wolf
#

It doesn't really matter if you use top.gg sdk or send a request to the api yourself

sharp geyser
#

sdk is just there to make your life slight easier and imo isn't necessary

frosty gale
#

its like the difference between windows and linux

#

sdk is bloated but easier to use 💀

sharp geyser
#

lol

#

honestly the only thing you gotta worry about is if the site is even up

light ravine
warm surge
#

check topgg github account

light ravine
#

weird topdotgg sdk automatically installs discord.py .. ig i will just go with the endpoint since i am not actually using discord.py

#

ah i think its for listening to discord.py bot events

warm surge
#

Okie

light ravine
#

any endpoint for checking how much time is left before user can vote again

#

or we have to manage that ourselves by listening to vote POST requests?

small tangle
#

i used mongodb when i realized im just using it in a relational way so i migrated to postgres dogkek

small tangle
#

is it normal that github takes up all of the monitors width when looking at a branch other than main? feels weird to me

#

i mean the top level view of the repo

pale vessel
#

nope?

#

it looks the same as main

small tangle
#

huh weird

#

im confused what could trigger this

#

ok there was this option unchecked

#

but on a branch other than main, do you have the sidebar with the directory contents already in the top level view?

pale vessel
#

no, that should only be in pages other than the top level view

tulip ledge
#

Is there a way with canvas to like smooth this transition? eg both strokes have a 60° end so it looks connected?

frosty gale
#

but if you want the turn to be smooth you're gonna have to tinker with arcs

#

and a bit of 🥧

tulip ledge
#

mmmh alr

#

I'll take a look into that I suppose

#

luckely I studied math angeryBOYE

quartz kindle
#

which lets you draw lines with rounded corners

#
ctx.beginPath();
ctx.moveTo(20, 20);
ctx.lineWidth = 15;
ctx.lineCap = "round";
ctx.lineTo(100, 100);
ctx.stroke();
tulip ledge
#

mmmh yeah I don't think that'll do what I want it to do

quartz kindle
#

try connecting two of those lines together like you did

#

it will look pretty decent

#

there's also this

frosty gale
#

don't listen to tim

#

that's the lazy way

#

if you do it my way you'll learn some maths

tulip ledge
#

I'm trying to make a hexagonal graph

You have a hexagon with the diagonals drawn. On each diagonal I'm trying to get a point based on the percentage of the graph item. The first line is rather easy since it's straight. But for the diagonal diagonals it's quite hard. I managed to get the x value of the point using this formula:

sin(60°) * sidelength * (1 + percentage)

But finding the y value is way harder I tried by using this formula and alot more.

200 - (1 - percentage / 2) * sidelength / 2

it's also worthy to tell you that I'm working in a 400 x 400 square with the top left corner being (0, 0) and the bottom right (400, 400) the center of the hexagon at (200, 200) and the hexagon is equilateral.

This is what happend now

earnest phoenix
tulip ledge
earnest phoenix
#

Huh, weird

tulip ledge
#

same thing

queen needle
#

I don't understand what is it supposed to do?

tulip ledge
#

Its supposed to get a dot on the second diagonal based on the percentage so I can connect the two

#

But I need to find the points

quartz kindle
#

you want something like this right?

tulip ledge
#

Yes

queen needle
#

How is the x using sin instead of cos?

quartz kindle
#

how did you calcuate the yellow corners?

queen needle
#

I mean considering it's a fixed value I don't think it matters does it?

tulip ledge
quartz kindle
#

since you already have the formula for the hexagon points, use the same formula but with a different radius

tulip ledge
#

I’ll send them in a sec

tulip ledge
quartz kindle
#

did you calculate the points using angles?

tulip ledge
#

Hold on heading to pc right now I’ll send the code

#
    ctx.moveTo(width / 2, offset);
    ctx.lineTo(width - offset, offset + sidelength / 2);
    ctx.lineTo(width - offset, offset + sidelength * 3 / 2);
    ctx.lineTo(width / 2, height - offset);
    ctx.lineTo(offset, offset + sidelength * 3 / 2);
    ctx.lineTo(offset, offset + sidelength / 2);
    ctx.lineTo(width / 2, offset);
    ctx.lineTo(width - offset, offset + sidelength / 2);
quartz kindle
#

does the hexagon have to be slightly flattened?

tulip ledge
#

what do you mean slightly flattened? isn't a 2D figure already flat or am I getting it wrong haha

quartz kindle
#

i mean

#

slightly more width than height

tulip ledge
#

well I'd prefer it be equilateral but it doesn't matter

#

is mine not equilateral ;-;

#

did I mess up my maths

quartz kindle
#

idk maybe its my screen

#

but it feels a bit wider than it is high

tulip ledge
#

yeah my friend said that aswell

quartz kindle
#

anyway, using circle math will get you equilateral

#
var x = xPos + Math.cos(angle * Math.PI / 180) * radius;
var y = yPos + Math.sin(angle * Math.PI / 180) * radius;
#

so you define a center point, then get the x and y positions using a radius and an angle, from that center point

tulip ledge
#

xPos and yPos are center right?

quartz kindle
#

ye

#

i dont remember if thats the exact formula, i copied from a random SO answer

#

but i use this a lot in my bot

#

since it generates circular charts

tulip ledge
#

and then I get the points using the angle right?

#

so top is 0 and then I add 60° per right?

quartz kindle
#

ye

#

0 will likely be pointing right

#

so you will need an offset angle

#

for example 90 deg offset to make 0 point up

tulip ledge
#

ah yeah

tulip ledge
#

Tim always has the best solutions

queen needle
#

Does it look better? I'm interested to see the product

quartz kindle
#

well i just had experience with it since i faced similar problems before :)

wheat mesa
#

How do computers do trig? Do they use Taylor polys?

quartz kindle
#

no idea what taylor polys are

#

but this is what google says

#

Calculators don't actually use the Taylor series but the CORDIC algorithm to find values of trigonometric functions. The Cordic algorithm is based on thinking of the angle as the phase of a complex number in the complex plane, and then rotating the complex number by multiplying it by a succession of constant values.

#

the Taylor series expansion of a trigonometric function can be slow to converge, especially for large input values. To improve the accuracy and efficiency of the computations, computers use specialized algorithms, such as the CORDIC (COordinate Rotation DIgital Computer) algorithm or the Taylor series with argument reduction. These algorithms exploit properties of trigonometric functions to reduce the computation to a smaller input range or to minimize the number of terms required from the Taylor series.

wheat mesa
#

Damn

#

I figured Taylor series weren’t used because of the issue with large input values

#

Then again since all trig functions repeat you wouldn’t have to have a massive Taylor polynomial to make it work

quartz kindle
#

mathematicians are aliens, prove me wrong

tulip ledge
tulip ledge
# wheat mesa Damn

yeah they use taylor series, I went to a nokia factory where they showed it so it's an aproximation not an exact value

#

but iirc the values like 30°, 60° and such are always 100% accurate

quartz kindle
#

some angles have exact values

#

there is a full list of them on wikipedia

#

but its mostly multiples of 15°, 18°, or 22.5°

queen needle
#

Lovely embed

quartz kindle
#

lmao

wheat mesa
#

Well I know the exact values for trig themselves but I’m saying the computer approximations of those values are slightly off

quartz kindle
#

yeah, the "exact values" are all multiples of PI, which is impossible to represent as a finite number

#

someone online also said this:

For many calculated values they actually use database stored values! These are known as table values. Yes, there is a little database in your calculator! It is a hardwired permanent database built into the electronics or chip of the calculator.

#

They permanently store a few precalculated values in memory for a few “important” values of the argument. If a user has a different argument, the calculator interpolates. Choosing values for storing depends on the function.

tulip ledge
wheat mesa
#

Yeah for calculators it makes sense that they focus more on accuracy

quartz kindle
#

yeah, computers usually focus more on performance

#

especially in game engines

tulip ledge
quartz kindle
#

:)

tulip ledge
#

yes 😄

weary ridge
#

hey do you guys got a weather api or smth like that

that is free ofc

spark flint
#
#

these are cool

#

i've used the latter before

quartz kindle
#

i use open-meteo but not for weather

lyric mountain
quartz kindle
#

geocoding and elevation

lyric mountain
#

of the moon?

quartz kindle
#

lol nope

lyric mountain
quartz kindle
#

i have multiple apis for geocoding and elevation

#

idk why tbh, i just wanted to support them all

ivory parcel
#

Quem pode me ajuda

quartz kindle
ivory parcel
#

Tim

#

@quartz kindle

quartz kindle
ivory parcel
#

Ajuda eu divogar meu servidor @quartz kindle

quartz kindle
#

no

ivory parcel
#

Blz

rustic nova
#

am too late lol

eternal osprey
#

hey does anyone know a good way to export my client from one file to another?

#

i know about module.exports, but whenever i do that and later on import it, it always states undefined

quartz kindle
#

index imports file which imports index which imports file.... ad infinitum

civic scroll
#

also CJS is outdated, consider using ESM

export = {} // quivalent of module.export
export VAR_NAME; // export variables `import { VAR_NAME } from "path/to/module"`
export default VAR_NAME; // for `import DEFAULT_EXPORT from "path/to/module"`
export function FunctionName() {}; // `import { FunctionName} from "path/to/module"`
// static import
import * as MODULE_NAME from 'path/to/module';
import { exported_symbol as alias } from 'path/to/module';
import DEFAULT_EXPORT from 'path/to/module';
// dynamic import
const imported = await import('path/to/module');
quartz kindle
#

esm sucks

#

cjs best

eternal osprey
#

ah i see, thanks guys. iT WORKS NOW

#

it works now*

frosty gale
civic scroll
quartz kindle
#

nah in websites we use global variables

#

like a real man

civic scroll
frosty gale
#

stupid gen z web devs

#

bet they would be shocked if they found out react runs on top of vanilla js

#

and a virtual dom is only a concept within the react framework

#

i sound like a 60 year old amiga user afraid of change

earnest phoenix
#

i tried the examples but they arent working, do you know like any other resources that have example code where i can just put in the token and it works?

lyric mountain
#

don't just copypaste example code smh

quartz kindle
earnest phoenix
#

yeah i believe so

#

and i cant find any like youtube videos or examples to figure out :/

quartz kindle
#

maybe if you show your code we could help

#

the first line is already wrong

earnest phoenix
#

😂

quartz kindle
#

top.gg webhooks are not discord webhooks

earnest phoenix
#

damn

#

is it the topgg token?

quartz kindle
#

nope

#

where is your bot hosted?

earnest phoenix
#

on my computer

quartz kindle
#

then you will need to port forward your router

#

do you know how to do that?

#

also, do you have a static ip address?

earnest phoenix
#

nope, i also host my main bot on my hetzner cloud server

frosty gale
#

this is why webhooks suck

earnest phoenix
#

is that any different?

lyric mountain
#

was gonna mention this now

quartz kindle
#

yes

earnest phoenix
#

damn 3 customer support now

quartz kindle
#

its much better to do it on the server

#

and not on your computer

#

much easier

lyric mountain
earnest phoenix
#

ok then ill code it as if its on the server and test it on there after

quartz kindle
#

yes

#

you can do that

earnest phoenix
#

ok so what do i need to do

lyric mountain
#

but discord could've chosen a better name for their implementation

quartz kindle
#

so basically,

frosty gale
#

but annoying bc you need a static ip which is also publicly accessible

quartz kindle
#

you can do this for example: .dbl_webhook("/votes", "password")

lyric mountain
#

well, that's true for any api

quartz kindle
#

then you do to top.gg website, go to your bot's page, click to edit your bot

#

then go to the webhook options

frosty gale
#

maybe you dont want to make an api

lyric mountain
#

webhooks are apis

quartz kindle
#

and you put in the webhook url "http://YOUR_HETZNER_SERVER_IP_ADDRESS:YOURPORT/votes"

frosty gale
#

if you're being technical about it sure but the intention is to inform the client of an event

#

so i dont rlly count them as apis

quartz kindle
#

the YOURPORT part is what you put here bot.topgg_webhook.run(5000)

lyric mountain
#

nono, not technical, they're literally apis

#

but instead of you calling a remote service, the remote service is calling you

earnest phoenix
#

it says invalid url

quartz kindle
#

and in authorization you put "password"

earnest phoenix
#

should i remove the http:/

quartz kindle
#

show what you put

earnest phoenix
quartz kindle
#

like, show what you actually put there

#

you can dm me if you want

#

i just said

#

the YOURPORT part is what you put here bot.topgg_webhook.run(5000)

#

lol

earnest phoenix
#

🤣

#

so i put 5000?

quartz kindle
#

so :5000

#

yes

earnest phoenix
#

yeah hm that makes slightly more sense than YOURPORT

#

a lil bit

quartz kindle
#

http://xxx.xxx.xxx.xxx:5000/votes

#

yes

#

now put it in your server

#

and try running it

earnest phoenix
#

should i leave this in the code as bot.dbl_webhook("/votes", "password")

#
bot.dbl_webhook("/votes", "password")



@bot.event
async def on_dbl_vote(data):
    """An event that is called whenever someone votes for the bot on Top.gg."""
    if data["type"] == "test":
        # this is roughly equivalent to
        # `return await on_dbl_test(data)` in this case
        return bot.dispatch("dbl_test", data)

    print(f"Received a vote:\n{data}")


@bot.event
async def on_dbl_test(data):
    """An event that is called whenever someone tests the webhook system for your bot on Top.gg."""
    print(f"Received a test vote:\n{data}")

quartz kindle
#

yes

#

you can change password to whatver you want

#

as long as you put the same thing in your code and in the topgg options

#

you still need the webhookmanager part, dont remove it

#
bot.topgg_webhook = topgg.WebhookManager(bot).dbl_webhook("/votes", "password")

@bot.event
async def on_dbl_vote(data):
    """An event that is called whenever someone votes for the bot on Top.gg."""
    if data["type"] == "test":
        # this is roughly equivalent to
        # `return await on_dbl_test(data)` in this case
        return bot.dispatch("dbl_test", data)

    print(f"Received a vote:\n{data}")


@bot.event
async def on_dbl_test(data):
    """An event that is called whenever someone tests the webhook system for your bot on Top.gg."""
    print(f"Received a test vote:\n{data}")


# The port must be a number between 1024 and 49151.
bot.topgg_webhook.run(5000)  # this method can be awaited as well
bot.run(token)
earnest phoenix
#

YES!!!!

#

the test worked!

quartz kindle
#

👍

earnest phoenix
#

Thanks so much for helping me nekoheart

quartz kindle
#

np

winged linden
#

anyone good with react and could help me with something?

peak drum
earnest phoenix
#

lmao

#

should'nt have posted that

#

webhook

#

someone just spammed it with the nword

#

goddamn

lyric mountain
#

well yeah, always delete the webhook if u ever leak it in a big public server

#

same for tokens

quartz kindle
#

lmao

spark flint
#

i regret using mongo

#

☠️

#

this is taking ages

#

like its been 2 mins already ☠️

lyric mountain
#

SELECT count(*) FROM dnsRecords u.u

#

anyway, how many docs are there?

spark flint
#

i can tell you in a sec

#

well might be a few minutes mmLol

lyric mountain
#

lmao

spark flint
#

its gonna be in the millions

#

i have hit the 15min mark

lyric mountain
#

final result: 42 documents

spark flint
#

its still querying

quartz kindle
#

dont databases update a count value somewhere?

#

if no, just make your own? and update it on every insert/delete

spark flint
#

i tried to cancel the query and now i can't SSH in KEKW

#

stuck on thius

#

nvm im in now

#

just took time

#

gonna reboot server

quartz kindle
#

lmao

#

what db is that?

spark flint
#

like what type?

quartz kindle
#

like mongo or pgsql

spark flint
#

mongo

quartz kindle
#

or whatever else

#

ah

#

lmao take a look at this

#

dude's query takes 1 hour to complete

spark flint
#

lol

#

its a 32gb ram 8 core 8tb hdd server

#

i might move to postgres for this

quartz kindle
#

or just store your own count value and update it yourself

spark flint
#

or that

quartz kindle
#

I have a mongodb PSA Cluster with 2 shards :

Centos 7.9
16GB RAM
4CPU
mongod 6.0.1
This is how looks my main collection :
STORAGE SIZE: 248.29GB
TOTAL DOCUMENTS: 3564898
INDEXES TOTAL SIZE: 4.74GB

#

[mongos] db> function a() {
… print(Date())
… print(db.dataset.countDocuments({_id:{$ne:null}}))
… print(Date())
… }
[Function: a]
[mongos] db> a()
Sat Jan 07 2023 15:59:43 GMT+0000 (Coordinated Universal Time)
3571253
Sat Jan 07 2023 17:01:44 GMT+0000 (Coordinated Universal Time)

#

lmao

#

1 hour to run countDocuments on 3 million docs

spark flint
#

this is probably at the 10 million+ mark

quartz kindle
#

gonna take 5 hours

#

:^)

spark flint
#

thats only like 2 days worth of data too

peak drum
quartz kindle
#

did you try countDocuments on an indexed key?

#

like countDocuments({some indexed key: some value that all documents have})

spark flint
#

nope

#

i should try that

#

they all have the same data structure so

#

can't SSH now

peak drum
#

Server is overloaded with counting

lyric mountain
#

MDoS

#

Mongo Denial of Sevice

spark flint
#

ok im back in

#

lol

lyric mountain
#

"I'm in"

spark flint
#

mongo loaded instantly this time

#

just requrying

#

i think because theres no writing happening

#

only reading now

#

IT QUERIED

#

65 MILLION

#

BAHAHAH

rustic nova
#

AYO

#

yesus

spark flint
#

thats only 2-3 days of data too

#

this is how it works

#

every time a new SSL cert is issued, this queries either google, cloudflare or cleanbrowsing DNS and stores that in the DB

#

meaning you can map sites overtime

#

aka phishing sites

#

and also allows us to search for sites by IP

quartz kindle
#

where do you get the SSL event from?

#

is that on a public api?

spark flint
#

yes

#

its a public open source websocket server

#

i am going to start self hosting my own one again, i selfhosted myself and since there aren't thousands of other people listening to the WS i got the results faster myself

quartz kindle
#

cool

spark flint
quartz kindle
#

you can run a whois service

spark flint
#

nah

#

whois is domain data which is not provided

#

99% of whois servers are slow as fuck

#

i have a whois API anyone can use anyways but its erroring a lot because of registrars being shit

quartz kindle
#

nah more like an ssl whois

spark flint
#

ah

#

true

quartz kindle
#

for ssl data for given ips/domains

spark flint
#

i dont store the cert details but i could

#

i could provide a reverse IP lookup service

quartz kindle
#

ye

spark flint
#

its also an easy way to find live domains

#

i just need to fix the code to change DB

#

30 mins of querying before i had to reboot the server is bad

lyric mountain
#

come to pogstres

spark flint
#

i did originally start using postgres

#

but it did not want to install on my pc

#

so i gave up

winged linden
winged linden
neon leaf
#

whats the best way to ensure people cant duplicate money by sending two requests at the same time (if that even applies to nodejs)?
my idea was that for some database queries I make a queue that works through the queries one after the other but that doesnt sound very performant even with a 0.1ms db ping.

quartz kindle
#

for a financial thing, logging would also help

#

it depends how you want to ensure the uniqueness of a transaction

neon leaf
#

dont they just make sure something fully happens

quartz kindle
#

yes, you need to combine it with a method of ensuring uniqueness

#

for example a transaction id or versioning

spark flint
#

You could also do a queue system

#

So it only processes one at a time and prevents duplicate requests

#

I use bee-queue personally and it’s great

quartz kindle
#

also if all you want to prevent is "duplicating" money, atomic operations alone already prevent that

#

do you have an example scenario or something?

neon leaf
#

not really, I just want to make sure noone somehow gets more money than they added

#

people can send eachother money and order services

quartz kindle
#

which db are you using?

neon leaf
#

both of those actions are probably vunerable I would guess

neon leaf
quartz kindle
#

use a transaction

#

that way, changing multiple user's values and stuff will be done as a single operation, and not multiple operations

#

it will ensure that the money added to one user will be fully removed from the other user as well

#

if either operation fails, everything gets rolled back

neon leaf
#

will I still have to do queuing with that?

#

like if I get two requests for the same thing at the exact same time

quartz kindle
#

use something to identify them

#

for example make a hash of the user ids and the value or items being transfered

neon leaf
#

I mean I store all transactions in the db already so every transaction has an id

quartz kindle
#

so that if the same transfer is attempted more than once, you will be able to see it

neon leaf
#

ahhh

#

you mean that

quartz kindle
#

it needs to be something that is not reusable

#

so you dont incorrectly catch two legitimate transactions of the same value

#

you can add something like a rounded timestamp

#

or

#

you dont need any of that

#

if you just limit the users to one operation per second

#

:^)

neon leaf
#

so ratelimiting?

quartz kindle
#

ye

neon leaf
#

basically

quartz kindle
#

if your db is 0.1ms

neon leaf
#

alr

quartz kindle
#

1 second rate limit is plenty

neon leaf
#

ig I gotta implement better ratelimiting in my webserver then

hasty nest
#

do i need to be careful about what characters go in a URL fragment? or does the browser not process those at all and i can throw in whatever i want

quartz kindle
hasty nest
#

well, meaning "will it screw with the data i get out of it"

quartz kindle
#

at most it will encode them as url entities

#

but you'll have to test it

#

if you want to be preventive, you can encode it yourself, and then decode it

#

encodeURIComponent / decodeURIComponent

neon leaf
#

yknow what I hate about js

#

the fact that you never know if a function can throw

#

I found it out the hard way

#

like I never wouldve guessed decodeURIComponent could throw

#

would be nice if ts would fix that somehow

quartz kindle
#

its well documented tho

neon leaf
#

the problem is noone is gonna read docs for every function you use

quartz kindle
#

i do lmao

neon leaf
#

🧐

quartz kindle
#

i read the docs for everything im unsure of

neon leaf
#

well I was quite sure decode would just provide the original input if it failed

quartz kindle
#

jsdoc has a @throws thingy

#

ts itself doesnt seem to have anything for exceptions

neon leaf
#

I thought no @throws = no throw

quartz kindle
#

ye

neon leaf
quartz kindle
#

who's in charge of those types? is it done by the ts team itself?

#

or by definitelytyped?

neon leaf
#

def typed I think

quartz kindle
#

so you could PR them

hasty nest
#

me when discord double-encodes it

neon leaf
#

what

quartz kindle
#

lmao

#

the % character always gets reencoded

neon leaf
#

do you need to customize any more about a ratelimit

quartz kindle
#

its dumb

#

i wouldnt even go that far

#

just set a timer on a user id that deletes itself after 1 second

#

if timer already exists, reject

neon leaf
#

its for my webserver package, It needs to be diverse

quartz kindle
#

i see

neon leaf
#

does this make sense

#

basically I never use setTimeout / setInterval and just do all checks / clears on the next request the ip makes

#

(with a background job that runs like every min that does some cleaning too to prevent a mem leak)

frosty gale
#

how are you planning on temporarily blocking the user?

neon leaf
#

by just ending the request with a 429 and not executing route handlers

frosty gale
#

i meant how will you mark the user as blocked so the api knows to 429 them

#

actually you probably just have some user object

neon leaf
#

I check their hits every time they make an request, if hits are higher than max allowed on route and end time isnt reached yet they get their end time increased and marked as "got penalty" so they dont get multiple penalties

spark pebble
#

Hey guys, anybody able to help me with some top.gg API intergration. Looking to change the cooldown of a command, depending on if somebody has voted that day or not.

Bot's in discord.py, currently using hybrid commands, and handling command cooldown via built in method.

    @commands.hybrid_command(brief="Claim a random card for your collection.")
    @commands.cooldown(1, 600, commands.BucketType.user)```
rustic nova
#
server {
    listen 80;
    server_name mailcon.cringe.dev; // The actual mailcow dashboard, not really relevant after I ditched the cloudflare proxy
    server_name mail.cringe.dev;
    server_name autodiscover.*;
    server_name autoconfig.*;
    location / {
        proxy_pass http://some-internal.ip:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 5s;
        proxy_read_timeout 5s;
    }

    # Add these lines to enable SSL
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/hopefuls.de/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/hopefuls.de/privkey.pem;
}
sharp geyser
#

what in the fuck

#

why are you doing server_name over and over

#

you can put that all into one

#

also your server_name is set to cringe.dev is this what you actually set it to?

rustic nova
#

smug I first used nginx in prod 3 days ago

sharp geyser
#

If so your ssl cert indeed does not match mail.cringe.dev

rustic nova
#

the certificate should cover *.hopefuls.de, aswell as *.cringe.dev

sharp geyser
#

seems like it doesn't

rustic nova
#

then shid certbot

sharp geyser
#

and fix those server_names

rustic nova
#

suffer

sharp geyser
#

looks cursed looking at them all split up

#

😭

#

Also if you are using nginx as a reverse proxy did you follow the tutorial for it?

rustic nova
#

Yeah

#

the reverse proxies are all working fine so far

sharp geyser
#

I see

#

Mine looks entirely different from yours

rustic nova
#

wdym

sharp geyser
#

Ill show you one sec

rustic nova
#

I'll give another try regarding ssl

#

since mailcow seems to want me to drop the certificates into assets/ssl

sharp geyser
#
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name mail.aarondye.dev autodiscover.* autoconfig.*;

    ssl_certificate /etc/ssl/certs/aarondye.dev.pem;
    ssl_certificate_key /etc/ssl/private/aarondye.dev.key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    ssl_verify_client on;
    ssl_client_certificate /etc/ssl/certs/cloudflare.crt;
    
    ssl_protocols TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!MD5:!SHA1:!kRSA;
    ssl_prefer_server_ciphers off;
    
    location /Microsoft-Server-ActiveSync {
        proxy_pass http://127.0.0.1:8080/Microsoft-Server-ActiveSync;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_connect_timeout 75;
        proxy_send_timeout 3650;
        proxy_read_timeout 3650;
        proxy_buffers 64 512k;
        client_body_buffer_size 512k;
        client_max_body_size 0;
    }
    location / {
        proxy_pass http://127.0.0.1:8080/;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_buffer_size 128k;
        proxy_buffers 64 512k;
        proxy_busy_buffers_size 512k;
    }
}
#

ok well it sent my mailcow conf has a file but ignore it

#

this is my nginx

rustic nova
#

yeah I have separate configs for everything

sharp geyser
#

👀

#

thats all for mailcow

rustic nova
sharp geyser
#

Its primarily so I can 1 visit it on the web

#

2 sign in to my email on say outlook or gmail

rustic nova
#

yeah thing being

#

I mainly had everything ssl on cloudflare

sharp geyser
#

I also just put this in my conf.d folder instead of sites-available

sharp geyser
#

I use Origin CA certs

#

not letsencrypt

rustic nova
#

ohh

#

so you essentially have a certificate on cloudflares end and one on your end

#

or how should I understand it

sharp geyser
#

You register the cert on cloudflare's end and it gives you the pem and key file contents that you have to save yourself

#

and then you put those on your vps and have nginx look for it

#

It covers my main domain and all subdomains

rustic nova
#

yeah this is too huge brain for me

sharp geyser
rustic nova
#

so I found out what the issue is

sharp geyser
#

Oh?

rustic nova
#

turns out, when I originally installed mailcow, acme still kicked in and somehow managed to get a certificate? KEKW

#

so that certificate obviously expired and mailcow apparently sent that out

#

So now re-checking the mail certificate, seems to verify it correctly now

#

so seeing if it works entirely now

#

yeah see, this covers *.cringe.dev and *.hopefuls.de

#

this is still worrying though

sharp geyser
#

eh should be fine mmLol

rustic nova
#

we'll se

#

e

#

fuck

#

yeah now its unable to get local issuer certificate

#

for fuck sake istg

sharp geyser
#

Welcome to the world of owning your own mailserver

#

the networking behind it is a pain sometimes

frosty gale
#

this will essentially let websites, especially google and other large players verify your environment to make sure they are happy with it or not

#

the same thing is basically done with androids and hardware backed attestation which is used for an app to 100% know a user is rooted or not or has modified their system

#

but google wants to bring it to every web browser

sharp geyser
#

meh

frosty gale
#

pretty sure on android theres this security chip that resembles a TPM which is relatively tamper proof and generates a cryptographically signed token for google to verify
if you do any modification like open the bootloader or root it, the thing gets tripped and will fail all your safetynet/integrity checks

craggy pine
#

ios deals with jailbreak detection in their apps. My jobs app literally banned me from using it (To view my schedule n shit) just because my Iphone is jailbroken. Not like I can do anything to your precious employee app anyways with it but so be it.

frosty gale
#

yeah thats the thing that plagues android as well, google doesnt want you to be rooted (you cant use google wallet if you fail safetynet too)

#

they, and all apps that make use of it claim its for "security reasons", whether they are blindly following the consensus that rooting is "insecure" and "dangerous" or dont like your freedom

craggy pine
#

I jailbreak for freedom. I theme out my phone

frosty gale
#

some nice apps only display a warning that your phone is rooted on first start but let you use the app anyways

#

my bank app does that but i know other banks flat out block rooted phones

rustic nova
#

see if that does something

#

nope dies entirely

#

fun

sharp geyser
#

Honestly all I can say is have fun figuring it out cause I don't even know at this point

rustic nova
#

thing is, the certificate works fine

#

but apparently

        Certificate #1 of 1 (sent by MX):
Cert VALIDATION ERROR(S): unable to get local issuer certificate
This may help: What Is An Intermediate Certificate
So email is encrypted but the recipient domain is not verified
sharp geyser
#

hm

frosty gale
#

i setup my own mail server and never had an issue with certificates

#

literally just made a letsencrypt cert and passed it to the mail server

rustic nova
#

@sharp geyser did it

#

guess how

#

had to fucking merge my certificate with the fullchain

#

dying inside

rustic nova
#

SMTP AUTH extension not supported by server.

#

YES works

#

fucking hell

rustic nova
#

you ever just

#

have a docker image

#

"be recommended"

#

but their documentation entirely refers to the by source installation

#

fuck them

spark flint
#

is this MiaB by any chance

rustic nova
#

No clue what that is, but its another web-based docker thing

#

trying to run behind a proxy

#

its using django

#

continuously hitting csrfs, even though the headers are passed through

#

fun

rustic nova
#

nah

spark flint
#

oh ok

rustic nova
#

nothing like that

#

cant tell you whatz

#

but yes

spark flint
#

yeye

rustic nova
#

hoping debug will help

#

at least I fixed the email thing KEKW

spark flint
#

fairs

sharp geyser
rustic nova
#

exactly

sharp geyser
#

:c

#

dm me it

#

😉

rustic nova
#

Ok cloudflare

#

where do I view my block rules again

#

lmao why did I create this dead

#

finally I can ufw my 80 ports again to only allow cf

#

swag

earnest phoenix
# lyric mountain same for tokens

yeah for some reason i thought you needed to be in a server to use the webhook or that its "public" lmao, ofc i wouldnt leak a token xD

frosty gale
neon leaf
#

Ok

#

why in the actual hell is tsserver so slow

#

its loading for up to 8 minutes at times

#

is there any way to make it faster

#

if its needed Id use a different editor too

weary ridge
#

hey is there an ai or api that i can give HUGE text and that it returns the personnality and what he might like

#

or things like that

sage bobcat
#

One message removed from a suspended account.

#

One message removed from a suspended account.

#

One message removed from a suspended account.

#

One message removed from a suspended account.

#

One message removed from a suspended account.

#

One message removed from a suspended account.

quartz kindle
#

why are you coal

sage bobcat
#

One message removed from a suspended account.

quartz kindle
#

did santa give you coal for chrismas?

#

bad grill