#help-development
1 messages Β· Page 835 of 1
I'll make sure to avoid that then
ok that makes sense
More than one usage means im creating a new variable.
I dont make exceptions there.
I just assign all variables at the top and re-use them whenever
one of the worst things about java is that heap allocations are a byproduct of virtually all meaningful work
Yeah except for multithreading where u sometimes want the up to date value every call
it's so gross
So that if I want to use it again I don't need to refactor
go write RustySpigot
call it Plumber or something
Faucet
did you see that imlucid denied evolution
isn't it funny we worked for that guy
and took it seriously
π
Well
Bro got depresso and canceled the entire project
I don't think I've been paid for it more than once
I did sell some minigames
for $$$
damn
made a couple grand on top of the couple grand I was paid to write them
I had a few preexisting minigames I wanted to sell and put into use somehow but they were old and riddled with issues
mm
I don't remember what I got paid but I think I settled for less because I was excited to work on a minigame core
what project
eH
and then quickly became unable to work on it because of mental health
could've done your research :)
I based my entire core around minikloon's state system
think yours was just a bunch of kit logic
I mean sure but what they paid is reflected in what they got
I don't doubt it
it might still come out of the dead
I wish they'd had me write a minigame alongside it instead of the core first
whenever I try to build an abstraction in a vacuum it ends up not working very well
I need to adapt it alongside an implementation of its use case, and this has proven itself time and time again
I'm working on some minigame infrastructure stuff rn, might resell it to him
he's trying again?
well no
But I did tell him about the idea a few months ago and he was super interested in buying it
and told me that the project might be restarted in ~6-8 months
well it's been 6 months
nice
hope you get in touch with him and make bank off the loser
you might be able to find a better buyer though
I'm not doing exclusive reselling I'll prob resell my stuff like 5-6 times
if I were to make a really good core I'd probably just open source it
I'm not just making a minigame core
like this?
that's the least of my concerns
Reuse variables
I would want to abstract every part of minigame development
lol
in order to get a feel for it I'd probably want to write a few minigames first, then start building abstractions around it and retrofit them into the existing games, and slowly build higher and higher level abstractions to target problematic areas that have a lot of boilerplate
yo so uh
going to be writing the entire infrastructure and sell it as a package
boxbeam i tried to abstract my plugin into like
oh hi good timing
a bunch of configs and stuff and it just seems rly unneccessary
You dont actually use the future here...
lmao just noticed
what do you mean
looks very cool
so you're trying to make the full package, front to back
Yep
could spawn a lot of minigame servers
it just looks like a ton of work and I just wanna add my custom items
And a solid minigame core that lets me make a minigame in like a day
I'd be very interested to see how that plays out
wtf am I saying with a week it takes like 2 hours rn
lol
Worst case scenario I just spin up my own bootleg network
And try to fit 800 people in a single dedi
hmu if you do set that up
I'd be interested in trying to write a minigame in your framework and making something for your server
gotta rewrite half of it but I'll make it work out
ok but what did you actually do
Btw you should probably reduce your nesting my refactoring the codeblock into a method and referencing it with
CompletableFuture<Profile> future = CompletableFuture.supplyAsync(() -> loadProfile(discordId));
It gives your anonymous method an actual name and makes it more readable by adding secondary information.
I also gotta work on my skyblock core :p it'd allow me to do player housing n stuff
you're not showing us any code or getting specific
but you said you abstracted it and made it very config based
oh I tried but it just seems so like dumb lol
sop instead of 1 method threes 2
ill need a config for every item, and descriptions for every item, then ill need a config for the character the item belongs to
yeah p much
Yes. π More methods = More information => results in comments being less needed
no
so
I made a dc bot and I had this config system where it's very easy to get configs Repository#getConfig(Class) kinda like that and it's easy to register them too

All fun and games until you have multiple copies of the same config for different stuff
For example, map files

