#help-development
1 messages · Page 778 of 1
yes
When i launch mcp (trying to open it in intellij) all the dependencies are at another location from another mcp, and i have just changed them all and when im opening intellij it sets them back again, is there a way to fix that?
you would need to know resolution in order to calculate pixels. but blocks are 1meter tall and 1 meter wide, and 1 meter long
Okay, so there's no easier way to know how tall a block is?
You could make use of its collision shape, https://hub.spigotmc.org/javadocs/spigot/org/bukkit/block/Block.html#getCollisionShape()
well, knowing that a full block is what I said, it should be fairly easy to calculate all other blocks based on that
Get the collision shape, getBoundingBoxes(), iterate over said bounding boxes and find the highest y value
There's your height :p
the alternative, is to just make a list of all block sizes
I mean yeah but have fun making that list lol
lol
I suppose if you're checking a very specific set of blocks then possibly better, at least it's O(1).
But otherwise you can just use the method I suggested
I mean if he goes through all types of blocks onEnable or smth and saves their height, he’d be at O(1) in a HashMap still 👀
Does anyone know why?
@timid hedge
Kk, i just though your guys didnt see it
I saw it but you would be hardpressed to find someone who knows a lot about mcp i think
No clue about mcp
Yeah proberly, but is there anything else that is good for a client / a launcher
And i cant find out if it is allowed or not to make your own
Fabric
Its for 1.8.8/1.8.9

