#🧩-plugin-development
1 messages · Page 16 of 1
i'll take a look into it later
because i will also be adding a character counter
instead of displaying how many characters are left, it would display how many characters have been used
hmm what is the name for when you click an image?
some tips: we have a built-in escape for matching minified variable names \i, they can change between builds and even have symbols/be more than one char, so it makes patches more reliable
same with the find
also small nitpick but the space after var will always be there so the ? isnt necessary ^^
thanks for the tips
{
find: ".CHARACTER_COUNT_OVER_LIMIT",
replacement: {
match: /var \i,\i=\i\.type,\i=\i\.textValue,\i=\i\.maxCharacterCount,\i=\i\.className/,
replace: "return null;$&"
}
},
made it a bit better
still should prob replace the es with \is but yee
also, u dont need to put the whole match in a capture group, you can just use $& to output the whole match
oh nice
human tersing
edited now
@amber condor do you intend on allowing large message edits too?
not doable
Why, what's blocking that?
by that i mean the edit will be the first 2k chars in the message then send a message with the remaining
Yea that should work
you are gonna end up sending a message with others in the way
so like
first part of message
if edits will not be supported they need to have the blocking modal on them still
i tried it with his plugin and it will just ignore the edit
with no feedback
https://github.com/mwittrien/BetterDiscordAddons/blob/2aa5956d7ed349bc407b66d95acbeba526328745/Plugins/SplitLargeMessages/SplitLargeMessages.plugin.js Can you translate a bd plugin manually or is that not possible?
its possible pierre has pretty much done it
second part
ahhhh I see
Lmfao
i was afraid of that but i forgot
I was gonna do that but I realised that doesn't really help us in any way, it's much better to just have the types directly in our mod
makes it easier to maintain
Sounds reasonable
you can monorepo it

