#🧩-plugin-development

1 messages Ā· Page 72 of 1

proud parrotBOT
iron epoch
hushed loom
#

That returns a function that loads the module

#

You then need to find the module like normal

iron epoch
#

noted

cedar olive
#

that's correct

#

you can use Discord own function for lazy modules for that

#

no need to use our own

iron epoch
#

okay I tried this

const requireCustomStatusModal = extractAndLoadChunksLazy(["this.renderCustomStatusInput()", ".CUSTOM_STATUS_MODAL,"]);

to get the modal of the custom status, but idk what's wrong here
it raises Uncaught Error: extractAndLoadChunks: Couldn't find chunk loading in module factory code.

#

that error been raised in devtools as I was testing if it works or not

bronze dove
iron epoch
#

ohhh

#

that's explains a lot

swift delta
#

Im very shocked and surprised that this actually works...

hushed loom
#

i would never send bad code clueless

swift delta
humble tulip
humble tulip
#

I think this is gonna be a bitch to make polished

real sequoia
#

whats a regex patch and how is it different from a monkey patch?? how do i use it to make a plugin?? pls help n thank u

vast karma
#

Regexes patch the code before the module is run, monkey patches replace functions after it's run

real sequoia
humble tulip
#

It's a proof of concept for now, it's not using chat spacing atm

real sequoia
#

other than that it looks great, vencord plugins are enabled in it too which is great

humble tulip
#

Thanks though

#

I'd like to just use Discord's chat component but that just takes a channel id and handles loading the messages itself so I can't just give it a list of messages

vapid oar
#

is there a way to bypass cors for a little private userplugin im making?

humble tulip
#

Make the request in a native.ts file

real sequoia
#

@humble tulip hi! you seem knowledgable about making plugins. Could I bother you in DMs about simple questions because i'm new to making plugins ??? (beginner to vencord plugins, decent ish dev [py n some other stuff]) or can you link me some docs i can look at?

hushed loom
#

There are plenty of people that could help you

humble tulip
#

Yeah tbh basically everyone here is more knowledgeable than me lol

real sequoia
real sequoia
# hushed loom Ask here

lowkey wanna make a character count plugin similar to the BD one, just useful when you're writing a large annoucement or something similar

#

I setup everything and even built vencord, but i cant figure out how to get UI to show and also the counting itself....did fiddle around and was able to make the plugin settings thing work

swift delta
real sequoia
#

and me a totally dumb person can probably make something better than BD

#