i really hate methods that jump around a lot
it makes it harder to read code form e
ok, can I see what the code for that looked like?
symlinks π
That is counter intuitive. If your methods have proper names, then you can read your code like a book.
You should be able to inferr what your method does by its name, making you read one word instead of 30 lines and having the same understanding of your code.
public interface ConfigService {
void loadAndRegister(@NotNull Object config) throws IOException;
<T> @NotNull T get(@NotNull Class<T> configClass);
@NotNull List<@NotNull Object> getRegistered();
void save(@NotNull Class<?> configClass) throws IOException;
boolean isSaved(Class<?> configClass) throws IOException;
boolean isRegistered(Class<?> configClass);
}
I used generics dw but this was what i copied
ok, so is it using reflection to load config values or something?
gson
im looking at the image that imillusion sent and i have no idea whats going on
gotta verify
iok here
?verify
For example
public Profile loadPlayerProfile(String profileId) {
You dont need to care what the body of this method looks like. You give it an ID and it returns a Profile. Thats all you need to know.
!verify
Usage: !verify <forums username>
and i aint doing allat to msg staff to change my dc
@Config(name = "StartUpConfig")
public class StartUpConfig {
@Mandatory
private final String token;
private final String motd;
public StartUpConfig(String token, @Nullable String motd) {
this.token = token;
this.motd = motd;
}
@NotNull
public String getToken() {
return this.token;
}
public Optional<String> getMOTD() {
return Optional.ofNullable(this.motd);
}
}
and here's an example
yeah that looks really nice
thanks
and then a method loadplayerprofileasync
that returns completablefuture
then I would do this: configService.loadAndRegister(new StartUpConfig(null, null));
now that I think abt it
well no because they have different values
I might remove the constructor parameters
yeah
but
then you could set defaults in the class
ye
For me it is kind of clear. The method associate is just a bad name.
Thats why you need really descriptive method names.
that's what I was gonna suggest
store what
like a base custom item class that stores all the regular properties
no lol
and some optional meta which can be a subclass attached to it only for items that need more special properties
so every item has special properties like that?
this is what a custom character is lookin like rn
in that case, a class per item sounds pretty standard - the only real alternative would be to pass around lambdas for any overridable functionality
public class KnightCharacter extends CustomCharacter {
public KnightCharacter() {
super(
new CustomCharacterInformation.Builder()
.setVerse(CharacterVerse.CLASSIC)
.setReferenceName("classic_knight")
.setDisplayName("Classic Knight")
.build(),
new CustomArmorEquipment.Builder()
.setHelmet(() -> new CustomItemBuilder(Material.IRON_HELMET, "classic_knight_helmet")
.setName("<gray>Knight's Helmet")
.setLore("<gray>Just a good old knight's helmet.")
.build())
.setChestplate(() -> new CustomItemBuilder(Material.IRON_CHESTPLATE, "classic_knight_chestplate")
.setName("<gray>Knight's ChestPlate")
.build())
.setLeggings(() -> new CustomItemBuilder(Material.IRON_LEGGINGS, "classic_knight_leggings")
.setName("<gray>Knight's Leggings")
.build())
.setBoots(() -> new CustomItemBuilder(Material.IRON_BOOTS, "classic_knight_boots")
.setName("<gray>Knight's Boots")
.build())
.build(),
List.of(
() -> new CustomItemBuilder(Material.IRON_SWORD, "classic_knight_sword")
.setName("<gray>Knight's Sword")
.setLore("<gray>This sword could have some history",
"<gray>behind it.")
.build()
)
);
}
}```
hmm
at that point I feel like it's better to be able to load that from config or something
then you could write it out in a much more concise format
and define any special behavior separately in the code
This needs refactoring...
lol
like you could imagine it looking like this in config
Yeah so here's the thing
None of this needs to be set in code
You can make a parser and read all of these values from a config
characters:
Knight:
verse: CLASSIC
referenceName: "classic_knight"
display_name: "Classic Knight"
helmet: ...```
^
I think this looks better. Why is your method package-private?
i have my database in my manager class
its public in manager class
super epic not confusing
you could create a base class that is loaded from config which holds all of the regular properties of the character
But default values have to come from somewhere. π
so i dont have to have instance of manager and database when i need them
and then you could make a wrapper class that is passed the config and can specify any additional behavior
if there is no additional behavior it can just be the base class like Character or something
make a registry that stores them by their reference name in a Map<String, Character> and you're set
well it looks like you weren't loading these with the old config system
Wdym wasnt
you're using a builder
Oh I meant the one using gson
that could work
can gson convert to yaml?
if not, I have a config library which can
Well
I choose json cause snake yaml or whatever it's called looks kinda weird to use
And json looks fine with the pretty printint
probably annoying to configure by hand though
this works very much like gson, you won't have to touch snakeyaml at all
you just define your data and it will serialize and deserialize it automatically
ok so
well
when I end up having my configs
Do I pass in a ConfigurationSection, or a concrete class
like KnightBootsConfig
for red lib?
concrete class
the point of the deserialized object is to abstract away the config layer
and provide the data directly
only if they have additional behavior to define
again, there's no way you're getting overridden behavior per item unless you have a class per item or pass around lambdas to define that behavior
or somehow make all of that behavior expressible through config
sounds like dumb behavior. Why would it be beneficial to have a config for each item instead of deserialize one config into an array of items
I'm literally saying you don't have an additional config for each item
each item can be deserialized into a common config class storing all of the base metadata
and then you can attach additional behavior if you want to by either wrapping it in a class that defines that behavior or passing around lambdas
but even if you do define that additional behavior, you're not redeclaring the config logic, you're just reading the config data from variables
serialization has always been the source of way too much boilerplate
gotta get rid of it somehow
Yeah true, there is that aspect to not neglect
one of my favorite things about rust is that you can just slap a #[derive(Serialize, Deserialize)] on any type and basically be able to convert it to any serialization format
json, toml, yaml, xml, I think it might even work for sql
raw bytes
Oh yeah, but rust is just a chad language in general lol
fr
bro came back from the dead just to shit on java
I might have a class per item lol
That was the original plan
Maybe do it similarly to how mc does it, I mean that has its disadvantages also, but yeah just an idea
i got this code but it dosent tdo the breaking when its netherite i know its not because of the config because all the others work:
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockDamageAbortEvent;
import org.bukkit.event.block.BlockDamageEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitTask;
import uk.co.agwoo.zelrpg.Functions;
import uk.co.agwoo.zelrpg.ZelRPG;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
public class BlockDamageListener implements Listener {
private final Set<UUID> damagingPlayers = new HashSet<>();
public BukkitTask task;
public void onBlockDamage(BlockDamageEvent event) {
Player player = event.getPlayer();
ItemStack heldItem = player.getInventory().getItemInMainHand();
FileConfiguration config = ZelRPG.config;
if (Functions.isPickaxe(heldItem.getType())) {
int delay;
if (heldItem.getType().equals(Material.WOODEN_PICKAXE)) {
delay = config.getInt("timings.tools.pickaxes.wooden");
} else if (heldItem.getType().equals(Material.STONE_PICKAXE)){
delay = config.getInt("timings.tools.pickaxes.stone");
} else if (heldItem.getType().equals(Material.IRON_PICKAXE)){
delay = config.getInt("timings.tools.pickaxes.iron");
} else if (heldItem.getType().equals(Material.GOLDEN_PICKAXE)){
delay = config.getInt("timings.tools.pickaxes.golden");
} else if (heldItem.getType().equals(Material.DIAMOND_PICKAXE)){
delay = config.getInt("timings.tools.pickaxes.diamond");
} else if (heldItem.getType().equals(Material.NETHERITE_PICKAXE)){
delay = config.getInt("timings.tools.pickaxes.netherite");
}
else {
delay = config.getInt("timings.tools.pickaxes.wooden");
}
player.sendMessage(heldItem.getType() + "");
damagingPlayers.add(player.getUniqueId());
task = Bukkit.getScheduler().runTaskLater(ZelRPG.getInstance(), () -> {
if (damagingPlayers.contains(player.getUniqueId())) {
event.getBlock().breakNaturally();
}
damagingPlayers.remove(player.getUniqueId());
}, delay);
}
}
public void onBlockDamageAbort(BlockDamageAbortEvent event) {
Player player = event.getPlayer();
damagingPlayers.remove(player.getUniqueId());
if (task != null) {
task.cancel();
}
}
}```
Ehm
Every time the event is called, u just store the a new bukkit task
Is that intended? I mean you basically forget about the older ones
Wdym how mc does it
I pretty much meant how they structured their design after items, materials etc
Yeah how
one class per
I mean they have some sort of type inheritance such that there is a base/universal type all item subtypes derive
But yea
Damn whats this if else clause hell I'm witnessing
If it's one class per item, that is how I originally intended it to be
why not I be consistent with it
I mean sure, but on the other hand, dont overdo it and keep it simple
look at mcβs source
They keep their code open for extension
maybe I should make a core for this and have extension plugins
that is, youβll see some materials with custom classes, and some materials just represented with the base material class
Or well they call materials for items but you get the point :)
Should I do this
If you want
can someone explain why tf sometimes == or .equals() have different results?
if you dont want to explain just ignore it dont throw lernjavas at me pls
okay here is the rule basically
if A.equals(B) is true
then A == B should always be true
the converse is not necessarily true
A.equals(B) may be true even though A == B is false, this implies that there might be cases where different objects C and D are not the same (C != D) but their data/content is the same so C.equals(D) still holds true
okay, thanks :)
yeah
For instance if you do something like
A = new String("test".toCharArray());
B = new String("test".toCharArray());
then A != B is true or equivalently A == B is false
yet A.equals(B) is true
okay, yeah thats kinda confusing, i guess i need to adapt to .equals()
Whats the best way to make a multipaged chat answer?
equals() basically tests if two objects contain the same data
And if the two objects are the same object, then ofc the data will be the same
ok
Example?
Coreprotects lookup feature has multiple pages of information.
I have a similar query feature for my plugin
Well in the works
do u have an image or sth of how it looks? :>
Whats the best way to store the information so the player can run the command to go to the next page?
yes
oh image wait
1 sec let me boot up my test server
Here, its a query system, right now it just shows the 8 most recent ones (17-10) but I plan to add a pages system so I could see more (9-2 etc). What would be the best way to do this/store information?
I think you keep the pages absolute
And in the command you just provide the TUI if needed
(Like a next/previous/jump to, buttons)
Else ned, to calculate lines and pages etc, modulo usually works great :)
I think ill make like a /query fromindex command, for example if it goes 20-13, Iβll use a text component that does /query fromindex 12 (cause 12 is 1 less than 13) and it will go from there
Name for the class
like character as in person
yeah, but code wise the names can be different yk
And then when u display it to the end user, translate it back
Variable/object names dont really matter in java if youre the only developer
And you can understand what you meant
I mean itβs convenient not to use the names of classes that already exist in the java std library
do u think a "Person" is a good class name π
Sounds fine
nah im just override character
never rly seen the character class being used anyway
Maven CLI Invocation
how can I enforce something like this (getItem()) that the item has a pdc which contains a specific namespacedkey
public interface CustomItemProvider {
ItemStack getItem();
}
to rephrase, you want to enforce that the item returned by getItem has a matching pdc key?
I mean there isn't a way to do it at compile time, but at runtime, wherever you call getItem, just verify a key has been set
you could add the key yourself if you added another method to get the key, and then when you call getItem you add the key yourself
but that is more of a structural change
does Location#subtract mutates itself?
Yes
Opinions on an item abstraction API?
public class MyPhone extends CustomItem {
@Override
public ClickResult handleClick(Player player, ItemClickContext context) {
// The context is basically a PlayerInteractEvent wrapper
Menu menu = ...;
menu.open(player);
return ClickResult.PREVENT_ACTION;
}
@Override
public String getIdentifier() {
return "phone";
}
}

I could change all the clickresult logic to the ItemClickContext object
Or should I do something a bit more picky
@Override
public ClickContext getClickContext() {
return ClickContext.builder()
.limitTypes(ClickType.LEFT)
.entityPolicy(EntityPolicy.IGNORE_ENTITY_CLICKS)
.filter((player, context) -> player.isSneaking()) // shift-left click
.build();
}
Seems like I'm overengineering clicking
I made a custom intelligence system for my plugin
the code i use to update it (along with relevant feedback) is this
Score score = Objects.requireNonNull(Objects.requireNonNull(Plugin.getInstance().getServer().getScoreboardManager()).getMainScoreboard().getObjective("Intelligence")).getScore(p.getName());
if(score.getScore() < 1000) {
score.setScore(score.getScore() + 1);
Plugin.getInstance().getLogger().info(p.getName() + " damaged " + e.getEntity().getName() + ", gaining 1 Intelligence. Current intelligence: " + (score.getScore() + 1));
p.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("Intelligence: " + score.getScore() + "/1000", ChatColor.AQUA.asBungee()));
} else {
Plugin.getInstance().getLogger().info(p.getName() + " damaged " + e.getEntity().getName() + ", but they are at max Intelligence. Current intelligence: " + (score.getScore() + 1));
p.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("Intelligence: " + score.getScore() + "/1000 " + ChatColor.RED + ChatColor.BOLD + "MAX INTELLIGENCE", ChatColor.AQUA.asBungee()));
}```
this worked in version 1.20.1, but upon updating to 1.20.4 it no longer updates the score of the scoreboard, is there any reason as to why this may be?
this hurts to read
hello!
how to disable this inventory sort?
create a minimal test case and open a bug report
?jira
so, I'm trying to make a Placeholder in my plugin that changes every few minutes. but I don't know how to give it a timer.
basically I have a txt file with a list of things I want it to display and I want it to go to the next line of the file every like 5 minutes but I dont know how to setup a timer for it.
any help is appreciated!
please ping me when u respond!
declaration: package: org.bukkit.scheduler, interface: BukkitScheduler
i think this might help you
I think it might just be what I wanted. thanks!!
Is it possible to disable this auto-condensing in intellij?
I want it to look like this
At the top of the project files theres three dots clicl that go into the tree appearance and disable compact middle packages
hi why this keep giving me null?
this one exactly :
also the cosmetic data is there in the mongodb :
the players is also in the mongodb :
does anybody know how to invert world edit selection i want to make only some chunks/areas are avaibale other block/chunk will be deleted
do you mean like a plugin to do that or for a world edit tutorial
also tlauncher is spyware
I have:
Map<String, Object> serializedMap = itemStack.serialize();
String itemStackString = String.valueOf(serializedMap);
and i saved the string somewhere. Now i want to get "serializedMap" back, how would i do it?
That doesnt work
what
ik but what can i do i am poor ;-;
itemStackString returned {v=3578, type=DIAMOND_SWORD, meta=UNSPECIFIC_META:{meta-type=UNSPECIFIC, display-name={"text":"Teast@Teast"}, enchants={FIRE_ASPECT=2}}} so i think it works?
It might look like it works, but this is not how serialization works.
What is your original plan?
Save where and why
What data object does this String get written in?
yea uhhh tlauncher has a keylogger in it and moitors your web activity, steals ur passwords
toStringification is a one-way process, it's not supposed to be deserialized
ummmm anyway ;-;
typo in the field name maybe?
Debug your code all the way up.
Which format?
txt
i dont have any purchase also my pc is potato so i dont care that much ;-;

any way can you help me with world edit tho
any guides to testing plugins? idk what to use, mockito or mock bukkit, maybe both idk ?
There are other, better cracked launchers, just saying.
i made sure its the name!
i know that serialized stuff isnt supposed to be put in a txt file, but i really need a method that works with txt
Why
i will deal with that later but now i need help with world edit T_T
to store container data
Use the BukkitObjectOutputStream, create a byte[] with it, pipe it into a Base64 encoder to get a String.
Im guessing since its txt you wont need to edit it.
this is null for some reason :
Why not just use yml for this?
0.0;0.0;0.0@minecraft:chest[facing=north,type=single,waterlogged=false]@13@SPLITINDEX@{v=3578, type=DIAMOND_SWORD, meta=UNSPECIFIC_META:{meta-type=UNSPECIFIC, display-name={"text":"Teast@Teast"}, enchants={FIRE_ASPECT=2}}}
this is how it looks like full
yes i know its bad
Let me start up my IDE and show you how easy it is with yml
ik that it is easy
i can just use getItemStack with yml
Right, so then what is your argument for txt
This is how i use it :
because txt is compact
Why not use a raw binary file then?
cuz of filtering
If you're trying to save disk space txt won't help much
the files it generates should be used in plugin resource
You can disable filtering
What are you trying to filter?
I sure hope you wont filter files by their content, because that can get horribly slow, really fast.
resource filtering from maven
its not mine
Ah you can exclude bin files from being filtered
but ye i could do exclude but do it for every file?
wait i could just exclude a custom extension
thanks
wildcards exist yea
.
any ideasxd?
Yeah just create your own .utter_rubbish extension and let it not being filtered.
utter rubbish
.bin
Debug and check when your Cosmetic becomes null and tell us the pos
Hey all my name is Shiv im a beginner dev. Im trying to make a building minigame based on random prompts that are stored in the config file. So far the command "/prompt get" works well where a book is given to the player with a random string in the page from the config. What i need help with is adding and removing these promts from the config file with the commands /prompt add <msg> and /prompt rem <msg>
?configs
See this wiki page on how to use custom configuration files: https://www.spigotmc.org/wiki/config-files/
just alter what you want in the config and call saveConfig()
worldedit tutorial
If I remember correctly, yaml can do stuff like
map:
- key: value
``` right?
After making my class serializable, i can just save the Map<> instead, right?
not just the string
no - as that indicates a list element
yep
And that map element can be gotten as a HashMap, right?
yes
get("map")
well that returns a ConfigurationSection but call getValues() on it to get the backing Map
Nice
its bugged here :
the data is already in the databse for both the cosmeticWrapper and the player data ..
but it send null when i try to get the Cosetmic object
why i use Wrapper , cuz gson don't support abstract class serliztion
Show me:
- How you create your
collectionobject - The cosmetic wrapper
and i tried to do it without the transient keyword , and with
It does
i tried , it doesn't
it send me a really long gson errors
this is where i create the CosmeticWrapper :
and i use it here :
this is only in lobby , cuz i don't want the file creation of the glass comsetic in all servers , that will be so redundent
only in lobby , and after that it will load it to mongodb, and from there other servers can get it from mongodb
- Show me where you create your mongo collection.
- Print out what
document.toJson()looks like.
Show me where you create your mongo collection.
Ok, then print out what your document.toJson() returns.
can i recomend joining the engin hub discord server: https://discord.com/invite/enginehub
they can probaly help u better
the cosetmic it self..
hey
yeah bc its transient
i tried without transient
What does transient even do
Prevents it from being serialized
Ah
prevent it from being serlized with gson
Why did you even apply transient here?
this GSON instance how did you create it, did you provide any configuration via the builder to create the instance?
Does it work now for some reason?
no still not working ..
Hey, I have a plugin already in production and I want to include a new feature, which will be basically a NPC with a RightClickEvent. The two options I think I have is using the Citizens API or using pure nms. The thing is that I don't want to force the servers that are already using my plugin to download Citizens, so I guess the best option would be using pure NMS. It's a 1.19+ plugin, so apparently nms packages names do not include the version, so I don't know how it would work having different nms dependencies in the same project if they have packages with the same name. Also, my maven project is not a multi module one. Does anybody know how I should proceed in this case? (I have just started with nms)
An everything else in the Wrapper class is initialzed?
so you dont know?^^
maybe log or inspect the json (for the cosmetic) which you give gson
Could be something wrong with the encoding of the text maybe
Gonna check it out
Yo guys. how do i make it so it gives a player a loaded crossbow
So getItemMeta of your item, cast it to CrossbowMeta, invoke said method on it and use setItemMeta on that itemstack again.
ok
thanks i'll check that out.
Can BlockPlaceEvent ever be triggered by enderman placing a block?
In which case I assume event.getPlayer would be null
That's a very interesting case
Called when a block is placed by a player. says the docu so I guess only player can trigger this
Yeah I think so. getPlayer is also marked as nonnull
So there couldn't be any case where it doesn't give a player
Paper defines the player as @NotNull in the constructor, so yeah
Though it is a good question what event will be called for this - EntityBlockFormEvent comes to mind, but that is unlikely to be the case
Well there is EntityChangeBlockEvent, that is probably the one being used
Guys I have a very weird issues, what are the causes for Bungeecord to return false to a ping request using the api? Even if the server is online (for sure, it's not timeout).
The ping api is really weird tbh, functions 1 time on 100
When your in a project and the wrighting is red how do u import the class?
Ctrl + Shift + O in Eclipse
Uh, generally autocompletion should nullify that problem, as long as you eagerly accept the IDE's suggestions
I am trying to stop the player's block from getting consumde when he places it, but this event doesn't work. If I put + 1 on the setamount line, then he starts gaining block
What is causing that behaviour
I don't want to just use inventory.additem because then it could go into any stack
I need it to return to the same stack
Could it be that they are ghost items?
Also, beware that you can place block via the OffHand - make sure to use getHand();
The easiest approach would be to schedule the change the next tick, but that isn't great
I was thinking of schedule but then it's got a weird lag
And thanks about the get hand I didn't realise
You could cancel the event and handle it yourself, but that is also a bit bogus
Yeah then I have to place the block myself and there are edge cases and it's getting complicated
I mght have to just schedule it
I'd try player.getInventory().setItem(event.getHand(), event.getItemInHand().clone());, but that'd be stupid if it works
Oh that's clever
I'll tryt it
It works!
It's got the item pickup squish animation thing on the hotbar but that's ok
Better than scheduled solution
Bruh what
Thanks man
Also for the record I tried doing -1 and he doesn't lose two items
It has no effect
Very weird
That was more of a joke than anything else. There might be a bug somewhere in spigot I guess
lmaoπ
Or just some really undocumented behaviour
How to make SpigotLibraryLoader download/load my deps or its own thing?
cant use the built in one, use something like libby instead
ah, blind me. sorry..
can you provide a example if possible
i don't fully understand
im new to this
CrossbowMeta meta = (CrossbowMeta) itemstack.getItemMeta();
meta.addChargedProjectile(arrowItemstack);
itemstack.setItemMeta(meta);
+/- a few inaccuracies
could anyone help me here? im trying to make it so that when ever the player closes the inventory it writes to the hashmap, if the title of the inventory is the players name. here is the inventory close event, and the inventory code: for some reason, it does not change the hashmap when ever i close the GUI
uwu
i was able to fix it . thanks everyone .
what was it?
it shows red on the arrow instance
the bug returned xD
do you get the message "ruuning" send?
then log all the keys in the hashmap so you know if the keys are in the same way as you want them to be
is there a way to fix the arrowitemstack issue. it shows red for me
alr ill try that
screen of the error
maybe import missing?
Do you have any idea of what you are doing?
I can safely assert without any proof that this is not the case.
ArrowItemStack doesn't exist
Jesus people, why do naming conventions exist?
arrowItemStack is obviously a variable, and a variable needs to be declared and initialized
XD
π ya guys took so long to notice it's a variable
ummmmmmmmmmm
i said i was new
jesus guys it took so long jesus
If I used ArrowItemStack it would be a class, and that would be syntactically incorrect as you cannot pass a type that way (hell, why the hell would you even pass a type in there?) - if I wanted to do that I'd so ArrowItemStack.class, but again, that is not what we want (there isn't even an ArrowItemStack class as far as I am concerned).
it's ok, everyone were new at some point. it's ok to make mistakes
class names will always begin with an uppercase letter whereas variable names start with lowercase letter
yea. i don't know how to make the variable. or even much about them
I learned java from w3schools, here's some info about variables https://www.w3schools.com/java/java_variables.asp
ItemStack arrowItemstack = new ItemStack(Material.ARROW, 1); - with some room for error caused by me not having seriously touched bukkit for multiple years now
thanks.
it works.
also thanks for showing me this
recursive relations?
i made a CosmeticWarpper ,cuz from what i understood , i can't use abstract class in gson serliztion
To be honest I have no clue what you are doing
how do i mock commands?
Like, I feel like this is a typical enterprise java moment
trying to serlize it and add it to mongodb
whatever the cause, I cannot really know it from what you are providing us
provide the complete stacktrace at best
It's pretty evident that two different types both require each other for (de-)serialization, so the full stacktrace isn't all that needed
Stacktraces start from the bottom
I suppose your logger somehow doesn't flush it's outputs correctly. Whatever
Do you happen to know what version of GSON your server is running on?
using 1.8.8 spigot for testing .
Ye, but to what GSON version does that correspond? Otherwise I'll be searching for a needle in a haystack
idk if i need to mock it, i used plugin.getCommand
i just wanna test a kick command
so idk if mocking is necessary
sry im new to tests
I can tell, its fine
Well usually when you test commands you end up needing to do integration, system or some other larger tests
mockbukkit
Yes thats a thing but you rarely need mock bukkit for actual unit tests
Then you ought to be able to isolate units and mock its environment with mockito
1.8.8 π£
its good for me ..
1.8 is awful in any case
the plugin does not have any nms , so it should work on any .
i use 1.8.8 cuz its the lightest ..xD
What java version do you use w it?
8
Why spigot unloads the deps first when disabling the plugin?
Using 1.20.2 spigot build
Poor server, java 8 is significantly worse than newer versions in terms of gc performance etc
xd
hey there how can i make changes to a bossbar i created in a file in my plugin through another event file? ive tried so many different things including using the same file for everything but i just cant get it to work. v1.20.2
?di
Guide to dependency injection: https://www.spigotmc.org/wiki/using-dependency-injection/
Hello, does anyone know why even though the packets are good, the packets to players aren't getting sent? On 1.20.1 it works, but in 1.20.2 and 1.20.4 it doesnt anymore:
public void send(Player to) {
try {
Object player = to.getClass().getMethod("getHandle").invoke(to);
Field connectionField = player.getClass().getField("c");
connectionField.setAccessible(true);
Object connection = connectionField.get(player);
Class<?> packetClass = Class.forName("net.minecraft.network.protocol.Packet");
connection.getClass().getMethod("a", packetClass).invoke(connection, packet);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | NoSuchFieldException | ClassNotFoundException e) {
throw new RuntimeException("Error when trying to send packet: ", e);
}
}
I've printed all of them, connection seems fine, so as the packet. I dont get any errors.
Viaversion compat
I've tried for each server 1.20.1, 1.20.2 and 1.20.4 without viaversion and it still didnt work
and the method names to get connection and packet are the same from 1.20.1 to 1.20.2 and 1.20.4
but it only works on a 1.20.1 server
Is the repository pattern strictly for holding data
like would it be misleading if I registered the data to some like bukkit listeners or something
I mean it's pattern for separating data access logic, not sure what it have to do with listeners
I'm making it store an implementation and the impls can have a listener
It's fine though ima just use a service class
Is a service just a fancy way of saying manager
Are u referring to spring service?
Na
If so, it's not
Almost all managers are some sort of service, all services may not be managers though
Service is basically component inside of ioc container which holds some application logic
But the term service is really vague
Also assuming you are talking about spring
so what does a service do
If you talk about services in java I think of Java's ServiceLoader API
maybe ill just use a manager
That is, a service is the implementation of a specification (most of the time that specification is an interface) which is dynamically discovered at runtime through the ServiceLoader API
Yeah the module api thingy thing
Nah, JPMS is something different altogether, although it ties in nicely
You can use services even outside of modularity. For example SLF4J works like that, but plenty of other libraries use it too even outside of Java 9+
Okay it's me again with another incredibly specific question: Is there some maven plugin to generate jar-in-jars while having a lot of control over said process?
Basically I want to have a single of my own classes and a few dependencies bundled as usual, while all my other classes and dependencies are bundled in a jar within that jar.
Although I suppose I ought to use gradle for such accursed setups.
Yeah Iβd prob stick w gradle
Ah I see yeah⦠thats nice
Well I thought it was mainly just for the JPMS even tho it has existed since java 8 if not earlier as well
Of course I could also fix the underlying bug that necessitates such drastic measures, but that might take even longer than figuring out how to work around it
What bug are we talking about?
My custom classloader using the app classloader instead of itself to load a class
Ah and I assume u want it to use ur custom cl instead?
Yep. I assume the fix would be as trivial as changing up the logic of Classloader#loadClass to not consult the plattform classloader, but I cannot exactly know what kind of issues that would cause.
Yeah true, although that might be easier than an uber jar, anyway if you do end up with the uber jar stuff, I think luckperms does that as well so you might be interested in their gradle setup
why do i need to cast this still
public <C extends T> void loadAndRegister(@NotNull C config) throws IOException {
Preconditions.checkNotNull(config, "config is null.");
Class<? extends T> configClass = (Class<? extends T>) config.getClass();```
if the method knows C extends T, and we get its class so the class has to be of a type that extends T
eh, the service is the interface/public API, the service provider is the implementation
oh bruh
Yeah you can define it like that too, yeah.
I think returns Class<? extends ClassType> no?
Oh yeah nvm me
Okay actually it is not caused by this - doesn't suprise me tbh given that the plattform classloader should not contain anything but the JRE.
Well then time to hunt down the other bottleneck(s)
Actually Max, it should be Class<? extends T> @quaint mantle
what should
getClass()
@IntrinsicCandidate
public final native Class<?> getClass();```
It should be Class<? super C>, no?
Read the javadoc, but I thought it was weird to just be a wildcard type, I mean
yeah lol
You cannot have it be anything differently because java does not have a "self" generic type
Well I think this is cause of covariance and contravariance and type erasure
bruh i hate generics
Uhhhh, no. I meant extends, not super
yeah extends it is lol
super is such a strange keyword, imo.
ok so if I have a method like this
well, it makes sense for consumers
<C extends T> void loadAndRegister(@NotNull C config) throws IOException;
Do i need the generic C
Not really
alr
I mean C erases to whatever T erases to
Yes, and no.
And since you donβt really have some sort of type token or anything, presumably quite useless method type arg
It isn't needed for compilation, but it is needed for making a good API
<C extends T> C get(@NotNull Class<C> configClass);
and for this one i can just have Class<? extends T> right
Actually no, my brain is melting right now
I mean yeah generics is nice, but type erasure is⦠well⦠a mess
Nah
There its fine
why
It is only required API-wise if you want to return it, but not necessarily for consumption
Since you want to get the exact type of the Class<C> argunent
i didnt even see it
lol
yeah I forgot i was returning the class
@NotNull
List<@NotNull T> getRegistered();
void save(@NotNull Class<? extends T> configClass) throws IOException;
boolean isSaved(Class<? extends T> configClass) throws IOException;
boolean isRegistered(Class<? extends T> configClass);
these are all fine right
i dont know
lol
whoever made this class needs to leave import org.checkerframework.checker.units.qual.C;
That is why you always exclude transitive dependencies
Oh yeah checkerqual with its thousands of annots
Oh, and annotation frameworks need to be provided/compileOnly
Well yeah most ones can, apart from if you need it at runtime, then prob wna have it there tho doubt Max needs that
question: how would i add something to this because when ever i do, it deletes the old value, and replaces it:
HashMap<Player, HashMap<String,Location>> bagLocations = new HashMap<>();
HashMap<String,Location> baginfo = new HashMap<>();
bagNumber.put(p,num);
bagLocations.put(p,baginfo);
Map#compute is one way
However, I recommend to not use Player in maps, instead UUID should be used.
But it is fine to do so as long as you remove the player once they disconnect
you have Map::replace as well
Like, it stores the player's name, and then the other hashmap will have a load of other Strings aka the names of the beds/bags, and when i look at that it will give me the location of the bag, so if i used replace, would i need a value already there?
also how do i use map#compute?
map.compute(key, (finalKey, value) -> {
if (value == null) {
value = new HashMap<>();
}
// Do stuff
return value;
});
finalKey being the same as key, but you can use finalKey inside your lambda without having to copy your key explicitly (though most of the time that is not needed)
okay thank you!!
You can also use HashBasedTable
Which is basically Map<R,Map<C,V>>
Wait that will actually really help, i didnt know they existed π
thanks xD
HashBasedTable.create() gives you one also :)
How can i use Plugin.getResource in this context?
BukkitObjectInputStream in = new BukkitObjectInputStream(new GZIPInputStream(HERE));
Should i immedietly use InputStream instead of GZIP?
It depends on how your object is stored on disk
You can use PluginClass.class.getResourceAsStream("my-resource-file.dat") to obtain an input stream
Does anyone know how to obtain an absolute URL from a non-absolute URL?
So far I tried
URI uri = url.toURI();
if (!uri.isAbsolute()) {
arr.put(url.toString());
} else {
uri = Path.of(".").toAbsolutePath().toUri().resolve(uri);
arr.put(uri.toASCIIString());
}
but URI#isAbsolute returns true even for file://myJar.jar, besides the else branch does not seem to work either
Iβve had issues with that as well in the past
Dont remember exactly how I fixed it, but I think I used a File object at some point
(Instead of Path)
Hm right, I can use that
yeah i dont think it needs to be like his
Yeah well it was weird when I fixed it cuz I remember just freaking out
i did some testing and everything I think works
idk if im doing this whole unit test things right tho
@Test
void getRegistered() {
assertEquals(2, configService.getRegistered().size());
assertTrue(configService.getRegistered().stream().anyMatch(c -> c instanceof ConfigOne));
assertTrue(configService.getRegistered().stream().anyMatch(c -> c instanceof ConfigTwo));
assertFalse(configService.getRegistered().stream().anyMatch(c -> c instanceof UnRegisteredConfig));
}
Exception in thread "main" java.lang.IllegalArgumentException: URI has an authority component
at java.base/java.io.File.<init>(File.java:425)
at org.stianloader.smatterbuild.cli.sll.CLISLLJumploader.main(CLISLLJumploader.java:45)
great.
Okay, for some reason the filename is encoded as the authority? Great - seems as if I am working with malformed URLs
lmao
Is there a way to determine if a block would change a noteblock's instrument or would I have to use NMS to do that?
Okay after fixing the problem at it's source it is gone now.
so mockbukkit doesnt work with spigot or what
At least not with spigot on the classpath
Under gradle you could've excluded spigot from the test classpath and added paper on the test classpath, but that is not possible under maven
Can anyone help me here? I am trying to sort the player list but everything I tried doesnβt work. By default it is sorted alphabetically, so I tried to put abc letters in front of the name but itβs still being sorted by the original username. I also tried creating teams, for example 00Owner 01Admin 02Supporter but no success..
FirmlyMCMoon.getInstance().getResource("moon_house.dStructure");
This returns null, even tho that the file exists under src > main > java > resources
Show your file structure
any image host?
?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
Oh let me do verification
does gradle make a difference if I dont care about build speed?
https://imgur.com/a/E0Isx5C
did you mean this?
gradle is more advanced but in some edge cases allows for more
if you need full
https://imgur.com/a/qF7o68o
I disabled filtering for them, does it affect it?
Can you check if that file is actually present in your jar
its not
i guess filtering disabled removes them as resources.
i disabled filtering
fully
now its there
Is it working if file is there?
The file does exists now yes, but it gives eof exception
i am trying to fix it
the problem is in
BukkitObjectInputStream in = new BukkitObjectInputStream(inputStream);
are binary files even supposed to be a input stream?
they should be right
Input stream is stream of bytes
Not sure about bukkit impl of object stream, but is should be checked exception
Meaning you should catch it
Yeah
I catched the exception already, do you mean that i should ignore it?
Read this so article
What file type is that?
its a wildcard
I have no idea what you mean with that
Is it a standard structure file? In that case, (Bukkit-)ObjectInputStream will not work. ObjectInputStreams can only decode stuff that was encoded via an ObjectOutputStream
no its not a standard structure file
a custom class is serialized in it
And that class implements Serializable, right?
what items are you serializing?
yes
a hashset and a string, custom serializable tuples, another custom serilizable class
And that class has never been changed since it was written via an ObjectOutputStream, or changes to it did not impact it's compatibility?
Gradle and maven can both be equally fast
Ohhhh
i only changed one function
I mean gradle does have incremental build, task caching and the daemon runner
As long as that function had nothing to do with the serialization process it should be okay
But i think maven got some upgrades also
it didnt
Do you have filtering activated in your pom perchance? Although that cannot really cause EOFs afaik
what might be different is the methods i used:
BukkitObjectOutputStream out = new BukkitObjectOutputStream(new GZIPOutputStream(new FileOutputStream(FilePath)));
BukkitObjectInputStream in = new BukkitObjectInputStream(inputStream);
maybe i should use the same methods...
If you GZIP it out, you need to read it via GZIP
same issue
Although I never used that one, and it is a bit uncanny for me that you don't declare all three streams in a try-with-resources
i dont really understand what u mean with "try-with-resources"
Did you invoke GZIPOutputStream#finish()?
you mean close
try (OutputStream rawOut = Files.newOutputStream(path); OutputStream gzippedOut = new GZIPOutputStream(rawOut); ObjectOutput oubjectOutput = new BukkitObjectOutputStream(gzippedOut)) {
// Logic here
}
and yes i closed it
Yeah same thing, didn't see that DeflaterOutputStream#close calls finish
anyone?
@quaint mantle Could you look into the contents of your jar file? (This can be done by renaming the *.jar file to *.zip if you don't already know that) and check whether your file hasn't been changed?
it is the same file
Even the path is the right one?
@quaint mantle You can filter some and not others.```xml
<resources>
<!-- Include all resources -->
<resource>
<directory>resources</directory>
<filtering>true</filtering>
<includes>
<include>.yml</include>
<include>.txt</include>
<include>*.json</include>
</includes>
</resource>
<resource>
<directory>resources</directory>
<filtering>false</filtering>
<includes>
<include>*.nbt</include>
</includes>
</resource>
</resources>```
compressed files (like nbt) must not be filtered.
well that would mean that the file in the jar has changed as a result of filtering.
And they even stated that filtering was disabled by them
yes
Just out of safety, does #getResource work now?
yes
yeah then I have no clue what is going on
How do I pass player chat signature into custom message? Or this even possible?
You could, just in theory, do some crazy magic, but I'm not sure
I mean... that's not true
its true on spigot cause it just uses the system chat packet iirc
but it doesn't have to be that way
Hmm
it only checks if the signed potion is contained in the plain text serialized chat component
so if you add some prefix/suffix to the signed content, then it can still be signed
but spigot just redirects all chat to use the system chat packet iirc (if a format is set)
That seems wrong from cryptographic pov lol
But seems it's true
While the message always needs to be verified by the player that sent it, player display name, team name, and surrounding format can be freely defined by the server.
Hello, I have a problem with the BlockDamageEvent. It does not get triggered when the player keeps mining a block after a BlockBreakEvent has been cancelled. I tried using the BLOCK_DIG packet same thing. So basically the player starts digging BlockDamageEvent gets triggered -> finished mining, but BlockBreakEvent is cancelled -> starts digging again while still holding LMB, but then both BlockDamageEvent AND BlockDamageAbortEvent are not triggered. Is there an alternative thing I could do to detect this moment?
Can I add stuff like prefix, suffix, e.t.c?
it uses the MODIFIED trust level. So I think it shows the message with the yellow indicator. whereas no indicator is pure signed
and red is unsigned
this is actually entierly different, and not related to what I'm talking about. that is the chat type and isn't included in the signed message at all
well in a way, yes, but not that way. Like if you take the signed string, and put it into a component with a prefix or suffix and put that into the unsigned content of the clientbound packet, it will show as modified, not unsigned.
there is the separate ChatType system which can define chat formats in datapacks which are synced to the client
but spigot has 0 API for that and setFormat does not use that at all, it just puts the whole thing into a system chat packet if you try to use setFormat with the non-default format
is this the most optimal way to load all the chunks from x -1000 to x 1000 and z -1000 and z 1000?
that wont load them all
use completable features and run it in async, not sure if async chunk loading is possible with a normal plugin tho
chunks have there own x and z so you just need to add 1, it will also probably just die
so the chunk at x10 z20 does not contain the block 10 20?
no
like what i mean is, in here, we use coordonates of chunks not blocks?
coord of chunk in getChunkAt
so yes?
so yes what
ok i get it
i missread what u wrote
chunk 10,20 doesnt contain block 10,20
Learn about CustomBlockData here:
https://www.spigotmc.org/threads/custom-block-data-persistentdatacontainer-for-blocks.512422/
thanks!
whos the blockpdc for
is this better? (its still reaaaally slow)
ay
yes
sure
do you have any way of doing that faster? it takes a REAAAAAlly long time
it might be slow becuase you are loading 252 chunks at once
wait too low
my math bad
You can use paper and get em async then wait for the async world system to create em all
7.938 chunks at once
what do you mean? i dont understand your message
lol
Donβt use it async
Asynchronous (aka async) programming in Java is a technique for parallel programming that lets teams distribute work and build application features separately from the primary application thread. Then, when the team is ready with the feature, the code is synced with the main thread.
that is wrong
lol
dont listen to google
you could still probably execute this better using some form of work distribution
The server is sync
Wouldnβt matter much since spigot halts until it has generated le chunk
So, you want me to put the chunk loading thing on an other thread?
you can't
well you might beable to use PaperLib here
should help if your plugin is run on paper
it does
chunky
wasn't a question it was a statement
hey guys, I wanted to ask you about a "pattern" decision. So basically I have a class called MerchantManager and it represents a feature for my plugin that soft-depends on Citizens. The idea is to spawn a NPC every X time and then despawn it after Y time. It will be basically a merchant with a custom inventory and players can trade items with him. If Citizens is not enabled in the server, I'll just enable a command to access the same inventory/gui that would be accessible with the NPC. In the MerchantManager class I'll basically have the timing logic, so it will check if it's time to end the "merchant event", start it, etc and also get config settings. What's the best approach in this case? Like, I'll have two implementations of the event, one using Citizens and another one using just the GUI and a command. Should I have an interface like this:
public interface MerchantEvent {
void start();
void stop();
}
and then on the manager:
public void start() {
// timing logic
merchantEvent.start();
}
do you have any documentation on how it can help me with chunk loading?
Craftbukkit modification
How to cap enchanting that it doesnt go further than prot 3 and sharp 3 I had someone make a plugin for me but it doesnt work good
Theres no way to speed up the chunk gen other than having powerful pc
https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/enchantment/PrepareItemEnchantEvent.html with getOffers
declaration: package: org.bukkit.event.enchantment, class: PrepareItemEnchantEvent
Is there an option I could send you the plugina nd tell you the errors and you fix it or no?
depends on the plugin
I think bros gonna send jar π
I got source code rn
did kacper code you a plugin
kaspain did ye
@onyx fjord do you not do bug fixes or smth
not him
kaspiandev
did make it for me
(i payed him for it)
that is kaspiandev
i thought u misstyped or smth
but is it possible I could send you it in dm send you the list of bugs and you fix it or no?
sure
Yeah that looks fine
public interface MerchantEvent {
void start();
void stop();
boolean isActive();
}
on your command you just check isActive
why when i do this plugin = MockBukkit.load(CorePlugin.class); this is thrown
sry i am new to tests
It mean its not mocking
