#🧩-plugin-development

1 messages Ā· Page 13 of 1

potent fox
#

worst case sceneraio which wont happen is discord will delete the server and ban ven (blobcatcozy )

#

then ven will create new account and server and put it on github

#

since github exists backup server would be meaningless imo

plucky sphinx
#

still stuck on this part :(

dull magnet
plucky sphinx
#

Oh damn

dull magnet
#

finding that function will be painful

#
const fetchProfile = proxyLazy(() => {
  const id = findModuleId("fetchProfile error:");
  const signature = wreq.m[id].toString().match(/fetchProfile error:.+?(return .{1,3}\.apply\()/)[1];
  return Object.values(wreq(id)).find(v => typeof v === "function" && v.toString().includes(signature));
});
#

works

lofty crypt
#

do you use dc in Norwegian?

#

haha v cool :D

there also used to be a plugin that let you open arbitrary web links in dc windows

paper mountain
#

Would it be even remotely plausible to have client mods for iOS discord?

opal fern
#

Ya

#

It's been done

#

But vencord won't touch android with a 7km stick

#

Even less iOS

#

Both are cursed as fuck

#

Refer to aliucord at best

lofty crypt
opal fern
#

Mostly due to discord being lazy with mobile discord web

lofty crypt
#

yeah i’m not surprised

paper mountain
opal fern
#

Uhhh

#

It can be sideloaded iirc

paper mountain
#

Ohh like an alternate app?

#

Like a "vencord" app?

#

just for example

solemn star
#

Yes it’s sideloaded

#

You can have both the modded version and the stock version installed alongside each other

#

Technically Enmity is a jb tweak, but it’s fairly trivial to inject it into Discord and redistribute modified IPAs, which is exactly what happens

paper mountain
#

Is there a version of vencord that works with enmity?

solemn star
#

What

#

Vencord and Enmity are two completely different mods

#

There is no compatibility between the two

#

Vencord’s entire premise doesn’t work in the mobile apps

paper mountain
#

oop ok

opal fern
solemn star
#

Plaintext patches aren’t really viable when your JS is all Hermes bytecode

opal fern
#

oh shit right

#

forgor about that

next stone
#

how can I properly trace where props are coming from?

#

the call stack just points me to React's bundle leaTired

dull magnet
#

because you're looking at a class component

#

the props are passed at instance creation time

#

renderBody is called way later

#

you need to put a breakpoint in the constructor, due to discords class transform its likely gonna be a plain function

#

@next stone

dull magnet
#

I switch my discord language occasionally to spice it up a bit and most germanic languages are similar enough for me to understand it

lofty crypt
#

freaky^^

#

think i’ve seen you cover .fr as well^^

#

i also used to switch my UIs to langs i was learning (.fr & .es)

#

but never got so adventurous as to use langs that are just similar to mine haha

next stone
dull magnet
#

based on the limited info I have, the code u have looks like this

function a() {
  ...
}
var i = a.prototype;
i.renderBody = function()... ```
#

a is the constructor in this case

next stone
#

yeah that's it

#

one second

lofty crypt
#

why don’t yall give some of dc’s functions self-documenting names to make traces etc. more readable?

next stone
#

...what? lexiCheese

dull magnet
#

I can't tell if you're joking

austere gulch
#

ah yes let us magically add context that doesn't exist

lofty crypt
#

the inverse of minifying

dull magnet
#

how are we supposed to rename discords names

next stone
#

lmfao

dull magnet
#

we could write patches that rename their variables but why

lofty crypt
#

i thought that would work with the regex patching

next stone
#

and then break everything that calls it?

lofty crypt
#

oh, didn’t think that far lol

next stone
#

silly

lofty crypt
#

fr

lofty crypt
#

unless

dull magnet
#

cause our code is minified too

lofty crypt
#

ig you could also regex all the calls, no?

dull magnet
#

if you look at the error in the console and enable source maps you get the real name

lofty crypt
#

’xD

trail ginkgo
#

yarn for discord

slow charm
#

unminify regex

trail ginkgo
#

going on the discord client mod bingo sheet

opal fern
#

Lmfao

austere gulch
#

actually so true

opal fern
#

Honestly someone should make a built-in sharex server

lofty crypt
#

xD

opal fern
dull magnet
#

lol someone is upset

dull magnet
#

you will stop using fake names

opal fern
opal fern
#

Otherwise I'll have to open GitHub app

#

Ahh fuck you I'm opening

dull magnet
next stone
#

search rotund balls on google

opal fern
dull magnet
#

search twinks frotting on google

opal fern
next stone
austere gulch
opal fern
#

Search blue waffles on google

#

🤯

dull magnet
#

NO

austere gulch
#

oh to be a twink frotting

slow charm
opal fern
#

Fawn about to be introduced to a whole new world

lofty crypt
#

that’s not frotting, Google 🤨

dull magnet
austere gulch
#

same

opal fern
#

Damn wtf

paper mountain
eternal lion
#

my iron chest is full lol

#

oops

#

wrong server

#

sorry

paper mountain
#

lmfao

dull magnet
#

wow

#

i didnt know jsdoc could literally replace typescript

#

@trail ginkgo u love

trail ginkgo
#

i found out when i had to do generics once

next stone
#

except it can't

#

for type hinting, sure, for anything else, not at all

dull magnet
#

holy shit

#

how is firefox so dogshit

austere gulch
#

actually so true

dull magnet
#

this just doesnt work

tropic galleon
#

Or use a jsconfig.json

orchid shard
#

Alright... So... I dont know if this is the right channel BUT hear me out..
I've never coded shit for Discord Mods and have a big respect for anybody that is willing to put up with having to constantly fix their plugins after discords great updates
But I have a single Plugin from BD that is the only reason I just cant switch over to Vencord even tho BD is crashing every 2 mins
What would someone realistically charge to port https://github.com/Dastan21/BDAddons/blob/main/plugins/FavoriteMedia/FavoriteMedia.plugin.js over to Vencord now that third party plugins are a thing?

GitHub

My personals plugins/themes for BetterDiscord. Contribute to Dastan21/BDAddons development by creating an account on GitHub.

#

(the functionality of the plugin is basically to add favourites like the gif ones to all media, be it audio, mp4's or pics)

orchid shard
#

WOAH

#

THANK YOU

sonic badger
#

any chance I could get a review on async message events pr

cedar olive
#

I can review it tomorrow

sonic badger
#

sweet, thx

nocturne dragon
#

merge

near aurora
#

but jsdoc more clunky

#

there should be a tool that converts ts to jsdoced js

lofty crypt
sonic badger
lofty crypt
#

type-fest
glorious name w_rabbitlaugh

potent fox
#

@dull magnet this guy will take vencord down with his innovations

cedar olive
dull magnet
#

wdym

#

we already depend on that library

#

you can just use it

cedar olive
#

well isnt it better to use Promise instead of PromiseLike

dull magnet
#

why would it be

#

they also mean Promiseable

#

Promiseable is a utility type that means Promise<T> or T

cedar olive
#

no it means T or PromiseLike<T>

woven lion
#

it doesnt matter xd

#

if its awaitable its fine

cedar olive
#

aight

south ridge
#

where was the patchhelper again?

woven lion
#

build in devmode

green vessel
south ridge
#

yop figured

#

thank uu

austere gulch
green vessel
#

true

south ridge
#

alright fixed the chat bar icon

#

@austere gulch you will review patch

#
            find: ".activeCommandOption",
            replacement: {
                match: /(.)\.push.{1,50}\(.{1,3},\{.{1,30}\},"gift"\)\)/,
                replace: "$&;try{$1.push($self.chatBarIcon())}catch{}",
            }
#

you will love

silk sorrel
#

any update on your decision?

cedar olive
#

this makes no sense

#

this is failing

#

but I didnt even touch the build function

#

and it works fine If I build using the cmd

#

oh got it

lofty crypt
#

what was it?

cedar olive
#

it was something else failing

dull magnet
#

pretty easy if youre smart

#

electron is a framework not a language

#

though u dont need to kno much about it

cedar olive
#

it works completely with git already

#

I'm gonna make a pr

faint siren
#

is there already some easy way to patch context menus?

#

specifically the GuildContextMenu

cedar olive
#

yes, soon

woven lion
#

context api coming soon

faint siren
#

nice

#

appreciate all your work!

lofty crypt
#

^ alr left server

river talon
#

Hiya, i'm a bit confused about how components work

#

i see a lot of plugins that just put normal html in the return of a function

#

for instance in the MemberCount plugin

#

when i try to do it it yells at me though Confused

viral roost
river talon
#

oh lmao

#

you can tell i am not a web developer

#

thank you very much

viral roost
#

wy

#

also heads up you cant use components at the top level, they have to be within a function

river talon
#

yee i'm seeing that from looking at other plugins

lofty crypt
#

huh what then?

lofty crypt
#

huh

cedar olive
#

Vencord.Webpack.Common.SelectedGuildStore.getGuildId()

dull magnet
#

Vencord.Util.Discord.getCurrentGuild()

#

works too

keen delta
#

there is no log tracker on the messagedeleted plugins

#

?

cedar olive
#

huh

keen delta
#

just a question

cedar olive
#

what do you mean

keen delta
#

like a button or something to see the last message deleted

cedar olive
#

nope

keen delta
#

and there is no gameactivity toogle ?

cedar olive
#

is it a specific activity you dont want to show

keen delta
#

no like u click on a button and ur game activity is not showing anymore

cedar olive
#

I know, but why do you want it to not show

#

do you want to disable it when you are playing a specific game?

keen delta
#

idk sometimes i toogle it to don't play with people

cedar olive
#

ah

#

either way no

river talon
#

is it just me or is the powercord api pretty weird

cedar olive
#

there is only IgnoreActivities which lets you not show the status for activities you select

keen delta
#

if i create a plugin i can have it instantly

river talon
#

having a look at a plugin i want to translate, guy makes direct calls to the inject method

keen delta
#

or there is a verification ?

dull magnet
#

yes it is

cedar olive
#

you open a pull request to the repo

#

if it's merged then it turns into an official plugin

keen delta
#

yeah so there is verification i can not make selfplugin

river talon
#
inject('better-folders-guildsTree', GuildsTreeStore, 'getGuildsTree', (_, res) => {
            const ret = new GuildsTree()
            ret.root.children = res.root.children.filter(e => props.guildFolders.includes(e.id))
            ret.nodes = props.guildFolders.map(id => res.nodes[id])
            return ret
        })
#
const { inject, uninject } = require('powercord/injector')
cedar olive
#

you can if you install using the power user method

#

which you are gonna need anyways to make plugins

cedar olive
keen delta
#

how can i have it ?

cedar olive
river talon
cedar olive
#

inject is powercord patcher

dull magnet
#

how else would u

#

oh thats smth else

cedar olive
#

yeah

#

same method name but something else

dull magnet
#

"inject" is just what powercord called their monkey patcher

#

stupid name

river talon
#

which file is it in lol

dull magnet
#

its just monkey patch

cedar olive
#

if you are porting plugins you dont want it

#

we do no monkey patch

river talon
#

okay i see

#

i'm not even sure what this is for

#

he immediately unpatches it

green vessel
#

should've been called XC_MethodHook trolley

dull magnet
#

it replaces functions

river talon
#

ahhhhhhh

cedar olive
#

basically monkey patch replaces functions, while vencord uses regex matching to insert your code inside the original function

dull magnet
#

he already ported that himself lol

river talon
#

i kind of just want to port the folder in a second row

river talon
#

ah šŸ™

keen delta
#

can we use multiple theme ?

river talon
#

yeah that's exactly what i want

cedar olive
river talon
#

good to know i won't have to do that myself

keen delta
dull magnet
river talon
#

nice nice

cedar olive
#

and yes you can.

keen delta
river talon
#

guess i'll compile this myself for now until it's merged

keen delta
river talon
#

simply use multiple links?

cedar olive
#

paste each link in a new line

river talon
#

it would be nice if we could toggle each theme

#

right now i'm just breaking the link for the one i'm not currently using

cedar olive
#

just add a invalid character

#

yeah

river talon
#

yeah but a lil toggle would be cleaner

cedar olive
#

we need an array component

river talon
#

maybe i'll make a PR for that

cedar olive
#

I think vap was working on that

river talon
#

ah okay

cedar olive
#

dang this is ugly

river talon
#

lol

keen delta
#

vencord is pretty cool

#

better than bettertrashcord

paper mountain
#

I'm sorry for bothering you, do you have a rough idea of when this should be done?

lofty crypt
#

ping didn’t track, Panda is not on the server anymore

paper mountain
#

aw what

#

damn

#

I was really looking forward to that

lofty crypt
#

you could dm him

pulsar arrow
#

is there a way to use animated gifs/pngs in a discord rpc? I stole found a way to do so for gifs but it requires the gifs to be uploaded to discord first @covert nimbus

#

by found a way I mean copied how it worked from replugged kekDoge

covert nimbus
pulsar arrow
covert nimbus
#

curious. mind looking around in the LocalActivityStore and showing me the asset?

Vencord.Webpack.findStore("LocalActivityStore") and try to find it

#

if it doesn't start with mp: then that is discord being bad at their job

pulsar arrow
#

also now I happen to make gif urls work, maybe that one time I tried I provided a wrong gif link or something causing it to give the broken image icon šŸ˜…

covert nimbus
#

check prototype maybe?

pulsar arrow
austere gulch
#

if you want values, use __getLocalVars()

covert nimbus
#

whatever.findStore(...).getActivities()

#

oh really?

austere gulch
#

it'll return the current state of store

#

ofc you should use the functions if they're relevant

#

but they don't always do everything you want

covert nimbus
pulsar arrow
#

oh another issue I found, whenever updating the rpc (by that means clicking "Save and Close"), it stops running (?) and I have to toggle the plugin on and off again for it to display the rpc again

covert nimbus
#

yeah that's a big im too lazy to debug

#

bug

#

ffs

covert nimbus
pulsar arrow
covert nimbus
#

discordā„¢ļø

#

(jsyk, discord is incredibly inconsistent when it comes to activities)

pulsar arrow
#

apparently yeah wheeze, thank you for your time!

covert nimbus
#

no, feel free to ask anytime!

#

oh for fuck sake

#

np*

pulsar arrow
#

ok come back @covert nimbus I managed to fuck it up again

covert nimbus
#

i have been summoned through an unholy ritual

what does thee seek,

pulsar arrow
#

turns out it's okay with external image links? but with any images/gifs sent from discord I suppose it gives the broken image symbol

covert nimbus
#

oh uhh probably because it sees discord and goes "real"

pulsar arrow
covert nimbus
#

h u h

pulsar arrow
#

they're using the media.discordapp link

#

isn't that old or so I've heard?

covert nimbus
#

......i have no clue

pulsar arrow
#

here's the gif https://cdn.discordapp.com/attachments/643456544255639552/1081817160466300948/cat.gif

covert nimbus
#

I'll debug it when it's not 2AM trolley

pulsar arrow
#

get some rest 1550prayingcat

covert nimbus
#

once again, no problem

#

i will not sleeo trollmas

#

sleep

lofty crypt
#

owo no?

pulsar arrow
pulsar arrow
#

basically they just regex'd the domain off and append mp: from there

queen sedge
#

@dull magnet so am i just modifying the build workflow to only delete unpacked and adding update_url to the manifest?

#

also wouldnt the manifest file also need pushing to the builds repo

dull magnet
#

no clue

dull magnet
#

because those are separate electron browser windows

#

we only patch the main one

#

it wouldn't be too hard to patch the other ones too though

proud parrotBOT
# dull magnet https://github.com/Vendicated/Vencord/blob/main/src/patcher.ts#L74-L97

**patcher.ts: **Lines 74-97

class BrowserWindow extends electron.BrowserWindow {
    constructor(options: BrowserWindowConstructorOptions) {
        if (options?.webPreferences?.preload && options.title) {
            const original = options.webPreferences.preload;
            options.webPreferences.preload = join(__dirname, "preload.js");
            options.webPreferences.sandbox = false;
            if (settings.frameless) {
                options.frame = false;
            } else if (process.platform === "win32" && settings.winNativeTitleBar) {
                delete options.frame;
            }

            if (settings.transparent) {
                options.transparent = true;
                options.backgroundColor = "#00000000";
            }

            process.env.DISCORD_PRELOAD = original;

            super(options);
            initIpc(this);
        } else super(options);
    }
}
dull magnet
#

you need to edit this

#

line 76 in particular

proud parrotBOT
# dull magnet https://github.com/powercord-org/powercord/blob/v2/src/browserWindow.js#L17-L35

**browserWindow.js: **Lines 17-35

if (opts.webContents) {
  // General purpose popouts used by Discord
} else if (opts.webPreferences && opts.webPreferences.nodeIntegration) {
  // Splash Screen
  opts.webPreferences.preload = join(__dirname, './preloadSplash.js');
} else if (opts.webPreferences && opts.webPreferences.offscreen) {
  // Overlay
  originalPreload = opts.webPreferences.preload;
  // opts.webPreferences.preload = join(__dirname, './preload.js');
} else if (opts.webPreferences && opts.webPreferences.preload) {
  originalPreload = opts.webPreferences.preload;
  if (opts.webPreferences.nativeWindowOpen) {
    // Discord Client
    opts.webPreferences.preload = join(__dirname, './preload.js');
    opts.webPreferences.contextIsolation = false; // shrug
  } else {
    // Splash Screen on macOS (Host 0.0.262+) & Windows (Host 0.0.293 / 1.0.17+)
    opts.webPreferences.preload = join(__dirname, './preloadSplash.js');
  }
dull magnet
#

you can likely yoink these from powercord

paper mountain
#

"yoink" (steal)

dull magnet
#

pog

#

why are there switches

#

you can disable features? PikaWhat

#

but only locally

lofty crypt
#

heh cool

cedar olive
#

nvm

faint siren
#

We could copy pasta the message context menu api from replugged now

dull magnet
#

no

#

we have a way more powerful context menu that can patch any context menu

#

but it's not merged yet

#

sooon

#

should I just yolo and merge @cedar olive

cedar olive
#

nono

#

we need the branch thing working

#

then we can merge everything

cedar olive
queen sedge
#

@dull magnet q: are we gonna work on a devbuild store published extension or nah

faint siren
#

any way to update discords electron version?

cedar olive
#

Openasar I think

faint siren
#

hm i see

viral roost
#

just use armcord

cedar olive
#

armcord is completely different

#

you will lack discord features

#

it's not just updating electron version

faint siren
#

since when is openasar updating the electron version?

viral roost
#

since never

#

they tried but it's been stale

faint siren
#

i see

#

just updated to electron 13.6.8

dull magnet
#

it uses very recent electron

faint siren
#

canary doesn't display the electron version though? ._.

dull magnet
#

?

faint siren
#

or do i need to install Vencord for that?

cedar marsh
#

Just run a command in console to get it then

faint siren
#

yea, just got the user agent, nvm

cedar marsh
#

process.versions.electron
Oh yeah or that

faint siren
#

electron 22.2.0, sheesh

faint siren
cedar olive
#

then I can fix emote cloner too

dull magnet
#

hmm

#

I mean

#

try again if it fully works

#

my main concern is that it breaks some random lazy loaded chunk so we don't notice but then some poor guy crashes

cedar olive
#

I doubt it would

#

it's way too simple

dull magnet
#

maybe

#

idk I think I approved right

cedar olive
#

ye

#

I'm gonna do a last test

dull magnet
#

worst thing that happens is it causes issues and we undo

cedar olive
#

either way we have crash handler now

dull magnet
#

yeah just merge if it works

#

waiting longer won't help

#

I mean unless u wanna do dev branch first but I still gotta look at that

cedar olive
#

yeah I will merge

#

I'm just resolving conflicts

#

not with the actual pr

#

just my permissions viewer edit using the api

#

oh

#

maybe I can improve the patch too

dull magnet
#

wait

#

does ur context menu pr check key length too

#

cause the key length check isn't there for funnies or similar it actually considerably improves performance

cedar olive
#

nop

#

I will do

dull magnet
#

I tried

#

and it really does

proud parrotBOT
dull magnet
#

the reason is that it allows us to not check non mangled stuff

cedar olive
#

good thing I tested

#

some patches aren't working for some reason

#

they used to

dull magnet
#

huh

#

which ones borked

cedar olive
#

the patch for adding the arguments

#

didnt get applied here

#

but did here

#

hmhm

#

one is jsx other is jsxs

#

my patch doesnt rely on that though

#

odd

#

wait

#

what

#

nvm

#

var r=(i(667294),i(322922))

#

EWW

#

horrible

dull magnet
#

you love minifier being stupid

cedar olive
#

ok we ready

dull magnet
#

what did u do

cedar olive
#

I fixed tonguecat

#

using the knowledge I learned yesterday

#

which means we lost no performance

#

first match the id, then find the variable being defined by it

dull magnet
#

why did you add back nowarn?

#

if the patch isn't faulty it shouldn't warn should it

cedar olive
#

nah

#

the find isn't perfect

#

it's the best we can do

dull magnet
cedar olive
#

with what

dull magnet
#

how does that work

cedar olive
#

match id -> lookbehind: .+? to match the id again, go back until it finds \i=

#

the minifier can put as many things before it

#

it's always gonna match correctly

dull magnet
#

I'm confused

#

then how do you match the variable name

cedar olive
#

it's the lookbehind

#

there's a capturing group there

dull magnet
#

yes but

#

you match the id and then the variable name after it

#

I'm confused

cedar olive
#

no

#

the lookbehind goes backwards

dull magnet
#

????

cedar olive
#

it's matching the variable name before it

dull magnet
#

how does it go backward

cedar olive
#

that's what happens when you put a lookbehind after a match

#

it's how it works lol

dull magnet
#

I'm confused

#

I don't really understand

cedar olive
#

"ahi".match(/hi(?<=(a)hi)/)

dull magnet
#

oh huh

#

so it does go back but u need the matched part as well

cedar olive
#

yop

#

that's why I always use .+?

#

so I dont have to write it again

dull magnet
#

that's so strange

cedar olive
#

true

dull magnet
cedar olive
#

but it allows for better performance

dull magnet
#

okay I understand it now but this behaviour is so obscure

cedar olive
dull magnet
#

it is a placeholder for the first group that you can use in the regex

cedar olive
#

heh

dull magnet
cedar olive
#

ah

#

but I'm not capturing as a group

dull magnet
#

yeah fair

cedar olive
#

but damn that's so good

#

I wish I knew that before

dull magnet
#

it's probably poor performing

#

lmao

cedar olive
#

hmm

dull magnet
#

but I used it to match something super obscure somewhere

cedar olive
#

context menu api kinda does it

dull magnet
#

like a function that literally goes `a(b!=null?c:d,f)

#

I matched that with backreference

cedar olive
#

maybe if I change to that performance will improve?

#

let me see...

dull magnet
#

like I matched b=props.foo then used backref to match b

cedar olive
#

cuz then I dont capture the whole match

#

oooo maybbb

dull magnet
#

it might indeed be faster

proud parrotBOT
dull magnet
cedar olive
#

I'm about to do obscure stuff

#

cursed

dull magnet
#
RegExp(`${id}(?<=(\\i)=.+?).*?\1\.${key}, \{`, "g"),
cedar olive
#
RegExp(`(?=${id}(?<=(\\i)=.+?).+?\\1\\.${key},{)`)
dull magnet
#

oh yeah I forgot to use lookahead

#

you want to pass "g" as second param tho

cedar olive
#

mimicking atomic group

#

true

#

this is cursed stuff lol

#

awn it didnt work

dull magnet
#

hmm why

cedar olive
#

oh wait

#

Ihold on

dull magnet
#

why tf did it match l

#

that makes 0 sense

#

maybe u can't nest lookahead and lookbehind like that

#

wait

#

(?=

#

this should be (?<=

#

@cedar olive

cedar olive
#

I got it to work

#

I'm testing performance

#
RegExp(`(?=(${id}(?<=(\\i)=.+?).+?\\2\\.${key},{))\\1`, "g")
#

this is probably the best we can get

#

I used this too, to maybe increase performance a bit https://blog.stevenlevithan.com/archives/mimic-atomic-groups

#

most patches take 0.2ms

#

giant files take like 15ms

#

wait

#

I got it better I think

#

then we dont have to insert the match

#

nvm I made it worse

dull magnet
#

300ms real

#

ship it

cedar olive
dull magnet
#

that regex is mega on drugs

cedar olive
#

lol okay

#

ok done

#

@dull magnet allowed to merge?

dull magnet
#

if it works properly and isn't slow yeah

cedar olive
#

It's as fast as possible lol

#

not 300ms

cedar olive
cedar olive
#

badd

faint siren
#

btw is there anywhere documentation for any of the apis?

cedar olive
#

jsdoc

faint siren
#

ah ke

cedar olive
#

@dull magnet great just found out that regex I did doesnt work as global

#

gonna have to revert to this one

                replacement: [{
                    match: RegExp(`${id}(?<=(\\i)=.+?).+$`),
                    replace: (code, varName) => {
                        const regex = RegExp(`${key},{(?<=${varName}\\.${key},{)`, "g");
                        return code.replace(regex, "$&contextMenuApiArguments:arguments,");
                    }
                }]
#

god it's indeed slower

#

welp can't do much

#

I'll wait for what you want to do

cedar olive
lost granite
#

hi with my friend (umm ..boyfriend) we made an api for bubble gifs we thought it would be nice to make a slash plugin or something like that

https://bubbles.octozu.xyz/doc

someone can tell me where to start for make plugin ?

opal fern
lost granite
#

thank you very much i will read all this !

lost granite
dull magnet
#

oh speech bubble

#

there is/was a plugin in the works to generate those on client side

potent fox
#

how th does that api work

dull magnet
#

you need to add a tag and maybe more according to docs

lost granite
#

yees

lost granite
lost granite
#

the goal and select the category with the command /

dull magnet
#

mantika type beat

potent fox
lost granite
#

and you cand add param nsfw and set true or false

#

by default it is false

#

what do you think of the idea ?

potent fox
#

theres so much femboy nsfw gifs

#

tbh it can be made

#

shouldnt be too hard

lost granite
lost granite
opal fern
#

uhhh

#

anyone know how to bypass cors

dull magnet
#

you don't

opal fern
#

damn

dull magnet
#

what's your use case

opal fern
#

calling wikipedia api

dull magnet
#

what's the endpoint

opal fern
dull magnet
#

the actual endpoint you're calling

dull magnet
#

??? don't be an asshole @cosmic mortar

opal fern
#

im not gonna interact

dull magnet
#

vban 7 @cosmic mortar toxic

shrewd tundraBOT
opal fern
#

what are my options ven

potent fox
#

running discord in insecure mode

dull magnet
#

apparently you need to pass origin=* as query parameter

opal fern
dull magnet
#

yes

#

add origin=* and it fixes cors

opal fern
#

alr

potent fox
#

I need to make vencord run discord in insecure mod

#

it will solve all of this corse proxy thing

#

happier developers

opal fern
#

alright thank you ven <3

dull magnet
#

did you know that guy or was he just a weirdo @opal fern

opal fern
dull magnet
#

🤨

#

don't do that

opal fern
#

alr

green vessel
#

in samu's defence he was in fact dumb

dull magnet
dull magnet
opal fern
#

fine šŸ™„

#

How do I make embeds for sendBotMessage?

paper mountain
opal fern
#

@dull magnet would a plugin like this be merged?

#

Searches wikipedia for articles that are similar to a keyword

cursive plank
opal fern
cedar olive
potent fox
#

ven thinks it should be mergede after 8 months

lost granite
#

I started to try to make the plugin, and well there is no real way to make commands / with parameters currently with the plugin command api no ?

dull magnet
#

there is

#

look at other plugins using commands

lost granite
#

ok just unlucky that every order i tried didn't have one x)

lost granite
#

There are several things I don't understand and as I don't really know in ts well I can show my code here and ask for advice?

opal fern
#

Yes, just make sure it's in a coffee block

lost granite
#

import { ApplicationCommandOptionType, findOption } from "@api/Commands";
import definePlugin from "@utils/types";

const urls = {
    hostname: "bubbles.octozu.xyz",
    sfwRandom: "/api/random/all",
    nsfwRandom: "/api/random/all?nsfw=true",
    tags: "/api/tags",
};

export default definePlugin({
    name: "Bubbles chat Gif",
    description:
        "This plugin is there to answer a GIF chat (to make as if it was the person above talking) there are several categories ",
    authors: [
        {
            id: 360119696944660481n,
            name: "Octozu",
        },
        {
            id: 691413039156690994n,
            name: "UwU",
        },
        {
            id: 686166148882104337n,
            name: "lambdagg",
        },
    ],
    dependencies: ["CommandsAPI"],
    request: async function (path: string) {
        const response = await fetch(`https://${urls.hostname}${path}`);
        if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
        return "https://" + urls.hostname + response;
    },
    commands: [
        {
            name: "randombubbles",
            description: "Send a Random bubbles gif",
            options: [
                {
                    name: "nsfw",
                    description: "Send a NSFW bubbles gif",
                    type: ApplicationCommandOptionType.BOOLEAN,
                },
                {
                    name: "category/tag",
                    description: "Send a bubbles gif from a category/tag",
                    type: ApplicationCommandOptionType.STRING,
                },
            ],

            execute(opts) {
                return {
                    content: findOption(opts, "nsfw", false) ? this.request(urls.nsfwRandom) : this.request(urls.sfwRandom),
                };
            },
        },
    ],
});
#

this is what I have done so far

#

and my problem is the request

dull magnet
#

you need to await it since it returns a promise

lost granite
#

ooh ok

#

Just before "this.request" so ?

dull magnet
#
const BASE_URL = "https://bubbles.octozu.xyz";
const RANDOM = "/api/random/all";

...
  async execute(opts) {
    const url = new URL(RANDOM, BASE_URL);
    url.searchParams.append("nsfw", findOption(opts, "nsfw", false));
    return {
      content: await this.request(url);
    }
  }
#

also that won't work because this refers to the wrong object so this.request is not what you want but typescript should have already told you

#

so the solution is to make request a top level function

lost granite
#

This is what it looks like, it is correct ?

#

import { ApplicationCommandOptionType, findOption } from "@api/Commands";
import definePlugin from "@utils/types";

const BASE_URL = "https://bubbles.octozu.xyz";
const RANDOM = "/api/random/all";
const NSFW_RANDOM = "/api/random/all?nsfw=true";
const TAGS = "/api/tags";

async function request(path: URL) {
    const response = await fetch(`https://${BASE_URL}${path}`);
    if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
    return await "https://" + BASE_URL + response;
}
export default definePlugin({
    name: "Bubbles chat Gif",
    description:
        "This plugin is there to answer a GIF chat (to make as if it was the person above talking) there are several categories ",
    authors: [
        ...
    ],
    dependencies: ["CommandsAPI"],

    commands: [
        {
            name: "randombubbles",
            description: "Send a Random bubbles gif",
            options: [
                {
                    name: "nsfw",
                    description: "Send a NSFW bubbles gif",
                    type: ApplicationCommandOptionType.BOOLEAN,
                },
                {
                    name: "category/tag",
                    description: "Send a bubbles gif from a category/tag",
                    type: ApplicationCommandOptionType.STRING,
                },
            ],

            async execute(opts) {
                const url = new URL(RANDOM, BASE_URL);
                url.searchParams.append("nsfw", String(findOption(opts, "nsfw", false)));
                return {
                    content: await request(url),
                };
            }
        },
    ],
});

dull magnet
#

well i changed ur URL logic so you now just need

async function request(url: URL) {
    const response = await fetch(url);
    if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
    const path = await response.text();
    return new URL(path, BASE_URL);
}
lost granite
#

a yes I'm stupid I had seen it

#

tf , I'm still having trouble reading, I'll read it all again xDD

lost granite
#

ooof now the famous CORS .. x) I'll see tomorrow, but thank you for your help, it's very kind :3

#

gn c:

dull magnet
#

you need to fix cors on ur server

#

its really easy

#

do u use express or what do you use?

#

you just need to add header Access-Control-Allow-Origin: *

lost granite
#

i use spring boot

#

but tonight I'm tired

#

but thanks for telling me anyway

lost granite
#

It works, but there's something I don't understand

#

It works when I put this ts return { content: await request(url)+"", }

#

but not that

return {
    content: await request(url),
}```
dull magnet
#

cause it returns a URL

#

you need to return string or toString it

lost granite
#

okey thx

analog lance
#

i somehow recall a custom regex backslash escape thing that matches discord minified variables

was i just hallucinating that? if not, what is it?

cedar olive
#

\i

analog lance
#

oh cool, thanks

#

is there a better way of doing this

#

wait no this wouldn't work

#

hold on guh

#

wait this is a thing

#

nvm that seems to not do what i need

analog lance
#

i think i got it, hold on

green vessel
#

yea you dont really use those in patches

#

thats just a normal js thing

covert nimbus
#

oh fuck it i give up, how do i add something up here?

(ignore the missing texture svg)

cedar olive
#

@dull magnet I just made ContextMenuAPI patches all take less than 1 ms using proxies

dull magnet
#

how

cedar olive
dull magnet
#

wait what

#

I'm confused what does that do

cedar olive
#

cuz we no longer have to match the entire module

#

that's what makes it so slow

#
.                          this
RegExp(`${id}(?<=(\\i)=.+?).+$`
#

let me add some comments lol

cedar olive
covert nimbus
#

how do i colour this button properly

#

(placeholder texture until actual svg is made)

covert nimbus
#

once again reading invisible-chat source saves me

potent fox
eternal lion
lost granite
#

there is really a problem that I can not solve otherwise everything is fine

when the request doesn't go well it just sends the text /

dull magnet
#

working on vscode extension (yes test patch is in the wrong location i will fix)

#

still gotta actually implement the testing which I plan to do by running a websocket in the discord client inside an IS_DEV guard then connecting to that websocket from the extension

I also want to add test for all webpack find methods that ensure finds match exactly 1 function

#

might interest you @trail ginkgo

#

also i have no idea how vscode extensions api works but i figured out how to do code lens thingie and thats all i needed trolley

dull magnet
#

grr ts doesnt seem to have a way to walk the entire ast

#

like this is just direct children

#

oh wait

#

can just do this

dull magnet
#

why does walk only visit 6 but walk2 visits thousands

#

its the return whaaa

#

OHH

#

if you return a value it stops

eternal lion
#

Nice

dull magnet
#

You can now install the Vencord vscode extension from https://marketplace.visualstudio.com/items?itemName=Vendicated.vencord-companion which is basically PatchHelper but inside vscode

It adds "Test Find" on any webpack finds that will test whether your filter finds exactly one module (and not more or none)
It adds "Test Patch" on any patches you define in definePlugin() that will test that your find is unique and your match and replace works and compiles correctly

To use it you also need to compile Vencord with DEV (aka pnpm build --watch or pnpm buildWeb --watch) and enable the "DevCompanion" plugin. Then just start Discord after vscode (or right click the user settings cog and click "Reconnect Dev Companion")

lofty crypt
#

i’m sorry but this is epic

lofty crypt
#

can i do venc dev stuff with chrome or only standalone?

south ridge
#

In all seriousness ven, how would i add custom plugins / edit them on web. I'd like to find out what prevents invisible chat from working.

dull magnet
#

csp probably

#

if on firefox or userscript

#

you can also just pnpm buildWeb to build web stuffs

south ridge
#

the chat button just doesnt

dull magnet
#

oh interesting

south ridge
#

what i'm plaintext patching on desktop doesnt seem to exist on web

(.)\.push.{1,50}\(\i,\{.{1,30}\},"gift"\)\)
#

would be cool if you added a chat icon api to avoid such issues

dull magnet
#

kinda too niche imo

south ridge
#

wdym

dull magnet
#

but if someone makes it and its good then sure

south ridge
#

i mean, 2 plugins rely on it and neither will work on web cirnoshrug

pure temple
#

arghhh!! i'm so badd!
(i'm trying to make stupidly small ui tweaks)

#

is there a good way to do this?

eternal lion
#

What are you trying to do?

pure temple
#

i'm trying to get rid of the toggle on required plugins since it's kind of misleading

#

maybe they should stay though

#

one thing that definitely doesn't make sense is that the whole card is dimmed

#

however, the settings and info buttons are clickable

#

before and after ✨! the padding looks weird though

woven lion
#

just conditionally render the toggle in the actual component, dont do stuff like this

#

{!disabled && <Switch .../>}

pure temple
#

ahh

#

i knew it was bad, but thanks!

silk sorrel
woven lion
#

react won't render anything

silk sorrel
#

ic

pure temple
#

i'm also adding a notification preview button

#

is a fix annoying things pr fine?

#

lol

woven lion
#

sure thing

#

we had one recently

south ridge
#

thats on web?

cedar olive
#

yep

south ridge
#

odd

#

doesnt seem to appear for me

cedar olive
#

chromium

eternal lion
faint siren
#

where's the example for the context menu api again?

cedar olive
#

check emote cloner

faint siren
#

aight

#

any idea how i can patch the guild context menu with this?

pure temple
eternal lion
#

meh

#

idk

viral roost
#

or just take it from ViewIcons probably

faint siren
#

thx

#

well other question, how do i add the react dev tools to the client

#

nvm

#

found

viral roost
faint siren
#

wait, is the guild header popout a context menu?

viral roost
#

looks like it

#

guild-header-popout

faint siren
#

ye

#

btw is there hot reload for plugins or do i have to restart everytime i change something?

viral roost
#

hot reload isnt possible with how vencord patches work (i think)

faint siren
faint siren
pure temple
eternal lion
#

hmm

#

well you can see how it turns out ig

pure temple
#

would you still agree it's confusing having something which you can interact with appear as unavailable?

hexed cargo
#

is there a way to add a context menu application command with a plugin?

dull magnet
#

yes but it doesnt work

#

you could just add a regular context menu item

hexed cargo
#

how do ThinkingFoxi

faint siren
#

u chads wanna add TabBar as a component to Webpack api?

empty jacinth
#

@green vessel @dull magnet i'm working on a toggle for last.fm right now. just need to know, should the option be "Hide album art when missing," "Use placeholder when album art is missing," or maybe a dropdown saying "What should we show when there's no album art?" with the options of "Placeholder" or "Last.fm Logo"

#

i also want to implement code to check if the API itself is returning placeholder art and hide it.

#

which would make more sense in the context of the option.

faint siren
#

@dull magnet as icon for a context menu entry

dull magnet
#

as I said just make it a react component

#
function Icon() {
    return <svg><path /></svg>
}```
faint siren
#

yea

empty jacinth
#

I actually added a third option

#

Second option is the behavior before PR, third option is my original PR

pure temple
#

me trying to test

#

me not knowing properly how react works before doing this

lofty crypt
#

way to go šŸ™‚

pure temple
#

šŸ‘‹ hi [object Object]test

pure temple
#

i'm trying to get compact mode to work with pronouns!

#

it would also be nice if it worked in the modal too

dull magnet
#

does it not work in compact mode?

pure temple
#

not currently

lofty crypt
pure temple
#

it does! unfortunately the plugin in vencord doesn't though

pure temple
#

haha

#

oh no

#

i think my pronouns are in too many places

lofty crypt
pure temple
#

vencord enables discord's pronouns experiment which is risky tbh

#

(risky because it could disappear)

lofty crypt
pure temple
#

it uses discord's

lofty crypt
#

oh

pure temple
#

i don't know how to access discord's settings though!

lofty crypt
#

what settings?

pure temple
#

compact mode

lofty crypt
#

lol

#

ay, pronouns are important, i don’t see the problem trolley

#

there’s prbly a css class, ima have a look

pure temple
#

i was also considering a github-style option for the profile

#

there is!

#

but i thought it would be good to skip the logic if compact is disabled

#

otherwise it's doing it twice

lofty crypt
pure temple
#
if (compact)
    return;
#

basically this!

lofty crypt
#

yeah your if condition could be the existence of any compact-mode–only class in the dom

pure temple
#

hmm, well it currently just has the message object

lofty crypt
#

it =?

pure temple
#

the function

lofty crypt
#

what’s the msg obj? feel free to paste code if you like^^

#

ah nvm

#

well the dom is always at hand

#

sec, i’ll write the condition

cedar olive
#

The right thing to do would be to remove the logic that checks for compact mode

lofty crypt
#

and let the browser’s css engine handle it?

cedar olive
#

for the component in the user modal it's easy, there is aready a patch that is in the same place that logic is

cedar olive
pure temple
#

ohh

lofty crypt
#

oh, the one which hides the pronouns for compact mode?

pure temple
#

well then you'd have two timestamps

#

the timestamps being different stops it from working

cedar olive
#

modify that one too

#

hm

lofty crypt
#

that sounds a bit roundabout

pure temple
#

well in compact mode it should probably appear to the right of the username instead of the left

lofty crypt
#

tho i haven’t thought it through (or even know much about how all this works)

cedar olive
#

well you can patch that place and add it there

#

how are you adding the components?

pure temple
#

you can see the existing code

#

i'm just trying to improve it

#

it's by TymƦn (i am not a lame face)!

cedar olive
#

I know

pure temple
#

ok i just had to say that

cedar olive
#

how are you adding it when it's compact mode though

pure temple
#

by adding a child next to the username component

cedar olive
#

I see

pure temple
#

the username component is the same in both modes

lofty crypt
pure temple
#

hmm i guess the surrounding code probably already checks compact

#

yes, it's a var called c

lofty crypt
#

i’d suggest adding it either way and making it display:none via css for compact mode. That way the mod can be modded

pure temple
#

hmm

lofty crypt
#

also it’s v simple; also portable to other mod techs that don’t rely on regex patching

pure temple
#

i don't want the code to run at all

lofty crypt
#

why?

pure temple
#

well if you're not in compact mode, fetchPronouns will presumably be run twice

lofty crypt
#

but after the first request per user that just accesses a cache, right?

pure temple
#

ah, i just saw the code

#

css is probably best

lofty crypt
#

like, you don’t send a request to the pronounsdb server for every single msg?

pure temple
#

but the selector is kind of random

#

:P i wasn't sure if it cached the fact a request was sent but it does

lofty crypt
#

[class*=compact] on the right element would surely work. Maybe there’s a slightly better approach. i can look into that if you like

pure temple
#

doesn't the class have random chars though?

lofty crypt
#

yeah, we only match on the constant part in the front

#

*= means anywhere in the attribute: *compact*

pure temple
#

oh, css can do that?!

#

that's useful

lofty crypt
#

mhm catnod

#

yeah

pure temple
#

i wish i had known that earlier

#

i tried making a dark theme for google extension some years ago and didn't know this!

lofty crypt
#

since recently it can even go both ways in the dom hierarchy with :has()

pure temple
#

ah, i've defintely needed that at times

lofty crypt
#

haven’t we all nodKermit ^^

pure temple
#

i did know about that but last time i wanted to use it no browser could

#

how can you add a css file?

lofty crypt
#

yup, great new times!

  1. has()!
    (2. ai taking over all (super)human work)
pure temple
#

yay!

lofty crypt
pure temple
#

to vencord

#

i don't think bing will tell me this

lofty crypt
#

cheers!

#

huh?

pure temple
#

do you just import it?

#

I doubt that would work but it's what I saw in other plugins

lofty crypt
#

oh, right hehe

#

yeah idk that, i haven’t made a plugin yet. But i’ll look into one right now and return with the answer blobfingerscrossed

proud parrotBOT
pure temple
#

it works!

#

kind of

#

apart from the flickering

#

hmm, it normally flickers

lofty crypt
#

gg! :DD
yeah, the pronoundb extension sadly also has slight flickering problems. i don’t usually notice them anymore, but would ofc be nice to polish them out. Not necessarily before publishing your first release version tho šŸ™‚

i’m thinking with the component source patching approach this should be fixable

pure temple
#

it feels quite janky :P

#

it's less visible in cozy mode

lofty crypt
#

good. That’s the important mode. ||;)||

pure temple
#

still, it shifts the messages a tiny bit

#

cw: i guess it flashes a bit :P

#

another thing i'd like to do to improve it is add it to the profile dialog!

#

currently it only shows in the popout

lofty crypt
pure temple
#

it doesn't show here

#

1 karma :P

lofty crypt
#

oh the global profile

pure temple
#

still have that shown