(let's hope)

#

And even if I don't sumbit it I'll probably have fun with the experience

swift delta
swift delta
hushed loom
#

@real sequoia I assume you're having issues with the patches

swift delta
real sequoia
real sequoia
hushed loom
# real sequoia yes

do you know what / have experience with webpack or other bundlers in that style

humble tulip
#

Patch Helper is good for visualising what it's actually doing

#

Being able to see the replaced code

real sequoia
hushed loom
#

so discords code is split up into modules
think of them like one file, in a whole project

#

each module has a number, but that number can change at any time

hushed loom
#

yes

#

what patches do is they find a module by a string (or regex, but you shouldnt need that in 99% of cases)

#

then within that module they match parts of discors code

real sequoia
#

and then replace them?

hushed loom
#

and replace them with your string

real sequoia
#

ah

#

simple enough

hushed loom
#

few more things

#

you can use \i to match any javascript identifier

#

(think variable names)

real sequoia
#

How would I find a webpack?? I saw something similar in pins of this channel, but I couldn't make sense of it

hushed loom
#

replace is just an argument passed to string.replace

hushed loom
real sequoia
#

yes

#

first thing i do when i download a fresh instance of vencord

#

wrong image

hushed loom
#

make sure you have nodevtoolswanring, console janitor, console shortcuts, and react error decoder enabled

real sequoia
hushed loom
#

they're good to have while making plugins

hushed loom
real sequoia
hushed loom
#

@real sequoia each number: function entry here is a module

#

with the number being the module id

tight canyon
#

How can i ctl+f with new intl keys in devtools?

cedar olive
#

wdym exactly

hushed loom
#

(with console shortcuts)

tight canyon
hushed loom
#

i ended up doing it so often, i made a keyboard shortcut that hashes my clipboard 😭

cedar olive
tight canyon
cedar olive
#

you can also do this

#

if you search that it gives all the places it is used, excluding where it's defined

tight canyon
#

Thank you

hushed loom
#

does anyone know if flux events are syncronous eg waits for the first callback to finish before calling the next one

cedar olive
#

pretty sure they dont await

swift delta
#

What is the rule about posting mirrors in an unofficial plugin post?

swift delta
# hushed loom what

i got bored and made a mirror on git.gay and idk if you allowed to edit a post to add it there

swift delta
hushed loom
#

just edit your og post

#

dont think it matters that much

swift delta
#

I didn’t know if you’re allowed to use something other than github tho

#

I mean Nino does tho

hushed loom
swift delta
#

fair… plus git.gay is well trusted, and very reputable

hushed loom
swift delta
#

@cedar olive Am i allowed too? prayingcar

cedar olive
#

ya

swift delta
#

ok

hoary pilot
#

almost all forgejo instances retained the MIT license, while gitgay inconsistently licensed under the OQL, which is a source available license, with contradicting statements from the maintainers on what was (not) licensed

but ever since forgejo v9 going gpl they’ve been forced to go gpl too blobCatCozy

dull magnet
swift delta
# dull magnet >git.gay <:husk:1026532993923293184>

its just a mirror so i have a backup somewhere… plus it’s easier then just putting one on codeberg or something…
plus where else am I gonna put it… you gotta do some weird shit to put a mirror on codeberg, Nin0’s forgejo is down, git.lgbt is unstable rn, and I’m not about to host my own

cedar olive
hushed loom
cedar olive
#

well if its synchronous code that's obvious

#

you could check the dispatcher code too

#

but I'm prettyyyy sure it does not await asynchronous functions

#

it you look in console janitor there's one patch that targets something related to time

#

it's right where events are processed

#

just look if there's an await or .then blobwob

humble tulip
#

Couldn't you just try dispatching a couple of events?

cedar olive
#

easier to look at the code

hushed loom
#

Did I imply that it did?

cedar olive
#

that's what I understood from your question

hushed loom
#

Oh, oops

cedar olive
#

because else in no case that's possible

#

JavaScript is single threaded

#

it's always going to execute everything sync unless it's an async function or promise

hushed loom
#

I think I just worded myself wrongly blobcatcozy

swift delta
dull magnet
#

why

#

include exactly 1 link

#

which would be the original repo

swift delta
dull magnet
inner monolith
#

Why can't I pull?

#

I feel so stupid

#

I don't have the latest calltimer patch

rocky lynx
#

why are you pulling and building manually? use the built in updater

inner monolith
#

updater?

#

how do you know of such things

#

where are any of these documented

rocky lynx
inner monolith
#

would this update the github repository?

rocky lynx
#

it pulls from the github repo

inner monolith
#

this is a 2 week old commit

#

I want the latest patch

#

because one of the plugins i use is broke in canary, and fixed on the latest patch in the main branch

inner monolith
#

nothing?

oak sundial
#

this channel is for help with developing plugins, not for help with installing/updating dev builds

unkempt hemlock
#

it's probably a good idea to migrate the preference from the old plugin too (as it was done with the ShowAllRoles plugin)

#

personally I think it should just be deleted, no need to keep it around

cedar olive
#

it's forcefully disabled

#

after migration

#

because it does nothing

unkempt hemlock
cedar olive
#

ig

unkempt hemlock
#

ideally the plugin should be deleted and users be advised with the @plugin announcements role about it

cedar olive
#

nah

#

but yeah I'll make it keep enabled

#

(though now it's pretty later already lol)

unkempt hemlock
#

:p

unkempt hemlock
cedar olive
#

but honestly most people wont even notice

unkempt hemlock
#

if I understand it correctly

#

the new plugin has already done the migration

cedar olive
#

if enabled -> turm discord setting on -> disable itself

#

so the actual feature keeps working, and it's no longer done by the plugin

unkempt hemlock
#

yes, but does it take the previous user preference into account?

#

by user preference I mean the plugin being enabled before this change

#

I believe it doesn't

cedar olive
#

it only migrates if its enabled yes

unkempt hemlock
#

yes, but after the migration you can't tell if the user had it enabled previously

#

you can only tell if the stock discord setting is enabled or not

cedar olive
#

yeah

#

but that doesn't matter much

#

as the plugin will be deleted in a bit

#

we don't neee that info unless we wanna undo the migration

#

but no reason for it

unkempt hemlock
#

so I think a better way to solve this problem is to keep this code to migrate to the new Discord setting but keep this plugin hidden somehow, so it doesn't cause confusion by being enabled/disabled

"why is this plugin disabled? I had it enabled before"
"what's the difference between having this plugin enabled and the stock Discord setting?"

cedar olive
#

I understand it

#

but now it's kinda late

#

a lot of people updated already

unkempt hemlock
#

yes, that's good, but we have to take into account the people that didn't yet

#

for the people that have already updated we don't have to worry anymore

cedar olive
#

ya

#

I'll see later today

unkempt hemlock
#

so for the people that didn't we can make the plugin hidden but still keep the code

#

and it solves my initial problem

#

:)

cedar olive
#

I understand it can be confusing for people enabling the plugin now

unkempt hemlock
#

ye

#

thanks for understanding!

rocky lynx
#

I figured out patches

#

its alot easier than i originally thought

vast karma
#

That's what we all keep saying

amber basin
#

what flux event would i use to get when the user sets their status

amber basin
#

got it from user settings proto update, but how would i set the status?

#

not selfbotting, making a plugin to sync status between platforms

bronze dove
amber basin
#

can that change the text?

#

im toying with updating proto myself rn

bronze dove
amber basin
#

right now i have ts FluxDispatcher.dispatch({ local: true, partial: true, type: "USER_SETTINGS_PROTO_UPDATE", settings: { status: { customStatus: status ? { text: status, emojiId: settings.store.emojiId === "" ? null : settings.store.emojiId, emojiName: settings.store.emojiName === "" ? null : settings.store.emojiName, } : undefined, } } });

but its untested

bronze dove
amber basin
#

is emoji an id?

bronze dove
#

an object

amber basin
#

ah i see

#

{id:,
name:
}

#

discord > vrc works

#

vrc to discord!

#

thank youuuuuuu

bronze dove
#

np

opal portal
#

why not extnd message logger functionality to storage to sqlite database? or is it denied request?

dull magnet
#

because it is not desired

#

and if anything you would use indexeddb

hardy adder
#

i see the pinned thing for finding the patch for joining VC, but how would i find something like reacting to a DM?

oak sundial
#

whats the end goal

hardy adder
#

the goal is to have like a visual timer that resets when i get a dm

#

not self-botting

unkempt hemlock
#

@dull magnet shouldn't the ThemeAttributes plugin be enabled by default (or even be required)? I don't see any possible downsides for having it enabled

because some themes and CSS snipets require it I think it would be good to be enabled by default or transformed into a required plugin

dull magnet
#

no

hushed loom
hardy adder
#

flux event?

hushed loom
#

discords event system

hardy adder
#

oh cool

hushed loom
#

theres prob some event for a direct message

hardy adder
#

so would that go in le event() member?

cedar olive
#

from what I understood you want to have a global timer which would be rendered as a visual component somewhere

#

and you want that timer to reset every time you receive a message from a specific person

#

correct?

hardy adder
#

yea pretty much

hushed loom
hardy adder
#

i see, it's just defined as any

hushed loom
#

example:

hardy adder
#

yay

cedar olive
#

ngl there are multiple ways you could do this

#

hold on let me think

#

okay

#

simplest way would be to:

have a top level variable to store last time you received a message from them
listen for MESSAGE_CREATE using the flux event listeners as pointed above, if it's the right person and channel update the time
make a react component with a forceUpdater, and after updating the time variable, call the force update
and then just make your component calculate the time elapsed using the last time, and write a patch to render it where you want

hardy adder
#

yeh, somethin like that

#

gotta remember react and learn how to patch

cedar olive
#

you could also make it use a custom store, which is the right way, but that would be more complicated and probably overkill for this simple case

hardy adder
#

wat is an optimistic

cedar olive
#

nothing to worry about

#

(I dont actually know)

hardy adder
#

hm the types included don't seem to match djs types

#

how would i get a channel from a message?

cedar olive
#

inspect it

#

Vencord.Webpack.Common.FluxDispatcher.subscribe("MESSAGE_CREATE", e => console.log(e))

cedar olive
#

discord client has it's own internal structures

hardy adder
#

ok the full event had a guild id i can nullcheck to determine if it's a dm, but now i need to differentiate between 1 on 1 dms and group chats

cedar olive
#

harcode the channel id check

hardy adder
#

:(

#

sad face

cedar olive
#

oh

#

I mean

#

it will only be for a specific person right

hardy adder
#

i could but surely i can get a channel object somehow

cedar olive
#

but why do you need it?

hardy adder
#

to check if it's a gc or dm

#

unless there's some other way to determine that

cedar olive
#

then how are you gonna differentiate the dm user after?

#

as in, know which person that channel belongs to

hardy adder
#

user id

#

is user id the same as dm channel id?

cedar olive
#

nop

hardy adder
#

yea so i just don't really wanna hardcode two things for one function

#

bcuz that's LAME

cedar olive
hardy adder
cedar olive
#

store that in your plugin object to not have to get everytime

#

(the dm channel id)

#

and then you only have to hardcode the user id

#

compare message.author.id and message.channelId

dull magnet
#

and use useStateFromStores

hardy adder
#

oh no

cedar olive
#

I dont think that's needed

#

what they want is small and simple

dull magnet
#

it's really not complicated

cedar olive
#

and for that you gotta use proxyLazy and other stuff to actually get a flux store to work

hardy adder
#

wait how do i get my stuff into the flux functions

cedar olive
#

(sure it's the right way, but it's not that much cleaner either)

#

need more boilerplate for the custom store

dull magnet
#
const MyStore = proxyLazy(() => {
  let whatever = whatever;
  class WhateverStore extends Flux.Store {
      getWhatever() {
          return whatever;
      }
  }
  return new WhateverStore(FluxDispatcher, {
      SOME_EVENT(data) {
          whatever = whateverNewThing;
      }
  });
});

function Component() {
    const whatever = useStateFromStores([MyStore], () => MyStore.getWhatever());
}
#

it's pretty clean

hardy adder
proud parrotBOT
cedar olive
#

compared to

let time;
let forceUpdate;

function Component() {
  forceUpdate = useForceUpdater();  

  return <div>{time}</div>
}

export default definePlugin({
  ...
  flux: {
     MESSAGE_CREATE() {
        if (...) return;
        
        time = something;
        forceUpdate?.();
      }
  }
})
#

really not much difference

#

but yes extending FluxStore is the correct way

dull magnet
#

maintainability also plays a huge role

#

the forceUpdate approach quickly becomes a mess when you wanna add more data / logic

hardy adder
#

im not trying to make an official plugin, just a toy for personal use

cedar olive
#

they arent gonna add much probably

#

that's why I suggested the simpler way which had less things to learn about

#

useStateFromStores, FluxStore, proxyLazy...

#

but anyways they can choose whay they feel more confortable with now

hardy adder
#

yeh

#

ohh right react is coming back to me, you have to tell it when you wanna update stuff lol

cedar olive
#

which approach are you using

#

that's the point of useForceUpdater and useStateFromStores

hardy adder
#

not doing any ui yet

#

what are all the #{intl:: things?

cedar olive
#

macro-ish syntax

#

since discord now hashes the keys of localization messages, that macro lets you write finds and matches using the non hash key and later it gets turned into the hashed version

hardy adder
#

oki so what's the difference between find and match?

#

what if i just want to like... append to the end of the find

cedar olive
#

find -> unique string that only the module you want to patch has
match -> the regex to match the code to modify
replace -> the replacement code

hardy adder
#

probably js noob question but how wide is a "module"?

#

and does that mean i can just use the same thing in find and match?

hushed loom
hardy adder
#

ohh wait do you just mean the big long js file that its in?

hushed loom
#

that big file web-somehash.js has a bunch of modules

hardy adder
#

oh

hushed loom
#

thses are all modules, with the numbers being a module id

hardy adder
#

oh, huh

#

i see

#

do the silly one letter variable names stay the same between updates?

hushed loom
#

yes and no

#

but you should not use them in your patches

#

you can use \i to match any javascript identifier

#

and if you're having an issue with a find or match, let me know and i can try and help

hardy adder
#

how do you like

#

put the \i into your replace

hushed loom
#

use a capturing group

hardy adder
#

aw man

hushed loom
#

the replacement is just what is passed to String.replace

tropic ice
#

\i isn't real regex and is just something that gets replaced with some real regex internally
don't remember what exactly it gets replaced with though

hushed loom
tropic ice
#

ah nice

hardy adder
#

how do i capture a variable outside the scope of my match? i could just put o in but ofc icky

#

or i could use a massive match

#

is there a better way?

hushed loom
#

send module

hardy adder
#

like the whole thing or

hushed loom
#

id

#

the number

hardy adder
#

oh lemme find it

hushed loom
#

(normally 6 digits)

#

if you have a match, run wpexs(<your find>) and double click the result

hardy adder
#

838440

hushed loom
#

what do you want patch here

hardy adder
#

changing the slowmode condition null != v.getGuildId() && T && l.Z.getSlowmodeCooldownGuess(v.id) > 0 to append my function after it

#

so like null != v.getGuildId() && T && l.Z.getSlowmodeCooldownGuess(v.id) > 0 || myFunction()

hushed loom
#

one moment

hardy adder
#

wanna get v (channel) into my function

#

oh wait im stupid lmao

#

v is right there

#

tunnel visioned

#

still useful info tho so if there's a better solution to that general problem that would be cool

hushed loom
#
{
    find: "\"Message Too Long Alert\"",
    replacement: {
        match: /({if\()(null!=(\i).{0,100}>0)/,
        replace: "$1($2)||$self.myFunc($3)"
    }
}
#

@hardy adder that should work

hardy adder
#

woh

#

many capture

cedar olive
hardy adder
#

hm interesting

#

regex is wild

cedar olive
#

I found that trick while working with vencord lol

#

extremely useful for capturing stuff without matching and does not impact performance

amber basin
bronze dove
#

ah, you can require it your code so that it is loaded

cedar olive
#

I remade that function in the past

#

to avoid having to load it

#

@amber basin

amber basin
#

ah ty!!

#

is that exported anywhere or do i need to include it in my plugin

cedar olive
#

copy paste into your plugin

amber basin
#

oki

cedar olive
#

also remember to add UserSettingsAPI dependency now

amber basin
#

oki

#

thanks!! had to make a few changes to allow passing undefined as text and null as expiresAt but it works!

cedar olive
#

of course!

#

that implementation was a 1x1 copy from the discord one, but you can always change it to how you want

burnt ermine
#

Hey hey! Im curious about the best way of retrieving the users display name if we are in a DM. Im not currently sure how to do that so i just did getCurrentChannel()?.rawRecipients[0].username for their name and
parsed MultiAccountStore from localstorage to get mine. I am fairly new to this so im curious if theres any api for getting the recipients display name as well as my own.

hushed loom
#

Inspect it in console and the prop you want should be there

burnt ermine
#

im using generic typings for them. Are the username props viable? Does discord randomize class names like other sites orrr

hushed loom
#

On mobile rn

#

Send code and I'll take a look at in a voty

#

Bit*

burnt ermine
#

Voty kek

#

Ahh i feel like pulling from the html isnt the best practice

#

Is there a func that takes a user ID and returns their object?

hushed loom
#

Use patches

burnt ermine
#

When i finish a plugin, how can i share it with people so they can add it to vencord?

hushed loom
vocal ether
#

@hushed loom As I mentioned previously, I need the function that sends the package containing the video and audio of a transmission, is there any documentation about Discord modules or something like that?

flint bronze
#

It doesn't immediately send it though

burnt ermine
hushed loom
vocal ether
#

I'll explain the idea behind the plugin and where I need help. I'm creating a plugin that amplifies the sound of the payloads sent to the Discord server during a stream. The reason for this is a bug that I and some other people are facing. When streaming, the sound becomes extremely low, and we have to increase all the computer's audio levels just so people can hear the minimum. The solution is simple to implement; my main problem right now is that this is my first time interacting with Discord. I don't understand how the modules work or if there is any unofficial documentation created by the community for these modules. Regardless of whether such documentation exists, my first approach was to backtrace the logs sent when the stream starts. I found several error handlers and event listeners but not what I was looking for: the function that captures these packets or the function that sends them to Discord's server. Either of these would allow me to create a hook to amplify the payload. Where I need help is understanding the best way to find these functions or if someone has already found them and can tell me where they are or how to locate them

humble tulip
#

I'm sure if you've got this far then you've looked into this already but just in case, you've turned attenuation off in voice settings, right?

#

Also I could be wrong but I think the audio streaming is done in native code

hushed loom
#

it would be eaiser to do this via another program

vocal ether
hushed loom
#

@vocal ether are you on discord desktop, vesktop or browser

vocal ether
hushed loom
#

vesktop has a feature where it has its own implimentation of screensharing

#

via a native module

#

so look at what it patches

vocal ether
#

Ok, this is extremely helpful

#

One question, what is the best way to locate functions?

hushed loom
#

enable react dev tools

#

then use the view source button in the top left of selected components in the components page

iron epoch
#

how can I get the last two messages from a channel with the channel id? like that preview channel plugin

hushed loom
#

not sure how that will interact with message logger

#

if you care about that

iron epoch
flint bronze
hushed loom
flint bronze
#

Isn't it almost the same thing as VolumeBooster

thick sparrow
burnt ermine
#

Id love to upload mine but i just cant get an icon for it lmao

#

the chatbar icon i found wont work

#

heckin pizza slice

gloomy terrace
#

works well with The Fridgeā„¢ļø

burnt ermine
#

haha

#

is there any better way to test plugins? Im having to run pnpm build and then inject to test it

#

maybe a "live update" thing (no clue if thats a thing)

hushed loom
burnt ermine
#

yes

hushed loom
#

send code

burnt ermine
#

sure

#
const ChatBarIcon: ChatBarButton = ({ isMainChat }) => {
    if (!isMainChat) return null;

    return (
        <ChatBarButton
            tooltip="Use QuickSnip"
            onClick={() => {
                const key = openModal(props => (
                    <SnippetModal
                        rootProps={props}
                        close={() => closeModal(key)}
                    />
                ));
            }}
            buttonProps={{ "aria-haspopup": "dialog" }}
        >
            <svg
                fill="#000000"
                version="1.1"
                id="quickSnip"
                width="24"
                height="24"
                viewBox="0 0 24 24"
                xmlns="http://www.w3.org/2000/svg"
            >
                <g
                    id="g3"
                    fill="#aeaeae"
                    fillOpacity="1"
                    transform="translate(-0.0005,-29.198)"
                >
                    <g id="g2" fill="#aeaeae" fillOpacity="1">
                        <path
                            d="M 28.715,215.714 C 12.883,215.714 0,202.833 0,187.005 V 57.91 C 0,42.076 12.883,29.198 28.715,29.198 h 220.147 c 15.829,0 28.715,12.877 28.715,28.712 V 76.588 H 88.15 c -22.614,0 -41.006,18.399 -41.006,41.016 v 98.11 z"
                            id="path1"
                            fill="#aeaeae"
                            fillOpacity="1"
                        />
                        <path
                            d="m 337.013,246.692 c 0,15.834 -12.874,28.715 -28.703,28.715 h -14.705 c -3.394,0 -6.149,2.75 -6.149,6.148 v 26.26 l -25.58,-30.229 c -1.171,-1.387 -2.889,-2.18 -4.689,-2.18 H 88.15 c -15.826,0 -28.708,-12.881 -28.708,-28.715 v -18.682 -12.297 -98.11 c 0,-15.829 12.883,-28.718 28.708,-28.718 h 189.427 12.298 18.435 c 15.829,0 28.703,12.89 28.703,28.718 z"
                            id="path2"
                            fill="#aeaeae"
                            fillOpacity="1"
                        />
                    </g>
                </g>
            </svg>
        </ChatBarButton>
    );
};
#

thats the icon

#

do you want the entire plugin code?

humble tulip
#

Just build and reload

burnt ermine
#

oh nice

#

i had no clue

hushed loom
burnt ermine
#

ty prayge

humble tulip
#

You can also use pnpm watch which will automatically rebuild whenever you make a change but you'll still need to reload discord to apply

burnt ermine
#

hmmm doing ctrl shift r doesnt reload my discord

#

bc its just ctrl r

humble tulip
#

It's just ctrl + r

burnt ermine
#

im stupid lol

humble tulip
#

Same tbf

burnt ermine
#

Its been one of those days so far kek

burnt ermine
hushed loom
burnt ermine
humble tulip
#

I think you just need to put viewBox="0 0 337.01199 278.617" back to how it was

hushed loom
#

yea

#

view box doesnt change how its scaled

#

afaik it just says what the size to reference when scaling is

#

yeah

#

@burnt ermine also change all mentions of #aeaeae to currentColor

#

that way it has the color based off the users themes

burnt ermine
#

ohhh bet ok

#

whatre the classes for primary color and accent color i need to update my colors and stylings

#

is there a sheet/convention for it?

hushed loom
burnt ermine
#

no not for the icon for the ui in my plugin

hushed loom
#

but if you want to use them elsewhere

#

and just use the css inspector in devtools

burnt ermine
#

šŸ‘

burnt ermine
hushed loom
#

but change view box to viewBox="0 0 337.01199 278.617"

#

for the svg tag

burnt ermine
#

bet ty

carmine basin
#

heyy, i have a small question, i am starting to try to dev some vencord plugins and i just wanna beggin with some basics things, i opened the "noF1" plugin and the plugin is simple to understand BUT where i have to find this on discord:

{
    find: ',"f1"],comboKeysBindGlobal:',
    replacement: {
        match: ',"f1"],comboKeysBindGlobal:',
        replace: "],comboKeysBindGlobal:",
    },
},
chrome elbow
#

in devtools
ctrl shift i, ctrl shirt f, type something, enter

burnt ermine
#

im just about ready to submit my plugin as a pr. Any thoughts on the styling? (I've never touched frontend let alone react in my life lmao)

carmine basin
#

I wanna try something, I have 6 accounts and can only switch to 5 (max), I tried something like that:

{
    find: "maxNumAccounts: g.$H",
    replacement: {
        match: "maxNumAccounts: g.$H",
        replace: "maxNumAccounts: 6"
    }
}
#

I don't wanna the answer or something like that, i wanna learn how to do this type of things

#

for that, I searched "you can only add" and find [2, "maxNumAccounts"] so i searched maxNumAccounts and found the match, I don't thing that's correct 😦

burnt ermine
#

so what exactly are you trying to do?

#

i didnt read up

carmine basin
#

i wanna add a space for one account

#

in the "switch accounts"

burnt ermine
#

so alt manager?

carmine basin
#

yeaa

humble tulip
#

The code you see in dev tools is formatted but in the actual code basically all unnecessary whitespace is removed, so things like "maxNumAccounts: g.$H" are actually "maxNumAccounts:g.$H"

carmine basin
#

oh so if there's space in dev tools i have to remove it ?

humble tulip
#

Yeah

#

Newlines too

#

Also for the variables g.$H you should use the regex \i.\i to match as they'll likely change in updates

carmine basin
# carmine basin

and if there's that, for the find i put switch-accounts-modal, the match i can put let i = 5 ?

#

or I can't touched any let ?

humble tulip
#

Yeah but you'd wanna do let \i=5

#

So remove the spaces and use the regex special char for the variable in case it changes

#

But the space between let and i is obviously necessary for the let keyword

carmine basin
#

ok tysm

burnt ermine
#

What does pring a plugin look like? Is there any specific way i should be doing this or just pr in the plugin in its folder?

humble tulip
#

Check the first pin in this channel

#

You'll wanna put the plugin in the main plugins folder in the new fork

#

If you currently have it in userplugins

carmine basin
#

hey, I am so sorry that i am bad with that but I have another question, It didn't work so I don't think the find is correct. How can I find the find and match for my case (I don't want the code/answer, i wanna learn so sorry 🄲)

humble tulip
#

Can you show the patch you used? switch-accounts-modal should be a good find

carmine basin
#

maybe i have to take more things ?

#

I don't know if the let i = 5 is really for the Account Switcher

#

I found the number 5 just above and for me it was obvious that it was linked to the switcher

tropic ice
humble tulip
#

That i is the g.$H you referenced in your other patch so it is linked but there may be more to it than just that int
Also your match should be a regex string, this only works by coincidence because the variable is actually i

#

So you'd wanna do like (\i) and in your replace you can use the group you matched there in your replacement string like $1

carmine basin
#

if i understand it

humble tulip
#

No like

match: "let (\i)=5",
replace: "let $1=6"``` like if you were just using a regular regex replace
carmine basin
#

aaaok

carmine basin
#

and I noticed the text was related to this

#

so I was wondering if I should change that rather than the let i = 5

#

but maybe the let i is related to g.$H

humble tulip
humble tulip
carmine basin
#

yea

humble tulip
#

Also dumb question but did you enable your plugin?

carmine basin
#

yea xD

#

in the userplugin

#

i found it

#

tysm guys

humble tulip
#

Congrats thumb

burnt ermine
#

So i just submitted a PR for my plugin that i made, do i need to do anything else or just leave it there? I see quite a few PRs and i have no clue if it'll get lost lol

rocky lynx
#

Just wait, it will get looked at eventually.

tropic ice
#

Whoa I just realized pinned messages don't have any right click

flint bronze
tropic ice
flint bronze
#

i am too lazy to do so

tropic ice
steady knot
#

seY

tropic ice
humble tulip
carmine basin
#

heyy ! I am working on a "Spoofer" plugin like that:

#

i tried something just for testing to emulate the ps5 client and it worked:

#
find: "os:e,browser:\"Discord Client\"",
match: "os:e,browser:\"Discord Client\"",
replace: "os:\"Windows\",browser:\"Discord Embedded\""
#

but now i wanna sync with the settings, i did an object with all the platforms:

#

so if i do infos[settings.store.plateforme] I'm supposed to get:

{ os: "Windows", browser: "Discord Embedded" }
#

but didn't get it and connected as the normal Client 😦

burnt ermine
#

have you tried just console logging for debug the value of infos[settings.store.plateforme]

carmine basin
burnt ermine
#

oh wait

#

i might be stupid but youre using the entire object settings.store.platforme to get infos

carmine basin
#

yea

#

it's not correct ? 😦

burnt ermine
#

add these lines somewhere to log stuff

console.log(JSON.stringify(infos))
console.log(JSON.stringify(settings.store.platforme))
carmine basin
#

i have to place it where ?

#

in the function getData ?

#

or anywhere ?

#

i am trying outside every objects

burnt ermine
#

uhhh try and place it there before the return block yes

#

that should log it

carmine basin
#

okk

carmine basin
burnt ermine
#

oh, just do console.log(value)

carmine basin
#

nah

#

when i do ctrl shift i

#

how to see them

burnt ermine
#

uhh look for console tab

carmine basin
burnt ermine
#

hmmm im not sure

carmine basin
#

my real problem is "how can i see console"

#

bcs if I can see it, I can check it by myself

#

just putting some console.log until it works

burnt ermine
#

Sure yeah i do have to go so im not sure

#

just know you probably are getting this error here


const infos = {
    foo: { name: "foo", value: "foovalue" },
    bar: { name: "bar", value: "bar1" }
}

const settings = {
    store: {
        platforme: [
            { label: "windows", value: "windows", default: true },
            { label: "Linux", value: "linux" },
        ]
    }
}

console.log(infos[settings.store.platforme])
Type '({ label: string; value: string; default: boolean; } | { label: string; value: string; default?: undefined; })[]' cannot be used as an index type.

you cant get a value of infos with an array

carmine basin
#

i have to restart the plugin

#

i will try it by myself, tysm

burnt ermine
#

alright

#

good luck

carmine basin
#

ty

humble tulip
#

Would this cause any issues with Discord identifying the wrong platform for the features that are available in the client or is that just entirely seperate?

burnt ermine
#

What makes discord select you to have a guild im curious

#

is it batch rollouts?

velvet basin
#

[LilC]: quick question. pnmp inject, is there a command line way to to auto select repair and the instillation path? Looking to speed up deployment for testing.

burnt ermine
burnt ermine
#

of course! Helped me a crap ton when i first learned it haha

velvet basin
#

you litterly saved me days šŸ™‚

velvet basin
#

ok, next silly question. I have my plugin working and wish to test on another machine. Do I need everything in the dist folder or just the installer?

velvet basin
#

ah ha! batch file for the win šŸ™‚

hushed loom
#

Then clone and use that repo

kindred perch
#

Why does this re-render x3?

openModal(props => {
  { console.log("Executed"); }
})

I have an async request in the modal (when a button is clicked) and it causes a 429 because of the 3 re-renders at the same time

cedar olive
#

it's normal for react components to re-render a lot of times

#

if you don't memo it, a simple on mouse hover will cause a re-render

#

but either way, memoing is not the solution

#

if you want code to execute only when the component is rendered for the first time, and not everytime it re-renders, use useEffect with an empty dependency list

stone lintel
hushed loom
#

see more in src/plugins/petpet/index.ts

stone lintel
kindred perch
cedar olive
#

you can have another

kindred perch
#

wdym?

hushed loom
#

send code

kindred perch
#
    useEffect(() => {
        async function getMembersWithRole(guildId, roleId) {
            setLoading(true);
            try {
                const { body } = await RestAPI.get({
                    url: Constants.Endpoints.GUILD_ROLE_MEMBER_IDS(guildId, roleId),
                });
                // const members = await GuildUtils.requestMembersById(guildId, body, !1);
                setMembers(body);
                console.log(body);
            } catch (error) {
                console.error("Error fetching members:", error);
            } finally {
                setLoading(false);
            }
        }
        getMembersWithRole(guildId, roleId);
    }, [roleId]);
cedar olive
#
    useEffect(() => {
        async function getMembersWithRole(guildId, roleId) {
            setLoading(true);
            try {
                const { body } = await RestAPI.get({
                    url: Constants.Endpoints.GUILD_ROLE_MEMBER_IDS(guildId, roleId),
                });
                // const members = await GuildUtils.requestMembersById(guildId, body, !1);
                setMembers(body);
                console.log(body);
            } catch (error) {
                console.error("Error fetching members:", error);
            } finally {
                setLoading(false);
            }
        }
        getMembersWithRole(guildId, roleId);
    }, [roleId]);

    useEffect(() => {
        console.log("boop");
    }, []);
#

you can have another blobwob

kindred perch
#

But i mean the console.log() was just for debugging, the code that shouldn't repeat is the one in the useEffect

cedar olive
#

what is the issue then

kindred perch
#

for some reason, even if roleId doesnt seem to change, it will still rerender it, and do the request 3x

#

resulting in a 429

hushed loom
kindred perch
#

yes, so i want it to not rerender to not ratelimit

hushed loom
#

use GuildMemberStore

#

90% of the time you dont need to use RestAPI

kindred perch
hushed loom
#

if that isnt what you need, what do you need

kindred perch
amber basin
#

enable consoleshortcuts

#

adds alot of globals

kindred perch
# hushed loom

doesn't this just get roles from members online for big servers?
I need to be able to get every member from each role(if it has less than 100 members) which this request allows

kindred perch
stone lintel
hushed loom
kindred perch
hushed loom
#

@kindred perch it seems to work for offline users

not sure if you can do much more without having permissions in said server

kindred perch
kindred perch
flint bronze
#

?remindme 12h fix

fathom pivotBOT
#

Alright @flint bronze, in 12 hours: fix

fathom pivotBOT
#

@flint bronze, <t:1734612960:R>: fix

kindred perch
#

How do i get the name of a user?

#

i have a list of members from GuildMemberStore.getMembers(), but it only includes a nick, and no names

flint bronze
#

fall back to UserStore

#

look at how TypingIndicator does it

#

you can probably keep using the nick property directly

kindred perch
flint bronze
#

yes..?

kindred perch
#

thanks

kindred perch
#

How can i make it so the modal appears like clicking @mentions/user name on messages?
heres my code so far

function openServerProfile(props: ModalProps, userId: string, guildId: string) {
    openModal(props =>
        <div className={styles.accountProfilePopoutWrapper}>
            <UserProfile {...props} userId={userId} guildId={guildId} />
        </div>
    );
}
cedar olive
#

use a Popup instead of modal

errant sandal
#

@hoary pilot @median flare tysm

median flare
#

np

errant sandal
#

i come across with another problem
discord is open with devcompanion on but that appears

errant sandal
hushed loom
errant sandal
#

wh

#

i dont see one

hushed loom
#

wait no

#

vp toolnox

shrewd tundraBOT
hushed loom
#

vp toolbox

#

vp toolbox

shrewd tundraBOT
errant sandal
#

ohh its connected

#

tysm!!

hushed loom
#

tbh its pretty stupid

#

it should be enabled if the companion is

errant sandal
#

indeed

errant sandal
cedar olive
#

chatgpt knows nothing about vencord/discord modification

errant sandal
#

ggs..

stiff dragon
#

does anyone know how to make a context menu on emotes

#

like how Clone Emoji shows up on Emotes and Stickers only

proud parrotBOT
flint bronze
#

should I make mod view tweaks plugin already

#

actually why not just depreciate that code in a different way by making it so you can open mod view for non-members

flint bronze
#

does anyone know how to make a user profile popout

#

I MISS THIS SO MUCH I SHOULD DO IT ALL AGAIN

humble tulip
#

Nuckyz would've had to have done that for the member profile in account panel plugin right?

#

I can't remember what it's called lol

humble tulip
flint bronze
#

Ohhhhh yes

#

guh

#

WHAT IS THAT

#

if clan applications can do it so can mod view

#

(albeit, it pops open a modal)

cedar olive
#

and copy how discord does it

#

(or change the component to the guild profile if u need too)

flint bronze
#

i did find that

cedar olive
#

nice

cedar olive
hushed loom
#

does anyone know if this is the proper way to use props in an error boundary fallback

#
{UserMentionComponent: ErrorBoundary.wrap((props: UserMentionComponentProps) => {
        return <UserMentionComponent
            // This seems to be constant
            className="mention"
            userId={props.id}
            channelId={props.channelId}
        />;
    }, {
        fallback: props => {
            let username: string | null = null;
            try {
                username = UserStore.getUser((props as any)?.children?.props?.id)?.username;
                if (username == null) {
                    throw Error("Error getting fallback username");
                }
            } catch (e) {
                console.error(e);
            }
            username ||= "Unknown User";
            return <span style={{
                color: "red",
            }}>@{username}</span>;
        }
    }),}```
flint bronze
#

it should work?

hushed loom
#

but is this the correct way to do it

flint bronze
#

as far as I can tell, yes

winter tartan
#

is there any way to test out a plugin before submitting it?

hoary pilot
#

tells you everything on how to setup a vencord clone ready for development

winter tartan
eternal goblet
#

what is the purpose of the "find" in patches?

tropic ice
#

it finds the module that the regex will be used on

eternal goblet
#

like the specific file?

hushed loom
#

discords code is split into modules

#

each number here coresponds to a module

eternal goblet
#

yea

hushed loom
#

the find is a unique string

#

that matches the module to patch

#

it can be regex, but 99% of the time

#

it can be done with a string

eternal goblet
#

ah that makes sense

#

i figured it out

#

it does something !!

#

how do i play with state and make calls to the discord api ?

#

doesnt discord have some kind of built in state management

eternal goblet
rocky lynx
#

i would look around and see if there is already a function in discords code that you can use for what you want to do

eternal goblet
#

there isnt i dotn think

#

the specific api call im trying to make is only supported on mobile

rocky lynx
#

what are you trying to do?

eternal goblet
#

it isnt implement on desktop at all

eternal goblet
#

using the same api that the mobile search uses

#

i did proxied my phone and took a look at the api calls

#

should be too hard to implement once i get a hang of how plugins are written

eternal goblet
hushed loom
#

if you need to make an api call

#

use the RestAPI class

eternal goblet
#

got it

#

there isnt a builtin api call on desktop rn

hushed loom
#

but most of the time you can use discords built-in stores and functions

hushed loom
eternal goblet
hushed loom
#

oh

#

yea

#

you would need restapi for that

eternal goblet
#

is there already a plugin for that?

hushed loom
#

you also might want to take a look at https://discord.sex

Discord Userdoccers

You’ve found the Unofficial Discord User API Documentation! These pages are dedicated to showing you all the ways that you can use Discord to make cool stuff. It is not an official source of informati...

eternal goblet
#

already checked

#

its not documented yet

hushed loom
#

alr

#

glhf

eternal goblet
#

ty

#

how do i manage state

hushed loom
eternal goblet
#

data fetching and also tracking a textinput

#

there is a onChange prop on TextInput but idk where i would store it lmao

hushed loom
eternal goblet
#

can i store variables inside the definePlugin and access them via this or soemthing

hushed loom
#

also DataStore

#

for persistant storage

eternal goblet
#

the state probably wont need to persist

eternal goblet
hushed loom
eternal goblet
#

got it

hushed loom
# eternal goblet got it

you should also know that if anything at the top-level of your plugin errors, all of vencord wont load

eternal goblet
#

wtf

#

like will it crash?

hushed loom
#

vencord will

#

but discord will still run

eternal goblet
#

even if i use ErrorBoundary?

hushed loom
#

what

#

errorboundary is react

eternal goblet
#

yes

hushed loom
#

i think you misunderstood top level

eternal goblet
#

what did u mean by top level?

hushed loom
eternal goblet
#

oh

#

so like things erroring just from importing the file

#

that makes sense

eternal goblet
#

do i have to write all the styles directly in a style prop or is there a library like tailwind or styled components or something

#

or atleast put the styles in a seperate css file

eternal goblet
#

oh

#

that makes life easier

#

scss support ?

flint bronze
#

nop but stock css is actually tolerable now

eternal goblet
#

fair enough

flint bronze
#

you will enjoy :has

eternal goblet
#

i need some kind of state management to trigger rerenders

#

bru

#

i could just do it in 1 big component

#

what is flux?

hushed loom
eternal goblet
#

how does that work? can i make hooks with it or something

#

any docs on that

#

?

hushed loom
eternal goblet
#

ah

#

ty

#

big help

#

we sleep now cya o7

meager ferry
#

is the entire documentation 4 pages

#

where util docs

formal charm
#

The documentation is unfortunately heavily unfinished and the only way to really learn is by looking at existing plugin code

meager ferry
#

mhm ty

#

i think i alr cooked up something

#

first discord crash

meager ferry
#

yeah uh

#

how do i use vencord to send a message in current channel

#

ok nvm found it, theres a func for that under webpack

#

oik uhm

#

why is it sending empty messages

#

AHH

hushed loom
meager ferry
#

I'll publish it tomorrow :3

#

just open pr and ticket right

hushed loom
#

idfk what a ticket is

meager ferry
#

fully automated ai chatbot

#

just fixing up some twerps and itll be done

#

it automagically replies to messages in ur current active tab if enabled

#

since u can set the default prompt its good for support staff and common problems ig but more or less jst a fun project i could see people using

vast karma
#

So a selfbot?

hushed loom
meager ferry
meager ferry
#

jst a random fun project

vast karma
#

In what way is an autoresponder not a selfbot

meager ferry
#

:3

hoary pilot
# meager ferry well yeah but its cool

-# #rules
### Rule 11

Do not ask for, talk about, or use the following plugins:

  • Stereo Mic
  • FakeDeafen or other similar creepy plugins
  • Animated Status
  • Message Mass Delete
  • Selfbots, Spammers, MassMentions, NitroSnipers or similar
meager ferry
#

noted with tanks

#

but im ngl custom clients are already breaking tos so

hoary pilot
#

aaanyway

vast karma
#

So? Breaking vencord rules in vencord chat is still not allowed

meager ferry
#

anyway thx imma go have fun w/ my code editor now

#

cya

hoary pilot
#

anyone have any idea of how this code is an invalid hook call?

OutputVolumeComponent() {
        const [outputVolume, setOutputVolume] = useState(findByProps("getOutputVolume").getOutputVolume());
        return (
            <div style={{ marginTop: "10px" }}>
                <Slider maxValue={200} minValue={0} initialValue={outputVolume} />
            </div>
        );
    }
vast karma
#

As long as OutputVolueComponent is indeed used as a component that looks fine

#

Though you should move that findByProps to a findByPropsLazy on the top scope

vast karma
#

If you call OutputVolumeComponent as a function you're doing it wrong

hushed loom
#

but do what @vast karma said and move the findByProps to top-level

hoary pilot
hushed loom
#

show code

hoary pilot
vast karma
#

Yep, knew it

#

You're indeed calling it as a function

hoary pilot
#

guhh

how do i not call it as a function

#

isn't this the only way to inject a component?

vast karma
#

renderOutputVolumeComponent() { return <OutputVolumeComponent />; }

hoary pilot
#

react moment

vast karma
#

Or foo.jsx($self.OutputVolumeComponent, {})

#

Or however the syntax goes

dull magnet
hoary pilot
meager ferry
#

oh btw is there a func to return slowmode time

rocky lynx
#

getSlowmodeCooldownGuess might be what you're looking for

hoary pilot
meager ferry
#

<3 ty

hoary pilot
#

does anyone have an idea of what can be used to make the Slider component (in @webpack/common) use a different max value in the tooltip

like this slider has it at 200 max

tropic ice
hoary pilot
#

they use the same component last i checked

cedar olive
#

maxValue prop I think

tropic ice
hoary pilot
cedar olive
#

inspect the props

hoary pilot
#

true

#

why didn't i think of that husk

#

turns out it was

onValueRender={v => `${v.toFixed(0)}%`}
burnt ermine
#

Whatre the chances a plugin i made a couple weeks ago gets accepted in?

burnt ermine
#

quickSnip

#

#3084

hushed loom
#

idk, no harm in trying

but personally id make it as an addition to message tags

#

oh

#

its already a pr

#

idk wait

#

i have some from a few months ago

burnt ermine
#

I can always update it, im def gonna add more message tags later

burnt ermine
burnt ermine
#

*i might be horribly wrong BLEH *

burnt ermine
#

ohhhh boy

#

thats quite a few

#

No worries if you cant get to mine i respect your time Heart

quick zephyr
#

how do I remove my settings for a specific plugin? im trying to make sure the default values work right. I removed it from settings.json and restarted but it still has my modified settings

#

ah I just had to fully shut discord down

flint bronze
#

fun fact

#

deletion doesn't work with the settings proxy

quick zephyr
#

can the get_ functions from stores error ever or do they just return nothing if nothing was found

cedar olive
#

nothing

quick zephyr
#

nice

muted terrace
#

i am making the most horrid plugin

quick zephyr
#

proud of you

muted terrace
#

idk if this will even work

quick zephyr
cedar olive
#

of course

quick zephyr
#

thankies

muted terrace
#

is there a way to load .wav files

#

i currently have it where i modified build.mjs to add load .wav via the file loader

#

but its not playing audio

muted terrace
#

nvm i saw how moyai did it

#

i guess its hosting off to github time

quick zephyr
#

anyone know what dictates if a replied to message shows the @ before the user's name cause it seems random to me

green vessel
#

You can turn pings off ^

quick zephyr
#

yeah just found out. thats crazy

quick zephyr
#

knew about disabling pings just didnt know it had a visual indicator

#

neat

green vessel
#

yup

rough light
#

Hiya! Does anyone know how to access the Quick Switcher query and modify the results? Thanks!

#

Also how do I make the React DevTools show up, I only get the normal DevTools

tropic ice
rough light
#

yeah

#

I enabled it

#

but it doesn't show up

#

like when I do Ctrl + Mayus + I it shows normal DevTools but not React DevTools

tropic ice
rough light
#

I did

amber basin
#

click the dropdown

#

then components

hushed loom
#

you can drag them to reorder them too

#

so you dont have to go into that tab every time

amber basin
#

oh you can??

#

niuce

rocky lynx
#

What is profiler for? Every time i click it it just breaks everything.

hushed loom
#

but afaik you need a devbuild of react

flint bronze
hushed loom
#

not even sure if that is possible

flint bronze
#

anything is possible with a bit of insanity

#

we will make discordos

vast karma
#

Iirc some of the react modules are duplicated

#

So keep that in mind when injecting it

#

Also make sure you don't break my Classify plugin

flint bronze
vast karma
#

Give proper names to (some) hashed classes

rough light
hushed loom
rough light
#

yep

#

thrice, just in case

hushed loom
winter tartan
#

are there any docs or an option where i could learn about vencord's webpack and involve in js snippet making?

winter tartan
hushed loom
winter tartan
#

how do i find them tho, discord's props and functions

hushed loom
#

you can find discords functions by just looking at the code

winter tartan
#

i know javascript

hushed loom
#

(discords code)