that's what I plan to do with my mod
we just have them in src/webpack/common/types
monorepo it and autopublish to npm
my favourite method
me when the static method returns a trans
that should be in rust
q, does someone have a dash-to-space plugin or theme, too lazy to do myself
me
thanks
hey is there any tutorial to do a basic plugin for someone who is starting?
oh okey thanks
there are some docs on github but they arent the most useful or the most up to date
https://github.com/Vendicated/Vencord/blob/main/docs/2_PLUGINS.md
yeah probably best to look at other plugins
yeah i've read that but it isn't helping at all xD
i found a fix for the edit thing
of SplitLargeMessages
are function arguments e by default?
there are some exceptions
is it safe to assume so?
whats the need for it? do you just need to match or do you need to replace code with it
if you need to use it in replacement and you know for certain where it will be you could add a word capture group and use $1 to get it maybe theres better ways though
i need to read from it
you could try what i said
i will
i recently saw someone post something about lookbacks
is it possible to search for the most recent function \w+\((\w+)\) after the original match ?
// $1: argument name (currently "e")
// $2: the rest inbetween the argument name and my actual match
// $3: my actual match
match: /(?<=function \w+\()(\w)(.*)(\(0,\w\.jsx\))(?=(.(?!\3))+?canDM)/,
// paste my fancy custom button above the message field
replace: "$1$2$self.patchPopout($1),$3",
@amber condor
also you can use \i instead of \w to match minified vars
some custom feature for vencord?
yes
ah bruh
thats complicated 🥴
.*\Kfunction\s\w+\((\w+)\)(?=.*;if\((\w+\.length>\w+)\)({\w+&&null)) i somehow came up with this but its very inneficient
yea, didn't know there's \i till now
it doesnt even work
this is really bad
it will match the first function in the entire module then match up to the thing
the whole module is this function
Does someone know how to create a store with react states? I know how to create a store and do it like this.
const store = new Promise<IDBObjectStore>(res => DataStore.createStore(PluginInfo.PLUGIN_NAME, STORE_NAME)("readwrite", res));
But what's the best way to manage the states with that? Sorry if I'm missing something obvious but I only have experience with https://github.com/pmndrs/zustand and know that Discord uses flux store. Or do I need to create a context and manage all my states manually?
like lets say we have stringcookies1 cookies2 banana cookies3
and we first want to search for banana, then how do we get the most recently occured cookies\d before banana?
well the thing i sent basically is the solution to your problem, but i'm too dumb to explain it
try matching cookie first, then use negative lookahead and then match banana
do you want cookies2 or banana
i assume the former
what are u trying to do?
if so, then this is what you want cookies\d(?= banana) for that specific example
/banana(?<=cookies\d).+?banana/
cookies2
then this, i guess
I'm trying to store my plugin settings. But I don't use definePluginSettings because I need to display them somewhere else and differently. And I never used definePluginSettings so I don't even know how it really works.
looking for cookies with banana after it
yeah but there wont be just spaces, there will be a to of random characters
in reality it would be cookies1 {var t;} cookies2 {somethingsomething = ()} banana cookies3
this actually does not mutch anything for me
then you can swap it out for whatever you want
im doing it based on your example lol
regex is an awfully annoying system
im in a game rn
balls gaming
remenber guys, pee is stored in the balls
.*\K(cookies\d)(?=.*banana) this worksgreat but i assume it would be hella slow
"cookies1 cookies2 banana cookies3".match(/banana(?<=cookies(\d).+?banana)/)
first group will be 2
what kind of settings are u trying to store
lemme try a diff site ig
bruh why is there a diff in regex between languages 😭
because implementation detail
@hushed bloom uses regex but uses a rust implementation which doesnt have these lookaheads for example
Something like this
type Settings = {
width: number,
height: number,
fps: number,
codec: string,
resolutionEnabled: boolean,
fpsEnabled: boolean,
codecEnabled: boolean;
...
};
you can access and set settings from your plugin i believe
but i don't know if you can have custom settings that don't show in the plugin settings, if that's what you're trying to do
ah this is for ur plugin
you can just manually use settings
or use datastore
u dont need to make a store
just DataStore.get() and DataStore.set()
Hm I'm not sure if that's what I meant. But if I would set and get my settings like this and lets say I'm displaying them somewhere in a react component would they be rerendered if a setting changes?
no youd be responsible urself of keeping track
also ven when could i expect to know if the plugin i ported might get merged?
thanks i got it working
/;if\(\w+\.length>\w+\){\w+&&null(?<=function\s\w+\((\w+)\).+?;if\((\w+\.length>\w+)\)({\w+&&null))/
im doing that right now
match: /;if\(\i\.length>\i\){\i&&null(?<=function\s\i\((\i)\).+?;if\((\i\.length>\i)\)({\i&&null))/, :)
// match: /;if\((\i\.length>\i)\)({\i&&null)/, this was my original one
i remember trying to mod krunker.io by patching similar to how vencord does it
turns out it was possible a few months before i tried and it was how some hacks worked
but they improved their anticheat and i have no clue how they validate the game source
now i just gotta patch this out
That would be great :).
function useDataStore<T>(key: string): [T | undefined, (newValue: T) => Promise<void>, boolean];
function useDataStore<T>(key: string, defaultValue: T): [T, (newValue: T) => Promise<void>, boolean];
function useDataStore(key: string, defaultValue?: unknown) {
const [state, setState] = useState({
value: defaultValue,
loading: true
});
useEffect(() => {
let alive = true;
DataStore.get(key).then(v => alive && setState({
value: v ?? defaultValue,
loading: false
}));
return () => void (alive = false);
}, [key, defaultValue]);
return [
state.value,
async (newValue: unknown) => {
await DataStore.set(key, newValue);
setState({
value: newValue,
loading: false
});
},
state.loading
];
}
i hate keywordAlterts
usage ```ts
const [value, setValue, isLoading] = useDataStore<Settings>("YourPluginName-settings");
// might be undefined until loaded, if you supply a default value (2nd param), it won't be
value?.codecEnabled;
setValue({
codecEnabled: false,
...
})
Wow that's great and exactly what I needed! Thank you that helped a lot 🙂
i havent tested it btw
Looks good to me I'm gonna test it now
Can't u just use CSS to display: none it
yes but i actually want to replace the number instead
so it can show how many characters are inside the message
Oh I see
For the color you probs dont want that to be red, you can maybe use CSS with !important
i actually wanted to keep it red tbh
it shows you when you if the message is gonna be split
id recommend a different color like blue or something
red implies its not going to send
i think the red is from discord
hmmm
well i'll see what i can do
because it still has to be red when its and edit message
can I change the flex-flow of the child of a column flex-flow?
i guess it works
what do you guys think?
the green line is what i've changed during patching
originally it was just children:I
e is reused but n and o still refer to the variables at the top
if you really want to check, you could throw the entire function body into vscode, reformat it, and rename the variables using F2
then you can see which variables map to what
@amber condor
i know
but theres a chance the characters will collide right?
because function(...) arent always function(e)

so in some case it might be function(n)
that's why you use capture groups in your regex
then you can capture the identifier and use it later
yeah i know
rolecoloreverywhere makes extensive use of this
you sure?
yes
because if that second e was an n you've just broken the functionality of the app
they're two distinctly different values
so the build tool guarantees that it wont overwrite variable names if they have meaning
not if the e is replaced everywhere with n (which might happen when discord "smallifies" their code right?)
wha?
the minification step is done by the build tool
so its guaranteed that the variable names wont clash like that
the only reason why its reusing e here is beacuse e is not used anywhere else in that function
and you shouldnt need to either, its props are extracted already at the top to separate variables
what i meant is: is there a chance discord will ship their code with these two highlighted names being the same? because the variables in the green line are added by my patch, not discord itself
before my patch, only I was in the function
okay, odds are your patch will remain working
then iguess we just gotta live with that
i severely doubt swc will decide to start using n or o
but even then
as long as your patch is written correctly
it should be resilient against it
match: /;if\(\i\.length>\i\){\i&&null(?<=function\s\i\((\i)\).+?;if\((\i\.length>\i)\)({\i&&null))/,
replace: ";if(($2)&&($1.type.analyticsName!=\"normal\"))$3"
wait wrong one
match: /,{children:\w+}\)\)}}\)]}\)(?<=function\s\w+\((\w+)\){var \w+,(\w+)=\w+\.type,(\w+)=\w+.textValue[.\s\S]+?,{children:(\w+)}\)\)}}\)]}\))/,
replace: ",{children:$2.analyticsName===\"normal\"?$3.length:$4}))}})]})"
$1 should equal to e, but that's overwritten so thats why im not using it (even tho its still being captured
you shouldnt use it regardless
because as i mentioned before they're already being extracted
you should use the extracted props directly when possible
i dont quite understand it myself
i was thinking it was going to be something like this
**roleColorEverywhere.tsx: **Lines 66-69
{
match: /function \i\((\i)\).{5,20}id.{5,20}guildId.{5,10}channelId.{100,150}hidePersonalInformation.{5,50}jsx.{5,20},{/,
replace: "$&color:$self.getUserColor($1.id,{guildId:$1?.guildId}),"
}
actually thats a good point
this patch is very hyperspecific and will probably break very quickly when discord releases a new build that changes that code
it had to be specific because there are alot of ,{children:\i}, even with the almost random looking curly, normal and square brackets behind them
,{children:(\w+)}\)\)}}\)] this is the shortest i can make it for the to-be-replaced part, because otherwise it will match to multiple things
so basically
when you type close to 2000 characters it will show how many characters you got left, if you go above 2000 characters it will show a negative number
but i want to replace that with just the amount of characters in the textbox
which is pretty easy
the I on the green line is the amount of characters thats left to use
which is pretty easy to accomplish
but it should only do this when its a normal text box (not text box when editing a message)
so i came up with this:
I'm almost sure vencord streaming quality bypass actually causes crashes
still testing with it disabled
@dull magnet forgot to ping u
4
its the message length
4
4
{
find: ".CHARACTER_COUNT_OVER_LIMIT",
replacement: {
match: /(function \i\((\i)\){)(var \i,\i=\i\.type,\i=\i\.textValue,\i=\i\.maxCharacterCount,\i=\i\.className)/,
replace: "$1return ($self.renderText($2));$3"
}
},
this is the patch i made
renderText: e => <TextComponent length={e.textValue?.length} />
``` then i did this
function TextComponent({ length }: { length: number; }) {
return (
<div className="msg-content-length-text">
{length}
</div>
);
}
``` and this is to show the number
Do you know if there is a way to create a global store using the function you sent me? When I use the useDataStore function it only creates a store in the react component where I call it. That means I could have two stores which are independent of each other. I could easily solve this issue by simply creating the store in a react context, but there is no way for me to wrap the app component with a provider. I need to wrap the app component because I need to use the store in components I don't really have access to. I'm just wondering how other people have solved this problem because it's really unlikely I'm the only one using some sort of a store.
im pretty sure you can do a global store using a class extending Flux.Store
you could just use normal settings api
if ur data is small like this
and useSettings() from anywhere
#suggestions
no suggestions wqtf
anyways my suggestion add profiles for rich presence then ill uninstall bd
is there a way to access the guild icon component
u can use github discussions for plugin suggestions https://github.com/Vendicated/Vencord/discussions
i already got it working too
.
oh didnt see that
when the trolling
that means it's no longer binding!!!!!!!!! /j
real
if you want to make edits
i made a branch on my forked repo
i know how i can patch the character count better
but ive spent too much time on Vencord the last week
i really gotta start working on school stuff because exams in 2 weeks and have to do a assignment before next week, but i hadnt started yet 💀
procrastination
Is there a way to replace an object in the Settings Proxy object? If I do
getPluginSettings().currentProfile = profile
It just doesn't replace anything. The profile object conains informations about the current profile like (width, height, ...). The only solution iv'e found is
Object.assign(getPluginSettings().currentProfile, profile);
but this isn't really a solution because I need to replace everything and not merge it.
idk what getPluginSettings is
Oh sorry forgot to add the function. Here it is
export function getPluginSettings(): PluginSettings {
return Settings.plugins[PluginInfo.PLUGIN_NAME] as PluginSettings;
}
PLUGIN_NAME is the name of my plugin.
dont use it like this
oh, this should work fine
it doesnt?
Wait I will check something
Okay no. If I change the code to
getPluginSettings().currentProfile = profile
console.log(getPluginSettings().currentProfile);
it still prints other the old profile. I also checked the profile that it sets and it's a different one so it's something else...
The weird thing is if I print out getPluginSettings() it has the changed profile but if I print out getPluginSettings().currentProfile I get the unchanged one. Maybe it has something to do with the Proxy? I don't really have knowledge about the Proxy object but maybe it has something to do with it.
Ah and I found out something else. If I set it the way I do it (getPluginSettings().currentProfile = profile) currentProfile becomes a normal javascript object and isn't a proxy object anymore.
if i make a pr, will my branch still exist?
and
if i make a pull request
and it gets accepted
does that mean my branche will get "deleted"
(i am github noob)
it won't but you should delete it afterwards
why do you ask?
if you want to push a second feature, make a second branch
i was just curious because im github noob
its only 1 file, i would be able to just copy it back anyway
why would you need to add it back
if it's merged into main then you don't need the feature branch anymore
Okay I found a solution and don't know if it's a bug so it would be really helpful if you could tell me. If I change this
// Wraps the passed settings object in a Proxy to nicely handle change listeners and default values
function makeProxy(settings: any, root = settings, path = ""): Settings {
return proxyCache[path] ??= new Proxy(settings, {
...
to this
// Wraps the passed settings object in a Proxy to nicely handle change listeners and default values
function makeProxy(settings: any, root = settings, path = ""): Settings {
return proxyCache[path] = new Proxy(settings, {
...
it works because I changed the ´??=´ operator to =. Does that mean it's a solution to my problem or is it some sort of bypass of a mistake I made?
add ```js
delete proxyCache[path];
and it should work
What is a set trap? Do you mean the set function? Something like this?
set(target, p: string, v) {
// avoid unnecessary updates to React Components and other listeners
if (target[p] === v) return true;
target[p] = v;
delete proxyCache[path];
// Call any listeners that are listening to a setting of this path
const setPath = `${path}${path && "."}${p}`;
for (const subscription of subscriptions) {
if (!subscription._path || subscription._path === setPath) {
subscription(v, setPath);
}
}
// And don't forget to persist the settings!
VencordNative.ipc.invoke(IpcEvents.SET_SETTINGS, JSON.stringify(root, null, 4));
return true;
}
yes
Okay I tried that it didn't work for some reason
Ah yes now it works
the reason that cache exists is because otherwise it would create and discard hundreds of instances
which is just not necessary
every time you access a setting it would
settings. // create proxy
plugins. // create proxy and discard the first
YourPlugin. // create proxy and discard the previous one
SomeSetting // discard proxy
Oh that makes sense
wait
does android not use a momospace font
for codeblocks
I can't manage to align the //
I don't know hahaha
But is this whole thing some sort of oversight or something like that or only a fix for my plugin?
oversight
should I do a pr?
the reason this happens is because every time you get a value, it proxies it if it's an object and caches that proxy (for above mentioned reasons), then reuses that proxy for future use
if you overwrite the object later, it still has the cached proxy that still proxies the old object
So the settings actually do update correctly but the proxy returns the old value
simply deleting the cached proxy fixes it like u saw
yes please
Okay gonna do 🙂
git commit messages should be present tense :P
Oh sorry I don't have that much experience with github and even their naming conventions. And my english isn't the best as well hahaha.
that's fine
well it's slightly subjective, however most projects use present tense and even the git guidelines tell you to use present tense
That's good to know! Learned something new again thank you 🙂
@dull magnet sorry for the ping, i just wanted to check with you if the edits i'm making correspond to the edits you requested, here's a diff https://img.remty.xyz/Rx7L65aW.png
yup
also u should probably add { noop: true } as 2nd param to the ErrorBoundary
that's the default fallback of our ErrorBoundary
i see
passing { noop: true } makes it render nothing instead of the error box
it would be quite ugly to have a red error box randomly in settings so noop is probably better :P
right, makes more sense here
anyway every time you see one of those it means the ErrorBoundary just saved u from a crash
thats why u should always use them if possible
also what's the policy on trailing commas, cuz i saw i accidentally left some you removed
doesnt really matter, should just be consistent
okay thanks
also sorry for doing a PR from the main branch i forgot when making my commit
@dull magnet fuck i broke it
don't merge kek
wrapping in the errorboundary broke it somehow
huh?
yeah i need your help here
how is it broken?
the way i decided to do it was this but im not sure if you would want to
we could make it a option
but it'd be pretty performance heavy i assume
i dont really think
having to calculate how many chunks there are for every keystroke
its just math.floor(messagelength / maxcharcount)
not if you have SplitPlace.NewLine
lol i forgot about that
idk if you read my code
i think i'm just stupid don't worry ven
i did but i only use the single char one
simply debounce it :P
wat is debouncing
okay i'm just stupid
fair enough
**debounce.ts: **Lines 19-32
/**
* Returns a new function that will call the wrapped function
* after the specified delay. If the function is called again
* within the delay, the timer will be reset.
* @param func The function to wrap
* @param delay The delay in milliseconds
*/
export function debounce<T extends Function>(func: T, delay = 300): T {
let timeout: NodeJS.Timeout;
return function (...args: any[]) {
clearTimeout(timeout);
timeout = setTimeout(() => { func(...args); }, delay);
} as any;
}
i wasn't calling my function with my colors object
essentially, every time you call it it will clear previous schedules and schedule the callback in delay milliseconds
the only place where typing doesn't happen and i didn't think to check guuuh
so if you type 10 characters it will keep cancelling the previous timers
then once you stop typing for 300ms, it will run the callback
:P
okay fix pushed ven
hmm i guess its doable then
got an idea
actually no wouldnt work because the function only runs on send
what was your idea?
make a global chunks variable to only use the function as little as i can
that wouldnt really work no
I'm curious, what's a usecase for this
debouncing wouldnt work since it returns a promise and i need to return a jsx element
rewrite armcord
time to recreate discord in rust
something ive wanted for a long time
@hasty stag do you have your code opensource?
i can send it but its mostly yours
i added this to patches
{
find: ".CHARACTER_COUNT_OVER_LIMIT",
replacement: {
match: /(function \i\((\i)\){)(var \i,\i=\i\.type,\i=\i\.textValue,\i=\i\.maxCharacterCount,\i=\i\.className)/,
replace: "$1return ($self.renderText($2));$3"
}
},
renderText: e => <TextComponent data={e.textValue} />
``` and this
export function TextComponent({ data }: { data: string; }) {
if (data.length <= 0) return null;
const [chunks, setChunks] = useState<string[]>([]);
useEffect(() => {
debounce(() => {
setChunks(intoChunks(data, getMaxMessageLength(UserStore.getCurrentUser().premiumType ?? PremiumType.None), splitterSettings.store.splitPlace));
}, 300);
return () => { };
}, [data]);
return (
<div className="msg-content-length-text">
{`${data.length}: ${chunks.length} ${chunks.length > 1 ? "Chunks" : "Chunk"}`}
</div>
);
}
``` this doesnt work for showing chunks yet i still need to figure out the useeffect
yooo is that good?
like does it work normally or misses functionality electron has
its probably not much different, just that you'd be writing ur 'preload' logic in rust
i wonder how good of an idea that'd be
it seems terrible
the active now page seems to hide when the window width is under 1201 pixels, which is annoying since my discord monitor has a width of 1050pixels. does someone know how to lower this number with vencord?
If you're comfortable with installing userplugins I'm willing to have a look
i dont have a problem with that 🤷♂️
although ive never done it in vencord, i only switched recently
oh. that makes it slightly more complicated, although id give it a try
is there a way to keep my current configuration after selfcompiling?
yeah it's not too hard
yea ur config isnt stored in the same place
is it-
ur config isn't stored next to ur installation no
it's always in roaming right
yea
but you can have the repo cloned elsewhere?
although i think the installer might put the installation next to ur config by default
yea
also am i right about updates still working the same
i never actually checked i believe
idk i dont update
lol
do you want to make it doesnt hide or something
[class*="nowPlayingColumn-"] {
display: block;
}
yeaah
put that to custom css
welp i didn't think to check css
yeah lol
@unreal mason change it to what i edited, so it wont break when discord change these random letters, i forgor
ah right, makes sense
why does dc do the random letters tho?
it has to do with their css bundler, sometimes they use the same class names in different components, so the random letters specify which component it belongs to
so they dont overlap
alright
it works completely different under the hood, but it's the same flow for the user so you don't notice
is there a way to replicate banger plugin with js?
what
yeah that's what i thought
we have two updater backends, one that shells out to git and node and one that uses the github api

sounds like it might've been a pain to make
nah fairly simple
the git one we already had initially, it was the only way to install when vencord was new
then I just wrote an equivalent http updater
**index.ts: **
/*
* Vencord, a modification for Discord's desktop app
* Copyright (c) 2022 Vendicated and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import(IS_STANDALONE ? "./http" : "./git");
... (-10 lines left)
-10 lines left
lol
looks interesting
how can I make discord use the browser font?
css
what css?
my problem is that I don't know what font to set it to so it's the browser font
If I say it I'll get banned ||it's fira code||
idk if it's serif or not
--font-primary: sans-serif; or --font-primary: monospace; will probably work
i think those are the browser provided font names
How can I use css to modify "Avoid pronouns, use my name" to "Name" (The first takes too much place)
no
not possible with css
unless the plugin is edited to add some attribute
like data-pronouns
I don't use the plugin, I use the web extension which has a .pronoundb-pronouns class
knowing that, how can I do that ⬆?
there is also .vc-pronoundb-compact for the plugin
why would you post a css snippet that doesn't work with Vencord
That's a way to see it
I see it as working with the web ext
If you want I can delete it
yes
ok
can I make a PR for the plugin?
I think I'll need some help but I'm all for it
shall we use the same class as the extension?
(.pronoundb-pronouns)
no
I'll use the one you proposed then
if you use the same class as the extension then you must also guarantee our component is similar to theirs
aka in the same location, same styles, same htlm element
otherwise it's worthless
no compatibility is better than broken compatibility imo
I can do that
do you want it?
so @dull magnet ?
well I gotta go eat I'll do it after (usually takes 1h because of my sister)
has anyone figured out how to create new windows?
like a popout window?
yeah
the quick css Editor does it
oh yeah ofcourse
I wonder if we could fix quick css on Firefox by making it a popup of the extension instead
I think that's a thing
question difference between scripting and coding which one is better
scripting is automating something
coding is well, the practice of writing code
ik the difference
but i meant which one will have more uses
i’ve heard a lot bout js so i was gonna start learning it then i realized i would only know scripting so i was seeing if i should learn one before the other
coding lmfao
any language recommendations
js and python are fine choices
depends on usecase
(do not)
why not
you're gonna have a hard time
gonna do it then
i'd start with assembly
start with python
its easiest and doesnt have weird quirks like javascript
I think a lot of people call writing js scripting
dum
python is garbage
js is probably the best starting language
ok but try explaining === vs == to a complete beginner
they'll just get confused and use both at random
nothing to explain, just use ===
lets not get started on javascript types
gives you an easy step up to typescript, a great base for learning other C-like languages, and it's so versatile, once you know js you can basically make anything thanks to frameworks like electron
your argument is basically "obscure language feature and quirks you're told to just avoid by all guides make the entire language bad"
javascript is just weird
if you want to start with javascript you should rather start with typescript
no lol
@cedar olive epic idea
then check for that name query parameter and use it as the emoji name instead of FakeNitroEmoji
the thing is, those quirks and features can happen on accident and cause massive confusion
because sometimes they cause errors and sometimes they dont
honestly i would only reccomend python or c(++)
LOL
js is bad because making mistakes can cause massive confusion
I recommend C
a mistake can happen as quickly as taking a inputing and doing math
if user input = "4" and the code did input + 2 you'd get "42"
I tried C
I gave up
how are u gonna recommend C where forgetting to end a string with \0 or accidently indexing an invalid array index can cause undefined behaviour and memory corruption that's impossible to debug for a newbie
that kind of automatic type conversion is just bs
and at the same time say js is bad because you can make mistakes
What about rust then lol
doing rust good is too hard
but tbf they can .copy() everything
albeit inneficient
I never tried rust
i only reccomended C because you were talking about getting into C languages
we're talking about beginners
the beginner programming book gives an example of why you shouldnt use .clone() on everything
same with rbe
C wasnt a good example for safety i gotta admit
i avoid .clone() at all costs, but who cares if its someon's first file of code?
anyway
"2" * 2 -> 4
"2" + 2 -> "22"
teaching poor practice first thing is never a good idea
enforcing perferct code from the start is not a good idea either
.
there's a difference between enforcing perfect code and teaching something that you shouldn't be doing
your argument is really stupid sorry
well i wouldnt reccomend rust to a beginner anyway
too hard
you're trying to convince beginners of your own opinion instead of trying to be objective
Javascript is bad in my opinion so you shouldn't use it
javascript is bad because of things x, y, z, etc...
you said javascript is good for beginners because it has alot of capabilities, but so does python...?
its your preference for liking javascript too
so in your case it would be "Javascript is good in my opinion so you should use it"
no
Javascript is objectively one of the best languages if not the best language to pick up as a beginner for a multitude of reasons
high popularity, best odds of getting a job
many great resources online
versatility
absolutely necessary to make web stuff anyway
ease of use
high readability
clike which makes it similar to many other languages (java, C#, etc) and gives you a great base to learn those later
easy step up to typescript later on
and that's just the beginning, there's way more good arguments
the only real argument for learning python first is that it's easy. But it doesn't offer you a good base for other languages, it has crappy performance, cannot be used for as many things, it's mostly good for scripts
I always wonder how many people that bash on JS have actually used it seriously before, and if they have used it seriously I wonder how bad of code they must have written to consistently run into the "js bad" issues they always complain about
same reason why that's what we learned at school here lol
yeah, every time someone tries to call js shit it's them going on about things like ==, the fact that adding different data types yields weird results (duh??) and other quirky behaviour, but every up to date resource you can find online explicitly tells you to avoid things like this
there are many actually good arguments against js, but you can find good arguments against any language
its like me saying
dont use assembly
it doesnt have operators
and control flow is obfuscated
Also I think criticising "2" * 2 = 4 is also really funny coming from a python user, you're trying to unironically tell me "2" * 2 = "22" is any less confusing?

python is also populair. Depending on the field JS has biggest odds, but so do C# and python in other fields. This shouldnt be reason to learn a specific langauge.
alot of languages have great resources.
python also has huge versatility
not true, you can make a website with python-only (not sure if i'd reccomend that, but if you want to you can)
ease of use? python is the easiest to use
most well-made code is highly readable
going from python to java, the only thing that confused me was using this without this being a function parameter, but that didnt take me long either
your 2nd langauge is always easy, the only thing that's usually the challenge is setting up environments etc, because youre not used to them. learning new syntax is easy, the important thing about your first language is learning programming concepts
"its easy" shouldnt that be most important for a beginner? (its why scratch exists for young people... its easy?) performance doesnt matter, you can easily create 2d games in them and its fast enough with the abundant amount of c-librarys. python can be used for a fricking lot, desktop-dev, web-dev, creating games...
this is easy for experencied to say because they know waht to avoid while coding, a beginner does not
a beginner who just started to learn how to use variables shouldnt be bothered by the fact they have to check their code they didnt accidently use == instead of ===. Ofcourse the person eventuaklly finds out, but == doesnt lead to errors (right?), just weird behaviour.
its odd anyhow that === is common practice for is-equal rather than ==
do you know the difference between the two
yes i agree that something like .repeat(n) wouldve been better. But python errors while trying "2" + 2, in javascript it doesnt. my argument is that javascript has a very odd type conversion. Also, that python example doesnt actually do type conversion there. Every type in python has methods that describe how operators function on them, in this case it would be str.__mul__(self, other: int): return "".join(self for _ in range(other), ofcourse written differently because its written in C rather than in python
one is loose the other is strict
iirc
so what? as if an beginner would stumble upon how to write hexadecimal (btw for who doesnt know, it actually says 0x0f or x in {1,2,1}, its not an for loop)
im using your own complaint against you 
that was not clear to me the first time i saw that example
and i have been doing python for years
there are alot of things that arent clear when you first come across them
yes in every language
but in this case you wouldnt come across it very fast luckily
you dont just accidently write a hexadecimal while also accidently writing a list comprehension
assuming we're talking about python __<__3.11
how is "2" * 2 = "22" not confusing for a beginner
how is "2" * 2 = 4 but "2" + 2 = "22" less confusing than "2" * 2 = "22" for a beginner?
multiplying strings never makes sense
the first makes sense because people know what multiplication is
there's a reason why we have things like string.repeat()
the latter 2 are initially confusing because you have to learn casting / that * specifically means repeat
list comprehensions are also a pain to read for beginners, and sufficiently complex ones are a pain regardless of skill level
"2" * 2, i want string "2" two times?
"2" * 2 = 4, alright so math just works on string i see
"2" + 2 = "22", huh math doesnt work?
i agree that wouldve been better
a beginner isnt going to be thinking about types as rigidly as you are
but python's "2" * 2 is a one-off, javascript does automatic type conversion everywhere which is way worse
thats kinda the whole thing they have to learn
that doesnt mean theyre bad, just badly written, just like there are enough people that write poor javascript code
* 2 works because in js it implicitly casts the string to a number since thats the only logical solution, but + 2 onto a string is a completely different meaning and that, in fact, works in almost* every language as standard
they shouldnt be bombarded with all the different automatic type conversions from the start
so py > js?
/run
"2" + 2
are you saying "2" + 2 works in almost every language?
@woven lion I only received cs(6.12.0) error output
Cannot open assembly 'out': No such file or directory.
as a beginner, strict types might feel more bombarding depending on the person, as it requires a lot more keeping track of things
Here is your cs(6.12.0) output @woven lion
22
in what languages lol
what? having to keep track of all the possible type conversions is way more work lol
you dont have to as a beginner
/run
pub fn main() {
println!("2" + 2);
}
@woven lion I received rust(1.65.0) compile errors
error: expected `,`, found `+`
--> file0.code:2:18
|
2 | println!("2" + 2);
| ^ expected `,`
error: aborting due to previous error
chmod: cannot access 'binary': No such file or directory
/piston/packages/rust/1.65.0/run: line 4: ./binary: No such file or directory
people are a lot more neuroplastic in general than ur implying
/run
pub fn main() {
println!("{}", "2"+2);
}```
@amber condor I received rs(1.65.0) compile errors
error[E0369]: cannot add `{integer}` to `&str`
--> file0.code:2:21
|
2 | println!("{}", "2"+2);
| ---^- {integer}
| |
| &str
error: aborting due to previous error
For more information about this error, try `rustc --explain E0369`.
chmod: cannot access 'binary': No such file or directory
/piston/packages/rust/1.65.0/run: line 4: ./binary: No such file or directory
the point where a developer is annoyed because they feel like they have to keep track of types
is the point where you switch to TS
which is not a beginner stance
/run
public class A {
public static void main(String[] args) {
System.out.writeln("2" + 2);
}
}
wait
is it println in java
/run
public class A {
public static void main(String[] args) {
System.out.println("2" + 2);
}
}
Here is your java(15.0.2) output @woven lion
22
Here is your kt(1.4.31) output @woven lion
22
anyway i could get a massive list of these and just keep going
point is yes
"2"+2 does work in loads of major languages
exactly how js does it
yea but java and c# arent beginner languages lol
that's a different argument
they require the user to know what types are from the get go
and java and c# are taught at a very young age here nowadays
ffs im just gonna quit it
many universities use Java as introduction language
and

mine does lol
to which i presented a couple of major languages that do it like this
anyway adding stuff to strings getting auto casted is nice and useful
I use it a lot in many languages
with the subtext that most major languages do it like this
because it just.. makes sense
it just implicitly calls toString() in most languages

it doesnt matter anyway, no offense, but every web dev server always fanboys javascript. Most other prgramming servers would disagree.
yes i love TS but damn JS sucks for beginners
"https://google.com/search?" + new URLSearchParams({ q: "banana milkshake" })
Search the world's information, including webpages, images, videos and more. Google has many special features to help you find exactly what you're looking for.
i dont like javascript

i like typescript because its not completely insane
like yes there's still the funnies
it doesnt lol, type conversion shouldnt be automatic, especially if the beginner user doesnt know what types are
but typescript yells at you
(it doesn't, you're still just going on about ur personal opinion)
it doesn't matter much honestly lol
im gonna be honest you probably use autotype conversion without even thinking about it

it's almost like the majority of languages have implicit type conversions because it's incredibly useful
Integer x = 1;
``` vs ```java
Integer x = Integer.valueOf(1);```
yeah between String and &str
rust doesnt have implicit casts for primitives
rust has a ton of implicit casts with into()
you have to call into() for that
yeah
String != &str
into() is okay
i know
its that rust does implicit derefs to match a signature
sometimes implicit referencing
its kinda funny because i acctually dont like Java either 💀
the funny thing about this statement is that removing automatic type conversions will require the user to learn what types are
knowledge of types is also not even such a hard concept to understand
indeed
most knowledge is fuzzy as a beginner
if anything, it makes it less confusing to the person because you can't accidently pass wrong data to functions
so even if a beginner is basing their understanding of types from like typeof
then thats still fine
anyways
how about that [object Object] amirite
i prefer `${new class {}}`
wait i forgot what makes it just [object ]
`${{ [Symbol.toStringTag]: "" }}` 
knowing what a integer, a float and a string are is different than also having to know which types convert to which when you use them in certain ways
i think thats the only one tho, but atleast this one makes sense, theyre both numbers
true "2" + 2 simply multiplies "2" by 256 first
someone should write a language where thats the csse tbh
(it's called c)
(i did it in #🤖-bot-commands but here it is here for channel linear history)
/run ```c
#include <stdio.h>
int main () {
printf("%i", 'a' * 2);
}
Here is your c(10.2.0) output @grim hare
194```
is there a way to make compact mode work a bit like cozy mode where when someone post two messages in a short amount of time instead of saying the username twice it "merges" them?
tbf that's a char which is just a number type
and doing math on chars is really useful
int parseDigit(char digit) {
return digit - '0';
}
parseDigit('9') // 9 (as int)

imagine how peaceful and calm this chat wouldve been if this guy didnt ask for beginner language reccomendations 💀
it is peaceful and calm
i was jus jokin
me when mommy didnt get choccy milk
a squared
/run ```c
#include <math.h>
#include <stdio.h>
int main() {
printf("%c", sqrt('a'));
}```
Here is your c(10.2.0) output @dull magnet
h```
h
LOL
why is h the sqrt of a
that doesnt make SENSE
i would imagine sqrt('a') < 'a'

probably cause the sqrt of 'a' isn't a whole number
tbf it makes sense, it's just indexing into a pointer that is null (the pointer itself is null)
i think it would fail
it will just either segfault or work fine on weird systems
i was trolling about syntax that u have to learn to make sense
/run ```c
#include <stdio.h>
int main () {
printf("%lu", (unsigned long) "h" * 2);
}
Here is your c(10.2.0) output @grim hare
8405000```
/run ```c
#include <math.h>
#include <stdio.h>
int main() {
printf("%c", sqrt('a'));
}```
Here is your c(10.2.0) output @dull magnet
(```
/run ```c
#include <math.h>
#include <stdio.h>
int main() {
printf("%c", sqrt('a'));
}```
Here is your c(10.2.0) output @dull magnet
�```
/run ```c
#include <math.h>
#include <stdio.h>
int main() {
printf("%c", sqrt('a'));
}```
Here is your c(10.2.0) output @dull magnet
�```
how would it be
i dont know but it looks like it
stay mad, i already took my words back abt C
/run ```c
#include <math.h>
#include <stdio.h>
int main() {
printf("%c", (char) sqrt('a'));
}```
Here is your c(10.2.0) output @dull magnet
```
hmm
/run ```c
#include <math.h>
#include <stdio.h>
int main() {
printf("%c", (char) (sqrt('a') + 50));
}```
Here is your c(10.2.0) output @dull magnet
;```
/run ```c
#include <math.h>
#include <stdio.h>
int main() {
printf("%c", (char) (sqrt('a') + 50));
}```
Here is your c(10.2.0) output @dull magnet
;```
i need to know why
/run ```c
#include <stdio.h>
int main () {
char * hi = "hewwo owo";
printf("%s\n", hi + 6);
int numbers[5] = { 0, 1, 2, 3, 4 };
printf("%i", 4[numbers]);
}
Here is your c(10.2.0) output @grim hare
owo
4```
pointers are amazing
i need a translator
"its joke"
@dull magnet
/run ```c
#include <math.h>
#include <stdio.h>
int main() {
printf("%i", sqrt('a'));
}
Here is your c(10.2.0) output @trail ginkgo
-1103781416```
/run ```c
#include <math.h>
#include <stdio.h>
int main() {
printf("%i", sqrt('a'));
}
Here is your c(10.2.0) output @trail ginkgo
-821694712```
literally random number generator
ye
WHY
run it 5 million times and check if its evenly distributed
it might be because the function takes a double but we pass a char, so it just uses our char + 7 random bytes or smth
but that'd be weird too
/run ```c
#include <math.h>
#include <stdio.h>
int main() {
printf("%f", sqrt('a'));
}
Here is your c(10.2.0) output @dull magnet
9.848858```
no it works correctly
if sqrt takes a double that's definitely what's happening
/run
#include <math.h>
#include <stdio.h>
int main() {
printf("%i", sqrt('a'));
}
@steel oriole
Unsupported language: None
Request a new language
just giving printf the wrong format specifier
o that makes sense too
yea i just wonder what its doing
/run
#include <math.h>
#include <stdio.h>
int main() {
printf("%i", sqrt('a'));
}
Here is your cpp(10.2.0) output @steel oriole
324471560```
maybe the next bytes in memory?
Well you're telling it to print an int and passing a double
which doesn't make a lot of sense
why do you even have that bot
cant people make it say stuff that breaks rules?
yes so it just ignores presumably the last 4 bytes
So?
shouldn't it error if you give it the wrong format specifier
then we ban that person
this is C......
yea but truncation is deterministic
we don't know errors in C
not in v10
i think it does in a later verison or something
true
Update: Discord changed their client to prevent sending messages
that are preceeded by a slash (/)
To run code you can use "./run" or " /run" until further notice
Here are my supported languages:
awk, bash, basic, basic.net, befunge93, bqn, brachylog, brainfuck, c, c++, cjam, clojure, cobol, coffeescript, cow, crystal, csharp, csharp.net, d, dart, dash, dragon, elixir, emacs, emojicode, erlang, file, forte, forth, fortran, freebasic, fsharp.net, fsi, go, golfscript, groovy, haskell, husk, iverilog, japt, java, javascript, jelly, julia, kotlin, lisp, llvm_ir, lolcode, lua, matl, nasm, nasm64, nim, ocaml, octave, osabie, paradoc, pascal, perl, php, ponylang, powershell, prolog, pure, pyth, python, python2, racket, raku, retina, rockstar, rscript, ruby, rust, scala, smalltalk, sqlite3, swift, typescript, vlang, vyxal, yeethon, zig
You can run code like this:
./run <language>
command line parameters (optional) - 1 per line
```
your code
```
standard input (optional)
Provided by the Engineer Man Discord Server - visit:
• https://emkc.org/run to get it in your own server
• https://discord.gg/engineerman for more info
is there a way to replicate BANger using js
im reading linux docs
/run c
-Wall
-Werror
#include <math.h>
#include <stdio.h>
int main() {
printf("%f", sqrt('a'));
}
Here is your c(10.2.0) output @dull magnet
9.848858```
/run c
-Wall
-Werror
#include <math.h>
#include <stdio.h>
int main() {
printf("%i", sqrt('a'));
}
Here is your c(10.2.0) output @dull magnet
1927604840```
is there a way to replicate the effects of BANger using js
what the fuck does pnpm want from me
remove the import
you already asked that like 3 times and it still doesn't make any sense
i'm guessing "command line parameters" means passed to your program, not the compiler
how is there not any sense
/run ```bash
cat > main.c << 'banana'
#include <math.h>
#include <stdio.h>
int main() {
printf("%d", sqrt('a'));
}
banana
gcc -Wall -Werror main.c
@dull magnet I only received bash(5.1.0) error output
main.c: In function 'main':
main.c:5:14: error: format '%d' expects argument of type 'int', but argument 2 has type 'double' [-Werror=format=]
printf("%d", sqrt('a'));
~^ ~~~~~~~~~
%f
cc1: all warnings being treated as errors
there we go
it's already in js so I have no idea what you're asking
replicate the effects how
really?
i cant find the code
**banger.ts: **
/*
* Vencord, a modification for Discord's desktop app
* Copyright (c) 2022 Vendicated and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
export default definePlugin({
name: "BANger",
description: "Replaces the GIF in the ban dialogue with a custom one.",
authors: [Devs.Xinto, Devs.Glitch],
patches: [
{
find: "BAN_CONFIRM_TITLE.",
replacement: {
match: /src:\w\(\d+\)/g,
... (14 lines left)
that is typescript
now what's typescript
glorified javascript
a superset of Javascript
same thing
Also nothing in that file uses typescript features so u can literally just rename it to .js and it'll work
i just got 13 errors screaming
does vencord have custom plugins support? no
we dont provide support for betterdiscord
vote ban
vote ban
no
realise that maybe there's a good reason electron is so popular
nothing offers as good apis as it
way lower resource usage
But i like krisp :(
for example, does gluon support intercepting requests to modify headers
does it support custom protocols
does it support frameless windows, preload scripts similar to Electron
etc
But tbf having an app can possibly open doors to stuff like screenshare with audio on linux
the same is true for things like tauri
they all offer pretty limited apis
true enough
voice engine will be real
although u dont really need a new
desktop app for that
what the fuck is voice engine
oh yeah we need to work more on voice engine
tauri
tauri is garbage
👎
idk ive never tried it
.
why are you recommending something you've never tried