do maven modules make the jar size significantly bigger? ever since i made my project multi-moduled the jar size has been about twice the size it used to be
not a huge deal, but i'd prefer to keep jar sizes small
No
Might just be shading an extra dependency you missed
unpacking my project shows it only has the essentials plus some jeff media stuff which it had before anyway
or is that not the right way to check that
That’s a fine way
Yeah, .jar files are just an archive you can unpack :p
then im not sure where the doubled file size came from lol
project before produced a jar of like 800kb and now thats 1800
Maybe you weren’t shading properly before?
you probably shouldn't be shading essentials?
THE essentials lol
no not literally "essentials"
lol
essentials 🤮
how many modules do you have though
i was using the jeff media plugin preset thing which seems to do its shading fine
didnt support multi modules though so i had to change it up
currently it only has core, dist, and one for nms which is currently just 1
.
You changed smth
It got bigger
Boom
yeah
Issue solved
but WHAT
Whatever wasn’t there before
+1 ^
Does maven not have a minimize function for shading?
it does and im using that
not really wise to minimize if the dependency uses reflection, but You could otherwise
Guess ur using one extra class or smth that has a shit load of dependencies
how big is your jar
mind you when i didnt use it the jar became like 8mb big lol xd
used to be 800kb now its 1800kb
Not really that big
Not that big
that's still fairly small, though that little stuff shouldn't be that big make sure you're not shading stuff multiple times etc. if you're not you're all good to go
You can just do github releases and link to those
fair
im not saying its big im just wondering where the extra size is coming from
and 8mb for a plugin is rather big considering thats just code
not any configs or presets or whatever
Not sure how he managed to make such a big jar from so little stuff. My NMS library, My Core Library, AND my Database lib which shades a database platform with minimal exclusions ends up at 2mbs
that includes the size of the plugin I shade into as well
send your poms and label them
well first how many classes do you have abouts
is there a quick way i can see that lol
if you have a couple hundred the size would be expected
its probably roundabouts there
Hm
Open the archive
And see how many individual files are in it
If u unzip it and hit properties it should show
666 files right then
Probably about right
sounds about good for that size then
erm you uhh configured something incorrectly
YEAH
yeah ill do that lol
For once the time I spent properly learning maven may pay off
Bruh, even when people share their gradles i can only help sometimes ahaha. Like there is so much random shit u can do in so many diff ways
the main downside of gradle just being scripts
especially if they use random custom scripts
don't use maven shade in NMS and Core. Idk if this is the cause, but there is nothing you need to be shading there
you don't need to depend on GSON
spigot provides it
ill try removing that
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.jeff_media</groupId>
<artifactId>MorePersistentDataTypes</artifactId>
<version>2.3.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.jeff_media</groupId>
<artifactId>CustomBlockData</artifactId>
<version>2.1.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.github.MilkBowl</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.7</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-bukkit</artifactId>
<version>7.3.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-bukkit</artifactId>
<version>7.1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.11.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport</artifactId>
<version>4.1.82.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>3.0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
<scope>provided</scope>
</dependency>```
This is a lot of dependencies to have just sitting around in your parent project? do you really use them all in EVERY modules? that's the only reason you should ever really put something as a depend in your parent
i could just shove em to core i guess yeah
despite them being marked as provided I'd find it suspect that the shade plugin being literally everywhere as well as you not carefully choosing which dependencies to put where may be the issue
also i put gson there because supposedly using 2.10.1 fixed a specific bug i was having, it didnt solve it but i forgot to remove it
leads me to believe you may be shading and relocating multiple times
Ew lombok
we can ignore that for now one problem at a time here
i heard the word gradle
Not doing anything with it atm sadly
sad
intellij has ways to delombok and lombok classes
so just remove the shade plugin part yeah?
and yeah im not even using lombok so im removing that too lol
I'm back again with more bit funniness... Because I can't figure this out!
This code works fine, EXCEPT for negative numbers. Ik why, cause the twos-compliment causes the bits to always have all leading "1"s. So something like this for "-5": 11111111 11111111 11111111 11111011 and I want too insert the "-5" into a long at a specific place. But then all of my bits to the left get turned into "1"s when I shift it in.
So I made a mask, ie the 0x000000000000FFFFL too ensure that only the last 16 bits are put into the long... but that still breaks everything, why?
thought it would make certain stuff easier and i ended up making a whole lot of not use out of it
For the record, everything beside y1 & y2 is a byte, the y coords are shorts
?img
Can't send images? That's because you're not verified! Use !verify to complete verification.
Alternatively, you can upload screenshots to any image hosting site and share the link.
Here's some screenshot utilities that can use to upload images.
Lightshot: https://prnt.sc
Imgur: https://imgur.com/upload
Flameshot: https://flameshot.org
so when there is a minecraft update
how do i decide if i need to update the plugin or not
Do you use nms?
i might
Do you use any deprecated or staging bukkit/spigot api? @grand flint
is it preferable that we create threads or do we just ask away like this
Just ask, we mostly don’t care.
no my server
Thanks, I have a piece of code that I can't figure out why it's not working
Wasn’t asking that
or 1.21+
Well no matter about that either way.
If you use nms, you should probably go recompile for each version
Hmm?
?paste
ye
so id need to update
if i use protocols right?
so wait if i use protocol as my protocol library for all my plugins
id need to only update procollib right?
Sometimes
thanks was just trying to find that
if theres nms changes between versions yeah, eg 1.20 and 1.20.1 is compatable so you just need it for 1.20.1 but 1.20.1 has different internals to 1.20.2 so you use 1.20.2 nms
If there is a major protocol change you might need to change smth
like the config state
the entire point of protocollib is that it allows you to manipulate packets without having to update nms each time a new update comes out
you could i guess
Mostly
I want it to allow me to cancel the drop event and cycle through the different 'modes' by pressing Q
you just gotta wait on protocollib to update
an aquaintance of mine who does some software work asked me this when I was telling him that im gonna do an API to make other plugins access same configs and he basically asked if its not possible to make that so that Plugin 2 could use Plugin 1's config, is that possible?
like honestly updating nms isnt hard at all, takes probably a couple minutes maybe
if you dont use nms or packets or whatever the quickest way to figure out if your plugin needs to be updated or not is literally just to test it out lmao
fix the errors and continue on
usually
net minecraft server code
if you add an api to plugin 1 and give plugin 2 the dep it can work
you can
sometimes a version change is a little more sneaky though, like 1.19 to 1.20 they changed it so that SmithingRecipes no longer get registered to the server. You had to either use a SmithingTransformRecipe or a SmithingTrimRecipe. bit annoying because it didnt throw errors
ye but u can read the update log for that stuff right?
No
yesn't
smithing recipes got changed is about the furthest it goes, so you might wanna check your smithing mechanics then
Yes
configs are just files, why shouldnt you be able to access em
(from other plugins)
I'd expect bukkit to have some shitty anti-malware system or something
so if i have like just a simple chat plugin
Hkjk
that wont need to be updated most of the time right?
probably not
If you just use the spigot/bukkit api then no
Most likely not
the simpler the plugin the less likely it is it needs updating, obvio
if it's already on 1.19+ probs not
but text based shit is even less likely
okk
and where do i find hcanges between updates
for plugin development
to know if i need to update or not
honestly I always forget so I always just update and see whats broken and then google the methods
If smth breaks it’s time to update
real
put some tape on it and its as good as new
@drowsy lion are you codez14?
so generally id have to make separate plugin for config management (saving, reading, writing etc.) and make it a dependency for other plugins to use?
I got a plugin that supports 1.5 to 1.17+ never updating it again and crossing fingers
You really shouldn't be saving and writing to another plugins config
If you want to read something that's fine
but thats literally what I want
because I do?
just make a global database
thats what im literally doing
then why are u making
but why 💀
another plugin
if their use case requires reading other plugin configs then honestly let em
Reading is fine. Just don't write stuff to it
someone here told me to make database with configs
ye write stuff from the actual plugin its elf
which idiot told u that
use like mysql or mongo
look here:
or sqlite
have an api plugin that manages ur database with quick methods
let other plugins manage their own configs, and if they need to save anything or get anything to the database
then u get it from the main plugin which manages that
nothing to do w configs
config isnt a player data saving place
its for plugin data
it might have been Y2K or smile
^^
maybe use configs to read the database connection stuff?
Well ur probably doing something that doesn’t require a database
Well did you want a config for settings rather than a database
It entirely depends on what you're doing
no
literally
config
as
a database
skull emoji
using configs for extensive data storage isnt great no, for storing a handful of small little things you want an admin to be able to edit is probably fine i guess
What is in this database?
next, I'm going to use postgresql for my server config
PostgreSQL ❤️
Actually valid
Cross server config easymode
custom enemies (stats, names etc.), custom items, player stats etc.
and I want them to be set, read, removed if necessary or changed
I can see why they recommended a config. You really don't need a database to store custom items or enemies
player stats on the other hand should be stored in a database
Yep
and I want to read and edit from those configs in several plugins
to not make one plugin do all the work
They might. No idea
I have seen malware on Bukkit though so 🤷♂️
Literally his first question i answered a few minutes ago
and I got an answer to make plugin with configs and make it into api so that other plugins could use those configs
We've been saying that for days now I believe
I see
this isn't the first time
the api would be changing stuff in the config
Do not expose the config directly to other plugins
Sigh
Is it a good idea to compare command logic with config logic, because if i see them both have a root level and start going deep and deep. Each tree, having nodes and each node childs
Why is it that when I place an item forcibly, I can't pick it up? It just doesn't even click
?paste
IG so I mean they are pretty much both trees
oh okay. thanks bro. Im struggling at sub commands
thanks!! i wiill check itt, because in cap i can barelly read. Sorry tho
Gotta do some inventoryclickevent logic
yeah that's Paper
Help 👉 👈
spigot paper
what? Paper and Spigot are different if that what you mean
They 2 different "server software" calling it in a way
paper
@pure stag Just forcefully set the cursor when they click it in inventoryclickevent
Anvils are evil to customize
so what if I want lets say plugins to just read information and thats it, not edit it at all, can I make them read those from same config?
and how to make one?
Make some code that is accessible from the outside of your plugin
then depend on that plugin and call the api methods
OtherPluginMain otherPlugin = (OtherPluginMain) getServer().getPluginManager().getPlugin("OtherPlugin");
String smth = otherPlugin.getConfig().getString("something");
This is a simple example, how you get an instance from another plugin.And then access its own config
That would be how you read the config of another plugin
You're not making an api there
how i can adjust?
what?
What
what?
the error
uhm
what?
the error
yeah but how
so you do new SetPosition() instead
k
that still makes 0 sense though
yeah it does
I mean
tnx
I'm not here to teach you Java
Looking at his “Sender” assuming that would be wrong
I would suggest first learning the lenguage where you are coding at it
Here are some links to get you started on learning Java:
- https://www.codecademy.com/learn/learn-java
- https://www.sololearn.com/learning/1068
- https://www.learnjavaonline.org/
- https://programmingbydoing.com/
- https://docs.oracle.com/javase/tutorial/java/index.html
The last one is the only official one, however some of those concepts assume that you already know a bit about programming.
?learnjava!
Here are some links to get you started on learning Java:
- https://www.codecademy.com/learn/learn-java
- https://www.sololearn.com/learning/1068
- https://www.learnjavaonline.org/
- https://programmingbydoing.com/
- https://docs.oracle.com/javase/tutorial/java/index.html
The last one is the only official one, however some of those concepts assume that you already know a bit about programming. https://media.discordapp.net/attachments/694661573125472256/998143126373941248/6n0v4g.gif
If you dont want to learn java, you cant expect us to help because
and it didnt say anything about apis or dependencies
that or if you want to learn with spigot with java don't expect syntax help
Is he the guy who was here the first time with us Olivo?
that's something you can use google for
wdym by first time?
be less specific on your query
totally agree, GPT can resolve those fast side doughts
idk if its more spigot thing or java thing
thats why im asking
It's a Java thing
An API is a java thing
or just generally a programming thing
^
so what do I include in this api if I want to make it have configs that other plugins could read
You want to abstract away the config
how to make an API si something you need to look up
its a concept you want to learn
Don't let others touch your config
Well, it seems our friend here might want to consider a little rendezvous with the magical land of programming slang and knowledge. It's like his programming dictionary is stuck in the Stone Age! 😂
Slang to be hip
Wait wait, so he wasnt asking how to access another plugin config from his own plugin? I fully understand that
He was, but he was a few steps from that.
ItMs not
no, why its illegal?
The way he wanted to do it is considered bad practice.
some metaphysical shit perhaps idrk
why tf would you allow read and write access to your plugins config
terrible idea and practice
I was told to store things in configs so that would be a natural thing to ask about
Expect us to always go for “best practice” if we know it and we’re here
^^ why teach bad practices
dont apis need like a site
No
no
I saw that you need to use some kind of link
REST API is different than an API
in the simplest terms, it basically is just a means for different programs to communicate with eachother
if you want to make a plugin where other plugins can read and write to your own plugin configs, that just basically means getters and setters for your config properties
why you would want this i dont know
what are you wanting to make anyway
This a common error Y2k dont get upset, i used to happen this issue with a backend developer. Because when i talk about him API, he always associate them as REST API's because he was a backend, the same concept change depending your area
i said a few times already
I want to store/read stuff so that a few plugins could use it
for what purpose
because I want to and need it for later
im asking because theres likely better ways to do what you want to do
are you being secretive because it sounds like you dont actually know what you want to do
lets just say it with an example
He isn’t getting mad by correcting him. No worries
I have a thing that stores data about custom weapons with their respective statistics, same for players and custom enemies and I dont want one plugin to handle all the work because apparently its not optimal, so I want one plugin to handle custom damage (where it'd need all 3 forementioned things), weapon upgrade (that'd need weapon information) and such
sorry i cant barelly explained my self with english
your better than me in spanish xD
and I dont think doing all of those mechanics in one single plugin and store it in configs would be optimal
okay
Why not
I understand you Dusk
But thats would be a mess havign 3 plugins to do a final product
sounds like this should all be done in 1 plugin
do I just make one plugin with 294239439 classes each for one operation?
doesnt that sound like bloating?
they are all related things, or at least it seems like they are
I don't think the amount is an issue as long as you stay consistent to some form of theme
my second message won't send fuck discord
idk one of java courses was saying that it's best to make things do one particular thing to keep things clean
sure for particular classes Single Responability Principle is good, but projects should have a scope of related tasks to be done
so I wanted each plugin to do one particular task
That's a terrible way to go about things
especially if those plugins share a lot of data about eachother its Actually less clean then doing it all in one project
Dont care about amount, just care about quality ☝️
then its suboptimal to be accessing your configs, you just want to communicate the weapon and enemy information or whatever
np
and honestly yeah just use a single plugin
thats currently how the structure looks like
dont make a mess by fragmenting your main features
sounds like you need to learn some design patterns
discord is taking a shit rn
holy shit discord FUNCTION
finally good lord
discord took a right shit
right anyway, you dont see games splitting up their stuff in individual applications right? why should plugins
I dont know man its my first ever programming project bigger than a single python file
you're making a plugin with a goal in mind, you don't need to make a new plugin for each task. generally speaking you want each class to be responsible for one thing
A properly structured plugin should be fine having those 3 features
Limbo
.
Discord dies on me
died
seems to be coming back now
which are?
average daily discord occurrence
the item, enemy, and stat features you were talking about
its fine to have them all in 1 plugin
i mean heck my plugin combines custom crafting management and loot tables and stats and shit just because my goal for the plugin requires those features to be there
should I save customconfigs on plugin disable if I want plugin only to read those?
what do you mean
if your plugin is only reading configs then no you dont need to save them again
public enum Monster {
WYAX {
public void summonWyax(Location location, MonsterType monsterType, int playerLevel) {
Vex vex = location.getWorld().spawn(location, Vex.class);
vex.setCustomName(monsterType.getTypePrefix() + ChatColor.WHITE + " Wyax");
vex.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(CalculateAttribute.health(monsterType, playerLevel));
vex.setHealth(CalculateAttribute.health(monsterType, playerLevel));
vex.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).setBaseValue(CalculateAttribute.damage(monsterType, playerLevel));
vex.setCustomNameVisible(false);
vex.spawnAt(location);
}
},
SLACK {
public void summonSlack(Location location, MonsterType monsterType, int playerLevel) {
Enderman enderman = location.getWorld().spawn(location, Enderman.class);
enderman.setCustomName(monsterType.getTypePrefix() + ChatColor.WHITE + " Slack");
enderman.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(CalculateAttribute.health(monsterType, playerLevel));
enderman.setHealth(CalculateAttribute.health(monsterType, playerLevel));
enderman.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE).setBaseValue(CalculateAttribute.damage(monsterType, playerLevel));
enderman.setCustomNameVisible(false);
enderman.spawnAt(location);
}
}
;
public static void SummonMonster(Monster monster, Location location, MonsterType monsterType, Player player) {
switch (monster) {
case WYAX -> WYAX.summonWyax(location, monsterType, LevelManager.getLevel(player));
case SLACK -> SLACK.summonSlack(location, monsterType, LevelManager.getLevel(player));
}
}
}
Could someone explain to me why this won't work? I did try abstracting it which would work, but it required me to add every implemention into every enum variable and well that's just dumb because they would be doing nothing.
Hello there! I am learning all the events and such, so I'm working on the PlayerDeathEvent right now. I am wondering what way I can get the item that was used to cause the killing blow. I have tried a few things like killer.getItemInUse() (where the killer is the event.getEntity().getKiller() Player object). I have tried to google it but answers are from ~2012 and are telling me to use a deprecated function getItemInHand(). Any suggestions?
?paste
@zenith gate
Get their inventory then equipment then main hand
That's a good start, thank you! Will try to figure it out! ❤️
so I got a question about my project structure
If you have a question, please just ask it. Don't look for staff or topic experts. Don't ask to ask or ask if people are awake or available. Just ask the question to the channel straight out, and wait patiently for a reply. Make sure you use the right channel regarding the topic of your question. Create a thread in case the channel is already in use!
I am literally in the middle of typing
im just used to many short messages
if I wanted to add custom abilities to weapons id essentially make a package to hold them and then class for each one of them?
organization is up to you
Don’t implement it like that
I wouldn't use an enum here
I should just put them in their standalone methods? I also want the monsters in a nice list for when I do commands, and I have that setup so I could just add a monster to the enum, and the command will see that and can now summon that monster. An enum just seemed to be the best option.
How can i disable fire charges shot via dispenser from setting fire?
whats the event that i need to cancel?
BlockDispenseEvent? not 100% sure tho.
👍
how to do I make external classes do stuff like in main class?
is dependency injection enough?
You use inheritation for the common things
Where you will have a super a clase and then each sub class inhertitate from the super
I made this so far in this class, and idk if I should do anything else
the given solution may not work if the killer used a bow, since a bow might be in either main hand of off hand (or neither, if the killer switched their hands inbetween shooting and killing). this also wont work for any entity, just players.
if you want it to work for any entity killer:
you can get the last damage cause
if the damage cause is an EntityDamageByEntityEvent get the damager from said event
if the damager is a projectile, check if its projectilesource is an entity
if not, the damager itself will be what might have killed them. then you can get the item in their hand
mind you, this will not account for entities that die from non-entity causes. if you hit an entity and they die from fire ticks for example the last damage cause will be of said fire ticks, so that might not work entirely. You can solve this by keeping track of specifically the last EntityDamageByEntityEvents an entity took, and also probably at which time that occurred so you can decide when such an event should no longer be responsible for somethings death
like the first solution, it also wont work entirely for getting the bow used to shoot the entity since entities and players can switch their bow slot away between shooting and hitting, so one way to resolve this would be to map the projectile UUID with the ItemStack bow (which you can do in a EntityShootBowEvent listener) and then you know what item was used to shoot which projectile
of course, remember to clear out the entries of these maps when you no longer need them
are you just trying to access your plugin instance from other classes?
@storm crystal
im trying to make stuff in other class than main
what exactly?
discord be dyin again it seems
yeah it took me 15 minutes to just load in on my computer. servers are at capacity is what it screamed at me
I have this code, but runnable will only run one time correctly. After I add data to set, that set is empty in runnable any case why?
Other class where Im adding data to set:
System.out.println("CRYPTO MENU LIST: " + cryptoManager.getCryptosGuiPlayers());
cryptoManager.getCryptosGuiPlayers().add(guiPlayer.getUniqueId());
System.out.println("crypto added: " +cryptoManager.cryptosGuiPlayers);
System.out.println("CRYPTO MENU LIST AFTER ADD: " + cryptoManager.getCryptosGuiPlayers());
Class with runnable:
public class CryptoManager {
public Set<UUID> cryptosGuiPlayers = new HashSet<>();
public CryptoManager() {
cryptos.put(PCCryptoType.BTC, new Bitcoin());
cryptos.put(PCCryptoType.ETH, new Ethereum());
cryptos.put(PCCryptoType.DODGE, new DogeCoin());
this.saveStartValues();
this.startRunnable();
}
private void startRunnable() {
int interval = 10; //in seconds!
new BukkitRunnable() {
private final Set<UUID> a = cryptosGuiPlayers;
@Override
public void run() {
final Random random = new Random();
for (CryptoCoin coin : cryptos.values()) {
double epsilon = random.nextGaussian() * random.nextInt(0, 10);
double minusChance = random.nextGaussian();
if (minusChance < 0.52)
epsilon *= -1;
coin.setValue((float) (coin.getValue() - epsilon));
historyCryptoValues.computeIfAbsent(coin.getId(), k -> new ArrayList<>());
historyCryptoValues.get(coin.getId()).add(coin.getValue());
System.out.println("NEW VALUE " + coin.getId() + ": " + coin.getValue());
}
System.out.println("Test: " + this.a);
System.out.println("Test: " + new HashSet<>(this.a));
System.out.println(cryptosGuiPlayers);
for (UUID playerUUID : new HashSet<>(cryptosGuiPlayers)){
System.out.println("remove : " + cryptosGuiPlayers.remove(playerUUID));
Player player = Bukkit.getPlayer(playerUUID);
if (player == null) continue;
if (!player.getOpenInventory().getOriginalTitle().equalsIgnoreCase("Cryptos")) continue;
new PCCryptoMenu(player).show(player);
}
System.out.println("---");
}
}.runTaskTimer(RPComputer3.instance, 20L, interval * 20L );
}```
Output:
listeners
Okay well when you create your file and implement listener.
in your main class in the onEnable() you just register that event. getServer().getPluginManager().registerEvents(new FILENAME(), this) then that event will be registered.
your methods you can get easily by just FILENAME.METHODNAME() if they are in other files.
make sure you make them public if you want to access it outside the current class
But I guess if I wanna use the EntityDamagebyEntityEvent, I have to then calculate if that damage is going to kill the damagee, because this event is called just before the damage is being dealt right, so the event itself won't tell me if it's a killing blow?
Yes
you dont have to stop using an entitydeathevent, you just use it alongside that damage event so you can more accurately guess which attack killed an entity
if you solely want to count entity killing blows then you wont need to do this, if you want to account for causational deaths (like burning to death after the fact or being thrown off a cliff) then this is handy
basically all you do inside that damage event listener is mapping it to an entity and recording the time at which that event was taken, nothing else
Ah okay that does seem a bit easier 😄
then in the death event you check if that entity is recorded, and check if the time at which that damage event was taken is sufficiently recent enough to be considered
and then you got the accurate entity damage event which caused the entity to die
two hashmaps should do it
Oof that's a variable type I haven't heard of
or alternatively make a little record containing the damage event and time and then 1 map will do it
a hashmap is basically just a key:value pairing
sometimes called a dictionary
Oh a dictionary
hey so just to be clear, BlockDropItemEvent#getBlock() always returns an AIR block?
i coulda sworn that wasnt the case
Does it run before or after
how do I access method from main class in another class
?di
Guide to dependency injection: https://www.spigotmc.org/wiki/using-dependency-injection/
did I do something wrong
doesnt look like it to me
its just yellowlined like that because its a variable you're not yet using
cause it gives me this
playerCustomDamage is not a method
huh
its a double
you're supposed to do new BoneAbility(plugin, damage)
wait no
what are you doing
I got it in main class
I thought I should specify what type it gives back in here as well
thats in your main class?
yes
then you should be doing plugin.playerCustomDamage(..., ...)
assuming you're in BoneAbility rn
yes
playerCustomDamage you've made a behavior of your main class. it probably shouldn't be there, but good practice comes later. but because you've made this method a behavior of your main class you need an instance of your main class to act out that behavior
wasnt doing instance of main class bad
Creating a new instance of it would be bad
yes
but you'll find that out if you try it anyway, because itll throw an error saying you cant make another instance of your plugin main class
No code block
You're trying to get the config before plugin is set
Ain't the plugin set when I'm creating the class?
Fields get initizalized first then the constructor runs
so then getConfig is called plugin isn't initialized
Ah, any fix for this?
move that get config to the constructor
Alr, thanks
like this?
Main and Javaplugin are the same thing
yeah you dont need to literally make a main class
your main just refers to your application's starting point
for plugins thats your JavaPlugin class
have you removed your playerCustomDamage() method from your JavaPlugin class?
whats javaplugin class
[15:01:55 ERROR]: Error occurred while enabling Toastart v1.0.4 (Is it up to date?)
java.lang.IllegalStateException: Unable to find a resolver for parameter type class org.bukkit.Location
at revxrsal.commands.core.CommandParser.getParameters(CommandParser.java:436) ~[Toastart-1.0.4.jar:?]
at revxrsal.commands.core.CommandParser.lambda$parse$4(CommandParser.java:197) ~[Toastart-1.0.4.jar:?]
at java.util.ArrayList.forEach(ArrayList.java:1511) ~[?:?]
at revxrsal.commands.core.CommandParser.parse(CommandParser.java:168) ~[Toastart-1.0.4.jar:?]
at revxrsal.commands.core.CommandParser.parse(CommandParser.java:121) ~[Toastart-1.0.4.jar:?]
at revxrsal.commands.core.BaseCommandHandler.register(BaseCommandHandler.java:188) ~[Toastart-1.0.4.jar:?]
at revxrsal.commands.bukkit.core.BukkitHandler.register(BukkitHandler.java:148) ~[Toastart-1.0.4.jar:?]
at pine.toast.toastart.Toastart.onEnable(Toastart.java:31) ~[Toastart-1.0.4.jar:?]
at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:281) ~[paper-api-1.20.2-R0.1-SNAPSHOT.jar:?]
at io.papermc.paper.plugin.manager.PaperPluginInstanceManager.enablePlugin(PaperPluginInstanceManager.java:189) ~[paper-1.20.2.jar:git-Paper-234]
at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.enablePlugin(PaperPluginManagerImpl.java:104) ~[paper-1.20.2.jar:git-Paper-234]
at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:507) ~[paper-api-1.20.2-R0.1-SNAPSHOT.jar:?]
at org.bukkit.craftbukkit.v1_20_R2.CraftServer.enablePlugin(CraftServer.java:644) ~[paper-1.20.2.jar:git-Paper-234]
at org.bukkit.craftbukkit.v1_20_R2.CraftServer.enablePlugins(CraftServer.java:555) ~[paper-1.20.2.jar:git-Paper-234]
at net.minecraft.server.MinecraftServer.loadWorld0(MinecraftServer.java:627) ~[paper-1.20.2.jar:git-Paper-234]
at net.minecraft.server.MinecraftServer.loadLevel(MinecraftServer.java:424) ~[paper-1.20.2.jar:git-Paper-234]
at net.minecraft.server.dedicated.DedicatedServer.initServer(DedicatedServer.java:308) ~[paper-1.20.2.jar:git-Paper-234]
at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1086) ~[paper-1.20.2.jar:git-Paper-234]
at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:315) ~[paper-1.20.2.jar:git-Paper-234]
at java.lang.Thread.run(Thread.java:833) ~[?:?]
theres an error but no class name or line count for my plugin?
yes your main class but not literally your "Main" class
no its still here
whichever one of your classes says extends JavaPlugin
yeah Main.java is that one
wuh?
oh i see
no you literally passed JavaPlugin to your constructor
JavaPlugin doesn't have the playerCustomDamage() method
not really extremely urgent but just a reminder for you
Any idea why this is showing up rn?
?main
?jd-s
so use main.playerCustomDamage() and just remove the JavaPlugin part of your constructor
you need to learn more java
you can't have an if statement outside of a method
Just forgot.. I'm learning this way, duh.
how come so many beginners jump to putting developer and all sorts of languages in their bio when they literally just started lol
wait
you're not a developer bro you barely started touching java
I got fucking lost
I renamed my Main.java with JavaPlugin extension to Rpg now to make it less confusing
no clue I've never gotten that, its like if I said i'm a Haxe, C, C++, Lua, HTML, CSS, Javascript, SQL, React, C#, Rust developer because I've used those tools once I'm just not proficient
mb forgot rust
im a c++ developer fellas i touched it like once when i was 13
and i got scared
am an assembly developer too because i read an article about it one time
Oh forgot x86x64, x86, MIPS, ARM
how come you've worked in C# and didnt know if statements cant be outside of method
I've touched assembly for those processor architectures
anyway what do I do now to access customPlayerDamage from Rpg class again
brainfuck dev for 30 years of experience
Brothers, why be mad bout it? I just didn't program in Java for a long time, I tend to do more Lua these days - just returned to Java for some plugins for Minecraft and y'all be trash talking me just cause I touched objects after a long while
we're just poking fun lol
ah, alr, seemed like y'all were hatin on me :(
if thats poking fun then I must have become a swiss cheese by now lol
wait so when do I want to pass JavaPlugin and when I want to pass main class instance
like, think of it like this. Rpg is your implementation of the JavaPlugin class, JavaPlugin doesn't know about your customPlayerDamage() method, Rpg does. If you put JavaPlugin in your constructor you can pass Rpg into it because Rpg extends JavaPlugin, but unless you then cast that JavaPlugin to Rpg you cant use the behaviors that Rpg has
because it doesnt know JavaPlugin is an Rpg yet
like, JavaPlugin is a Fruit but Rpg is an Apple. All apples are fruits but not all fruits are apples. Apples know how to roll() but Fruits might not
thats my baby way of explaining that lol
That's a nice way of explaining tho, good work
which btw that allows me to explain the difference between static and non-static. static variables you can see as the properties that belong to that class in general, static methods are behaviors that apply to the class in general. non-static variables are properties that belong to only the instance of that class and likewise non-static methods are behaviors only that instance has. take for example
Apple {
static boolean hasRotten = false;
public static void setRotten() { hasRotten = true; }
}
when you call Apple.setRotten() suddenly all apples are rotten, might not be what you want
but
Apple {
boolean hasRotten = false;
public void setRotten() { hasRotten = true; }
}
now you cant call Apple.setRotten() because its not static, instead you do
Apple apple = new Apple();
apple.setRotten();
and now only that apple is rotten, you're still free to make new apples which wont be rotten
Does anyone know whether Jitpack still works if I have my own publishing logic - if so, what are the constraints?
Save yourself the trouble and use github actions with github packages
500MB free limit but 🤷♂️
Well if it'd be that easy I'd publish straight to mavenCentral :P
But alas, I'm PR-ing build logic changes to a repo that is deployed using Jitpack - don't think I can change that anytime soon as the Anti-Jitpack movement is rather limited in the relevant community
Though, isn't github package the absolute of the absolute dogshit given that it requires a GH account and extensive manual configuration?
not sure
why does it do action twice?
triggers once for main hand and once for offhand
you need to filter for one hand specifically
Wasn't there like ?interactevent
?interactevent
The PlayerInteractEvent may be called once per hand. If you only want code to be executed once, you can check the result of https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/player/PlayerInteractEvent.html#getHand(), then decide functionality.
For example, only executing code if the main hand was used:
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getHand() != EquipmentSlot.HAND) { // * if the hand used is NOT the main hand:
return; // do not progress past this point |
}
// provide functionality
}
/**
* A Node that links a structure together
*/
public record StructureNode(StructureNode north, StructureNode south, StructureNode east, StructureNode west, StructureNode up,
StructureNode down, UUID world, int blockX, int blockY, int blockZ) {
}``` can't wait to write a traversal for this one
anyone have tutorial on cooldowns? I forgot their name
the ones that can make something be done every few secs and such
u can use timestamps
its fairly easy, do you want me to show it to you?
I essentially want to spawn armor stand on action and after a few secs make it disappear
?scheduling
if you don't want an active animation you can do it lazily
oh scheduling is perf for that then
see link above
okay, also you got a link for spawning armorstands and changing their position item in hand etc.?
declaration: package: org.bukkit.entity, interface: ArmorStand
Bukkit#spawnEntity and then cast to ArmorSTand
^ don't do that
Use the spawn method that accepts a consumer if you plan on modifying the entity
modifying entity and then spawning it
vs
spawning entity and modifying it
ahhh I didn't see the consumer method
also another correction its World#spawn(Location, Class, Consumer)
I dont think I am implementing it correctly lol
you'
re not in a method
Keep in mind the order of execution
oh I just realized the runnable is just out of order as far as conventions not a scope error
That code will work fine if you fix the variable type and the plugin variable
though I wouldn't recommend starting a runnable on object creation
.
initializing plugin is literally above it
runTaskLater is called before the constructor
how
unlike languages like python the order in which you place the code doesn't really matter in the global scope
e.g.
okay so how do I make it later than constructor
why do you even need the runnable
to make spawned armorstands disappear after like 4 secs
Uh, onEnable()?
you seem to have missed the context
there was one method with lambda (idk what it is) so I picked that one
Well I only saw "init plugin" and "after constructor"
yeah plugin is their variable
I passed it from main class
Well once you have the actual plugin var you can just use the scheduler to init stuff on the first tick
It's fucking horrendous but it works ™️ (but - don't use this to init Vault or similar)
Well you haven't done anything I've asked of you so 🤷♂️
I fail to see what the problem is
Missing basic Java knowledge is the problem
You initialize a variable that you defo shouldn't have
it literally says "just fix it lol"
look at the runnable its being made before the plugins initialized
??
BukkitRunnable is ALWAYS a huge red flag. Period and there is no exception
Same goes with new Runnable()
idk man its literally my first time working with that kind of shit
eh it's fine if you want to extend it
This beginner Java tutorial describes fundamentals of programming in the Java programming language
It isn't. There is always a better (read: saner) option
is there any event called when Block#breakBlock() is called?
cant be BreakBlockEvent because no player is involved
why is it even a thing, being initialized before constructor does anything
code order doesn't matter scope does
fields are initialized before a constructor runs
no matter where in the code your classes field is
is there a way without doing all of it
You can init your field in the ctor
However, I don't think you actually want that anyways
^^
no I mean doing something after X time elapsed
but I'm honestly done spoon feeding here
How will you get your Amourstand instance from that runnable then?
idk why armorstand would even have an instance
havent worked with them yet
Uh, like how do you want to tell bukkit that you want to kill this amourstand and not the other one
idk yet why is that even important
basically everything you see in minecraft is an instance of something
Honestly, you probably want to have this be a task that runs periodically in the background, purging all amourstands that are too old
Well it's an object oriented language so a lot of things are instances
no not really
Otherwise you may run into issues with server restarts and other funsies
but fuck those armorstands for now thats totally out of the point
Kek this asking for helping is just looping back around to the basics of java can answer most of ur questions
I wont even think about them if I cant make delay at all
this
The delay thing would be super easy if you have a task that runs every tick and you store the timestamp of the creation of the entity in it's PDC.
Then in your task you iterate over all entities in the world and check if the PDC entry is there, and if it is if it is too old.
still boils down to setting a plugin field or whatever it is separately despite the fact that constructor exists and I literally have the plugin initialized in scope
so intellij just throws an error
Uh, and what prevents you from initializing the field in your constructor?
well, its already here
I'm going to write something very useful out whether or not you pay any attention to it is whatever I don't care anymore this is a continued sensless discussion
Right now the assignment happens outside the constructor
I got a static hashmap in my plugin1, once i use the plugin1 as a depedency in another plugin2, the hashmap is null, even though its being set on the start of the plugin1 with the hashmap. Why is it null once i use it in another plugin2?
Are you accidentally shading it
So basically something like (warning: pseudocode, I have no programmed with bukkit/spigot for well over a year now)
Bukkit.getScheduler().runTaskTimer(JavaPlugin.getPlugin(MyPlugin.class), () -> {
for (World world : Bukkit.getWorlds()) {
for (AmourStand e : world.getEntitiesByClass(AmourStand.class)) {
PersistentDataContainer pdc = e.getPersistentDataContainer();
Long time = pdc.getOrDefault(expiryTimestampKey, PersistentDataType.LONG, Long.MAX_VALUE);
if (time < System.currentTimeMillis()) {
e.kill();
}
}
}
}, 10L, 10L);
me?
Ye
i dont think so, i will look into this
what does it need to be, is it supposed to be shaded ?
Check the scope is provided for maven or compileOnly for gradle
scope is provided
Java loads a class in order
- Static Fields
- Static Initializing Blocks
- Fields
- Constructor
While I missed some nuanced examples this is basic enough for now.
public class ExmpleError {
private final MyPlugin myPlugin;
public ExampleError(MyPlugin myPlugin) {
this.myPlugin = myPlugin; // myPlugin is initialized in the constructor not a field
}
private BukkitRunnable runnable = Bukkit.getScheduler().runTask(() -> thing, myPlugin) // this will cause an ERROR because fields are intiailized BEFORE the constructor so myPlugin is null
}
as you see in the example no matter the order FIELDS are initialized before the constructor. The runnable can't use myPlugin because it is still null.
even though you set it to myPlugin in the constructor java couldn't give 2 fucks seeing as it only intializes the fields first and as far as java is conerned at this point your class looks like below
public class ExampleError {
private final MyPlugin myPlugin;
private BukkitRunnable runnable = Bukkit.getScheduler().runTask(() -> thing, myPlugin) // this will cause an ERROR because fields are intiailized BEFORE the constructor so myPlugin is null
}
Java doesn't even care about your constructor only once the constructor is run does java begin to factor in the value you assigned myPlugin to. As you see within the field MyPlugin myPlugin it has yet to be assigned a value
And check plugin1 has a depend in plugin2 so plugin2 loads after
sobbing
uninitialized not null but yeah
as far as intensive purposes go its Null easiest way to think of it
The main difference is I'm uncertain if you can compile when using an unitialized field like that
You can't
i dont know what i did but it works now, thanks :)
@hushed spindle Big thank you mate! I managed to make it work!
https://i.imgur.com/avwTzlO.png I now have a log of things that happened 20 seconds ago and can find what the last player did to the dying person!
that's enough for me there though
so for plugin I just do JavaPlugin.getPlugin(MyPlugin.class) but for what I have in my plugin?
epiiic nice job
you didn't even listen to what either of us said
Copy paste is easier so they went that route
Hm? JavaPlugin#getPlugin is a nice hack that allows to obtain any plugin instance as long as the plugin is already initialized
you essentially ask me to initialize a field but tell me that a) constructor wont work b) initializing a field wont work
instead of putting the runnable in a constructor they resort to hacks because they refuse to understand the concept of intialization
No one ever said a constructor won't work
I only asserted that assigning fields outside the constructor (or other methods) isn't great
https://www.w3schools.com/java/java_constructors.asp constructors are used for intialization
please learn about constructors above ^
Hey - it's a hack that even I use
I'd say that's worse than BukkitRunnable
just use static instance plugin is a singleton
Though uh, I don't use it when it is performance-sensitive but generally you only need the plugin instance for one-off things so whatever
Yeah sure. I do agree
But whatever
if I have an interface
unless you're diehard DI
should've told me earlier to put it inside a constructor 😭
and a data class impl an interface, do I name it like DataImpl?
without all the unnecessary hassle
We did
I think I did multiple times
^^
For example
We're trying to get you to learn instead of spoon feeding you
but you seem to not want that
you can use whatever naming convention you want, just stay consistent with it. usually I go with SimpleData or something along those lines, but at the end of the day its up to you. Or if your implementation is abstract you can do AbstractData
give me an example of what your impling
cuz sometimes their is something more specific you can use too
?conventions
public interface CustomCharacter {
@NotNull CustomCharacterInformation getInformation();
@NotNull ArmorEquipment<@NotNull CustomItem> getArmor();
@NotNull List<@NotNull CustomItem> getItems();
}
public class CustomCharacterImpl implements CustomCharacter
no?
java calls it record convention
alr
or whatever
oh is that the conventions for java 9
its just a convention that most people follow for Java, whether you choose to use it or not is up to you. But if you don't follow it, just be prepared for all kinds of people to not like it 😉
no clue
but you can't change it so I'd assume its a convention
is there a way to make scheduler conditional?
lmao name the variables getName
?scheduling
sounds terrible
yeah but when i got it like that it will just do it once when server is enabled
Yeah
Yeah, runnables don't run when the server isn't yet ticking
idk if its just me but do the bukkit runnables violate srp
Wha? Could you peeps stop inventing funny bullshit acronyms for "sane code"
Single Responsibility Principle
so uh is there a way to make it not work until i tell it to?
or will it always run regardless
Single Responsibility Principle from SOLID is pretty well known I feel like
Dusk do yourself a favor and go through a few Java courses
You're just wasting your own and our time
They don't need to
because if you understand the fundamentals you'd also understand how methods are called and what the scheduler actually does
yeah but getting stuck in front of black console trying to get desired input is kinda blunt and boring
almost every problem I've seen you have is because you lack an understanding of Java fundamentals
do yk what a lambda is dusk
You seem to be ignoring us when we try to explain stuff
wavelength
and instead you only want the answer
the fact that I dont answer to everything doesnt mean that I dont read it
Bukkit Runnables is just an extension of Runnables which comes from the Java API
and yes java courses will teach you about runnables
so how come we always end up in a loop of the same question
Like we told you multiple times how to solve the problem
it is weird they are having this much problems with Java considering they supposedly know another language
since when know equals to know everything
do you know what an API is?
you should if you know another programming language, the concept of an API isn't different because of the language
I think we are only past if and loops
if you know how to read an API for one language, it shouldn't be super difficult to read an API of another language
not really but I established that i dont need it
okay so when I want to access something from constructor that's like this.something = something; id just say something.whatever_I_need
but what about bukkitrunnable
python is more about functional programming, good news is that Java supports such things too
so it shouldn't be super hard to transition over 🙂
this is a special keyword
yeah but I cant just do this.BukkitRunnable
anytime you use this, it means you want to reference a variable that was declared in the class and not the variable in the method
variables in classes can come from a parent class too, which happens if you extend something
||Let's not introduce them to OuterClass.this though||
lol
I mean okay I got this and how do I access this outside in some method, like I know of scheduler.runTask but idk what to type in field of BukkitRunnable
like it doesnt really have a special name or anything like that
RTFM
If you have:
public class OuterClass {
private final JavaPlugin plugin;
private final BukkitRunnable runnable;
public OuterClass(JavaPlugin plugin) {
this.plugin = plugin;
this.runnable = new BukkitRunnable() {
@Override
public void run() {
// Do stuff here
}
};
this.runnable.runTask(this.plugin); // In order to start the task on the **next** tick
}
}
this method creates an anonymous inner class. If you want to instead be able to invoke the run method at a later time, you either create an inner class for it or you create its own class that extends BukkitRunnable.
depends what you need really
Of course, in this circumstance you might eventually see the need for ||OuterClass.this|| but I believe it's best to hide the existence of that feature until absolutely necessary as I think I'd be confused as heck if one were to introduce me to this feature 4 years ago
Yeah, it's best to have it be it's own class
lol
Of course you could also use Local classes but that is another thing done rarely
i feel like it makes quite alot of sense if you understand Anonymous classes
It makes sense, but only once you know that the constructor of anonymous classes isn't what it says they are
You need to invoke the method runTaskLater on the BukkitRunnable, not on the Scheduler
So instead of Bukkit.getScheduler().rtl(plugin, runnable, delay) you have runnable.rtl(plugin, delay)
like that?
Yeah
Although, uh honestly given in the context of folia I don't think that makes much sense but whatever - Folia is a large rewrite regardless of this
just fyi, that math will make it run 1500 ticks later
Huh`
I don't think 30*20 is 1500
30*20 is 600, no?
which is like 75 seconds
Which is like half a minute
it's literally 30 seconds
fyi I may not be the smartest
no clue what you're on
but I know my maths
what sin of 2 deg off ur head rn
bro went from the army to re-learning his abc's
for some reason I saw it as a 5 and not a 2 XD
isn't the cos of 45deg like 0.767
ok sin of 0.15159
I always rounded it to 0.7
I thought it was like 0.707
So it probably is closer to 0.71
idk I only remember this stuff was cause I was tryna understand spherical vectors
I remember I was in 8th grade wondering if there was a formula for the sin function I didnt know it was an algorithm 💀
I was looking for trigonometry back like on 6th grade
I was like
"if I had an angle and a vector length couldn't I calculate the 2d positions"
turns out
it's called cos and sin
U were not thinking about that in 6th grade
I was
Same - this is why I remember this thing as 0.7
my man I've been making plugins for like 7 years now
yes, coll, I'm 18
bro if I knew it was so fucking easy 😭
now make a cooldown for the cooldown message so it isn't spammy
Does that cooldown also get a cooldown
I was too wow I'm so old
Wtf
still amateur
Damn you're old
fossil
I am ahead of all of you: I already quit making plugins
Damn he's a pro
It's been a while since I made a plugin
it's been a while since I genuinely had fun in this industry
Oof
is it possible to add a keybind component to a line of lore
but presumably it can be done via nms
Yes
thank god
bros avoiding adventure
Paper
The only good reason to use paper
Yeah the adapter is pretty useless, I wonder why it exists at all
hook bukkit developers on the components so they switch to paper
Even for that it isn't great
😳
I will never switch to paper
I would only switch if spigot were to fully die and become unmaintained which is an unlikely event
at that point I will have no choice but to take over CB
when creating a new plugin on intellij
should i just use the minecraft plugin creator plugin
lol I have more fun working on the server now adays anyways lol
or a plain gradle project?
intellij mc plugin sucks iirc its memory leaky
whatever u find easier
@tall dragon idk u so i dont trust u
lol
guys how can i register a command?
o.O
idk u so I don't trust you so I cannot answer
sorry i dont know you, so it must be a virus.
