#help-development
1 messages Β· Page 1076 of 1
no
i need a enderchest plugin without this method
because i want edit the sizeenderchest
but
have a dup with freecam
idk how fix
just find a yt video that exploits it
Does bukkit still create a new Thread for each join? The one used in AsyncPlayerPreLoginEvent
How can u have a block display entity with a chest where the chest has the open state
may it be that u are spawning an actual enderchest?
Hey, could someone help me trying to solve this method?
I'm trying to calculate the maximum possible upgrades depending on the balance of the player.
The level price is calculated like this: initialPrice (100) + ((level) * increasePrice (150)) (Summing all levels)
public Result calculateMaxUpgrades(Player player, CustomEnchant enchant, ItemStack item) {
double initialPrice = getNextLevelPrice(item, enchant);
double firstBalance = plugin.getEssenceManager().getEssence(player);
int itemLevel = getEnchantmentLevel(item, enchant);
int upgrades = 0;
double currentPrice = initialPrice;
double balance = firstBalance;
int level = itemLevel;
while (balance >= currentPrice) {
if (itemLevel + upgrades >= enchant.getMaxLevel())
break;
upgrades++;
balance = balance - getLevelPrice(enchant, level);
currentPrice = currentPrice + getLevelPrice(enchant, level);
level++;
}
return new Result(upgrades, currentPrice);
}```
I've tried many different ways but cannot solve this mf
As you can see in chat I have balance for more levels but it gets stuck
Cuz they surely did that before but I'm not sure whether it's still the same
Explain it
Eyeballed this one. lmk if it works:
public Result calculateMaxUpgrades(Player player, CustomEnchant enchant, ItemStack item) {
double balance = plugin.getEssenceManager().getEssence(player);
double initialPrice = getNextLevelPrice(item, enchant);
if(balance < initialPrice) {
return Result.EMPTY;
}
int itemLevel = getEnchantmentLevel(item, enchant);
int maxLevel = enchant.getMaxLevel();
if(itemLevel >= enchant.getMaxLevel()) {
return Result.EMPTY;
}
int upgrades = 0;
double currentPrice = initialPrice;
while(balance >= currentPrice && itemLevel + upgrades < maxLevel) {
upgrades++;
currentPrice += getLevelPrice(item, enchant, itemLevel + upgrades);
}
return new Result(upgrades, currentPrice);
}
Not sure if itemLevel + upgrades < maxLevel or itemLevel + upgrades <= maxLevel
Brain is baked from exams
let me check
public static final Result EMTPY = new Result(0, 0);
yeah yeah
^^
thx
I think it's just <
also, getLevelPrice(enchant, level)
I'll try it now
But it should work
Okay it did work but I have a problem xd
I have this method too
This is just when enchanting the item to get the price
Look at the chat
Like it is almost the same
but NOT the same when it should be
Hm
I don't think you're doing it wrong, so something may be off here
Variable level is the amount of levels the user asked for
public double getPrice(int currentLevel, int levels, CustomEnchant enchant) {
double price = 0D;
for(int i = 0; i < levels; i++) {
price += getLevelPrice(enchant, currentLevel + i);
}
return price;
}
Is it possible to have a block display entity, with a chest that has an open state?
hmm, let me try
smart way lol
You would have to set the Lidded Blockstate to open. Display entities only contain BlockData iirc. Let me double check.
Yeah its only BlockData that can be set, not the state.
Didn't work i believe π
Is it too low or too high?
π€¨
so it also wouldnt be possible with minecart chests
That would increase the price even further
oh true
or those dont even have an open state I think nvm
+6 for 2850.0!
why π
I dont know, i have nothing i can base this price on
What do you need?
xD
Well, gl
Oh, i think upgrades++ should be after currentPrice ... Let me try ;D
This was the solve
nvm
This was the solve
wasn't there some button on intellij to download all docs/sources ?
yeah im looking there can't seem to find it
double shift and download sources
Can the tablist or scoreboard be changed async ?
Any idea as to why I can't access import org.bukkit.Material;?
I'm using Maven and Java16.
Here's my dependencies:<dependencies> <dependency> <groupId>org.spigotmc</groupId> <artifactId>spigot-api</artifactId> <version>1.20.6-R0.1-SNAPSHOT</version> <scope>provided</scope> </dependency> </dependencies>
π€¦Thank you very much, I'm following a mini-course on youtube to learn it and this is the only hitch so far.
The Material class still exists
For 1.20.6 you should be using Java 21
The material class won't load properly with Java 16
@gray geyser ^^
Ok, I've changed to Java21: <properties> <java.version>21</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties>
and my dependencies remain the same: <dependencies> <dependency> <groupId>org.spigotmc</groupId> <artifactId>spigot-api</artifactId> <version>1.20.6-R0.1-SNAPSHOT</version> <scope>provided</scope> </dependency> </dependencies>
yet i'm still unable to import org.bukkit.Material. any ideas?
Did you set jdk 21 in project settings as well?
SDK: 22 Oracle OpenJDK version 22.0.1
Language level: 19 - No new language features
is your IJ up to date?
Latest version
Open the File tab and invalidate caches
also language level should be set to 21
That's non-existent for me
19 is the highest
?
do you mean SDK?
Are you sure Intellij is up to date
I'll triple check now
that must be really out of date then
God knows I've only just gotten back into it
I did update it
It must be going one version at a time
Because I checked for another update and it's updated again
Well J19 is "only" 2 years out of date
Good as new
A bit strange, I could swear it was older than that though
Gotta love IntelliJ taking 10 minutes to update
Guess I should've updated 2 years ago
Eh it's finished now
Oh wow language level 22
this should work then?
And it works, my bad all π
What is it about enums and java 21 that makes IntelliJ upset
What is it?
Idk thatβs why Iβm asking
just an intellij bug
those old java versions did simply not support parsing java 21 bytecode lol
Hello, Ive been watching tutorials on how to make a currency diamonds instead of dolars on my mc server. But I am lost and have no idea how to do it, so I will try a shot here, if anyone has any suggestions. Thank you
But it only affects enums?
eh I think the diff is to java 8? Since that was basically the bump for most people?
java ehhh, 17? idk. Something shat in a $values method into the bytecode
I see
ye
hmm
that would actually imply they fail somewhere else if it is only on java 21
java 15 changed the bytecode layout for the values method
but w/e
update your IDEs people 
seems like whatever it is, it's fixed
are there any workarounds for shading java 21 classes with gradle?
shadow plugin seems to be stuck on java 17
change the shadow plugin ^
someone explain why don't work windcharge explosion range?
best way to make someone glow with color?
because then they still have to keep up with stuff
iirc its becoming a gradleβ’οΈ managed thing
there is an option issue to finally fucking move it
yea
sad
ayup
Tbf, johnrengelman absolute legend doing something as important as shading for so long

I will take care of the trademark grant when I am black from vacation
Must really want a good tan
i saw that and it made me laugh
its not august yet
nah just european

someone ;-;
Set the yield of the event
like this?
hey guys, are you able to compile any plugin that uses spigot? i think there's a problem with the repositories, it's taking too long to compile
after 6 min mvn clean package finally finished
but with this warning: Could not transfer metadata org.spigotmc:spigot-api:1.16.4-R0.1-SNAPSHOT/maven-metadata.xml from/to sonatype (https://oss.sonatype.org/content/groups/public/): status code: 502, reason phrase: Bad Gateway (502) org.spigotmc:spigot-api:1.16.4-R0.1-SNAPSHOT/maven-metadata.xml failed to transfer from https://oss.sonatype.org/content/groups/public/ during a previous attempt. This failure was cached in the local repository and resolution will not be reattempted until the update interval of sonatype has elapsed or updates are forced. Original error: Could not transfer metadata org.spigotmc:spigot-api:1.16.4-R0.1-SNAPSHOT/maven-metadata.xml from/to sonatype (https://oss.sonatype.org/content/groups/public/): status code: 502, reason phrase: Bad Gateway (502)
add teh correct repository
I think its down to some extent
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>```
yeah oss.sonatype.org is down
It won't compile with that in there at the minute
I am so confused. org.bukkit.Material is not recognized, but it is these when i check in my dependencies. Here's a picture showing the Material class and the error
update IJ
help me how i increase explosion range of wind charge?
or explosion force
something like
player#getuuid#hashcode remains even if the server restarts?
proper hash collision chance
idk why but that worked, thanks
cuz you had an onld version of intellij that probably wasn't compatible with all the latest minecraft dev stuff
I mean, the uuid itself will remain after the server restarts
And has a much lower collision chance
yeah a player uuid doesnt care about your server, its always gonna be unique for every player, thats what mojang kinda needs
Is there any way to disable the animation of chests opening when in vanish?
how do I get a sword's damage?
my way of thinking is when player rightclick chest, event cancel and just open inventory gui & get contents of the chest inside
it would be easier if you do packets but packets are a pain for dev
get the attributes of it
will be GENERIC_ATTACK_DAMAGE i think
?paste
https://paste.md-5.net/nolululavu.php
humm this is the first time i got this error anyone know what this is? its my localhost and i get timed out.
this error pops up when i join my localhost and ends up timed out
Does anyone have any idea what causes this?
its the PacketPlayOutScorebaordTeam packet, but its obfuscated thus why I'm asking what causes the error message
why is it obfuscated, does it not have mojang mappings
no it doesn't, was using protocollib for most of my packet work, so I never needed it π
but i keep getting that error in protocollib
so im wondering what the issue is
yeah im on the other half I guess
public void SetSkin(Player player) {
CraftPlayer craftPlayer = (CraftPlayer)player;
GameProfile profile = craftPlayer.getProfile();
ServerGamePacketListenerImpl connection = craftPlayer.getHandle().connection;
connection.sendPacket(new ClientboundPlayerInfoRemovePacket(Collections.singletonList(player.getUniqueId())));
int randomSkin = new Random().nextInt(skins.size());
Property property = new Property("textures", skins.get(randomSkin));
plugin.getLogger().log(Level.WARNING, skins.get(randomSkin).toString());
profile.getProperties().removeAll("textures");
profile.getProperties().put("textures", property);
connection.sendPacket(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, ((CraftPlayer)player).getHandle()));
}
After using this method I disappear from the tab but my skin dosent change nor do I get any errors. If anybody could help me I'd apprentice it.
MC Ver: 1.21
Only change I saw was the TeamDisplayName field changed from a Chat input to TextComponent, but that should still work with WrappedChatComponent class
?paste
and youre getting the illegalstateexc
i dont get how i f ed up my localhost
Any plugin developers in here ????
nope
we're all tumbleweeds
yeah, thats why im asking why, unless im not seeing something
yeah, i skript
did you reshow players
ie. does it work if someone else sees you
check how other plugins do it
I just depend on skinsrestorer because I am lazy.
Do you know how to use intellJ idea
https://paste.md-5.net/ofajihuwin.php I'm getting this error when i try to enable respawn anchors in the end. The error shows when i try to tp into the world and it kicks me from the server.
Here is my code: https://paste.md-5.net/paduwaboxe.java
What i'm trying to do is enable respawn anchors in the end. This is just to see if i am able to get it to work. Anyone knows why I get the error?
seems the client just is not accepting non-nether locations
I don't think you can do this, sorry
ensure it does work with the nether
in your own code
if not, maybe there's some sort of registry desync issue
You mean make sure I can block respawn anchors in the nether?
I will see
same error when i try to disable in nether
WHYY wind charge explosion force not increase ................
you may not be telling the client then
see if theres a packet for that
send more registry data?
seems like if the client knows the entry which will be the_nether
it doesnt send the data
or something
i'll see if i can change the name
well the problem is the client gets the packet and doesnt understand what dimension it means
Do you know how to use intellJ idea bro
you have asked multiple people
yes
what do you want
Can you compile a code for me
okay
do it yourself?
yeah
Idk how
or ask gpt to do it for you
i am not executing arbitrary code
awful idea never suggest again
maven or gradle
thats probably how they got the code in the first place
Can chat gpt compile now
Maven
no
I mean probably wont take long before it can
Bro you have to make many files
I know it can run python code now
Idk hownto use intellJ idea
Slap javac in there and call it gpt 5
exactly
running python code means it must some kind of compiling
unless its just guessing and not running anything
go to the maven button in the top right
press the big m
then type package
they use more complicated ways
EclipseEconomy/
βββ pom.xml
βββ src/
β βββ main/
β βββ java/
β β βββ com/
β β βββ eclipsemc/
β β βββ economyplugin/
β β βββ Main.java
β β βββ BalanceCommand.java
β β βββ PayCommand.java
β β βββ TopBalanceCommand.java
β β βββ BankCommand.java
β β βββ InventoryListener.java
β β βββ BalancePlaceholder.java
β βββ resources/
β βββ plugin.yml
βββ config.yml
I want it in this format
its more effort to try and get someone to compile your mysterious plugin then it is to learn intellij enough to do it yourself
Python doesnβt need compiling
is it not already
can you not depend on them
I'd rather not
I just need something really simple.
I have.
what do they do
I check multiple and they have some libary they used.
which
CustomSkinManager, Gysier Skin Manager or something
No Idk how to make it on intellJ idea
screenshot the structure
then learn it
Then
show?
Show what
Presumably the screenshot
There was a website where i could view what methods are what when converting from mojang mappings to obfuscated names
i forgot what it was
?mappings
Compare different mappings with this website: https://mappings.cephx.dev
tyyy
not sure about item held but this does armor and player
will this make the armor work??
yeah armor will still block the same amount
just use teh hidePlayer in the API
that doesnt work sometimes
or does it?
it always works
does anyone have a good method for giving user input during onEnable?
just loop over all players and hide the player from them
wut
I am trying to use a scanner or registering a command but its extremely laggy
and not getting input right
when its connecting to my database I want to ensure that the database schema matches the schema i have defined in my code. and if it doesnt it prompts me to create a new table, rename a table, create new columns, etc
just dont wana manually keep the schemas the same
Hey
Not sure if your issue has been resolved
But you need to send a respawn packet for the player itself
And do hidePlayer & showPlayer for the rest of the players
And it's not only respawn packet
You have to add them to player list since you removed the player etc.
Its not resolved what packet would it be?
What packet would that be
Ok follow up to this.
Now I have registered the custom dimension type in which respawn anchors are enabled in the overworld. I no longer get the error. However, the new issue I'm facing is a weird one.
If i reload the plugin with the player online and read the value of the world's dimension type, it's respawnAnchorWorks boolean is true.
If i then leave and rejoin or die, this changes to false. Any suggestions?
as u can see respawnAnchorWorks is true before i leave and then false when i rejoin
is there a way to make holograms not turn dark color when player is behind a wall?
pretty sure you can if you're using display entities
is text hologram via armor stand ok?
yeah, but if you can use display entities, use them
the method is .setSeeThrough(false) correct?
or is it true?
Is it supposed to persist?
persist a player join
i think so
what is even setting it back to default?
Then invoke a world save if you want it saved.
would that actually?
There is some things that dont stay loaded if there is 0 players on
Hence it being loaded during a reload but not if you disconnect. Fairly certain if you had 2 players on and one disconnected and rejoined it would still persist
Where is my custom dimension saved
Well good time to test it out lol
I think it's very hacky what i did
and i dont think this is gonna work
but i'll test it anyyway
But you need to account for when no players and you should never assume your data is always present
So you should implement some checks to ensure its still there and if not fix it
btw did you have a look at what i'm doing?
Yes i looked at it
here
ah ok
gonna build and test with 2 players
I cant look at it with an ide currently at work
public void SetSkin(Player player) {
protocolManager = ProtocolLibrary.getProtocolManager();
PacketContainer packet = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
WrappedGameProfile profile = new WrappedGameProfile(player.getUniqueId(), player.getName());
int randomSkin = new Random().nextInt(skins.size());
WrappedSignedProperty texture = new WrappedSignedProperty();
profile.getProperties().put("textures", texture);
protocolManager.sendServerPacket(player, packet);
}
I am now using ProtocolLib. I just need help applying the skin. I have a list of strings which are a mineskin url.
hey guys is ConfigurationSerializable can saved float type? 'cause when I tried it
@AllArgsConstructor
@Getter
@Setter
public class RegionSoundImpl implements RegionSound {
private String name;
private float volume;
private float pitch;
private int length;
private boolean isRepeat;
@NotNull
@Override
public Map<String, Object> serialize() {
Map<String, Object> result = new HashMap<>();
result.put("name", name);
result.put("volume", volume);
result.put("pitch", pitch);
result.put("length", length);
result.put("isRepeat", isRepeat);
return result;
}
public static RegionSoundImpl deserialize(Map<String, Object> data) {
String soundName = (String) data.get("name");
float volume = (float) data.get("volume");
float pitch = (float) data.get("pitch");
int length = (int) data.get("length");
boolean isRepeat = (boolean) data.get("isRepeat");
return new RegionSoundImpl(soundName, volume, pitch, length, isRepeat);
}
}
error said :
java.lang.ClassCastException: class java.lang.Double cannot be cast to class java.lang.Float (java.lang.Double and java.lang.Float are in module java.base of loader 'bootstrap')```
I'd suggest using doubles for that
It's a bit wonky because collections can't hold primitives
So it gets saved as a Double
oh, got it thank you
And when you deserialize, it autocasts to the primitive double
You're casting it before this autocast is done, which means it's trying to convert Double to Float
thank you for answer!
its possible to execute something in main thread from another thread?
using the scheduler
Hi!, im looking for developer if anyone is interested just mention me !
?services
If you wish to request or offer development/art/building/administration services, please do so at https://www.spigotmc.org/forums/services-recruitment-v2.54/
Lol
guys
we dont need ai for everything
@young knoll use a compiler lmao
βcan AI download minecraft now?β
hi, how can i getHolder as EnderChest when getClickedInventory?
it returned as null
a platapus
a holder is never enderchest
oh wait no im wrong
?
declaration: package: org.bukkit.inventory, interface: InventoryHolder
what about it?
Does anyone have a Gson adapter that I could use to serialize and deserialize ItemStacks β οΈ currently using Base64 with BukkitObjectOutputStream but itβs super outdated.
is there another way to prevent my own plugin that has GUI listener being affected another GUI of other plugin ?
how are you handling guis?
just sounds like your system isn't designed correctly
well im just make sword handler and it affected to other one
that's still the regular way to do it
yeah how are you keeping track of your custom inventories though
mostly im check holder as well and this listener being affected to another plugin anyways
the listener is not based on any GUI as well
Don't use the holder for your GUI
im just want make it listener on Chest and EnderChest only
?gui
I think paper has a serializeBytes method but the object output stream uses Java IO and has known security issues
That's only if you can't control where the data is coming from
it's safe to use for local storage
basically these listener im just used only for Chest and EnderChest only
declaration: package: org.bukkit.inventory, interface: Inventory
public class InventoryManager{
private final Map<UUID, CustomInventory> inventoryMap = new HashMap<>();
public void openInventory(Player player, CustomInventory customInventory){
inventoryMap.put(player.getUniqueId(), customInventory);
}
@EventHandler
public void onClose(InventoryCloseEvent event){
inventoryMap.remove(event.getPlayer().getUniqueId());
}
}
public abstract class CustomInventory{
public abstract Inventory getInventory();
}```
this should ideally be the way you do it
but yeah check out that turtorial olivo sent, virtually the same thing
i used getType on my code but problem is other plugin is handling them with GUI
?
@EventHandler
public void onSwordEnchantInChest(InventoryOpenEvent event) {
Player player = (Player) event.getView().getPlayer();
IArena arena = Arena.getArenaByPlayer(player);
if (arena == null || BedWars.getAPI().getTeamUpgradesUtil().isWatchingGUI(player)) {
return;
}
// Check if player is watching a shop GUI
if (ShopCategory.categoryViewers.contains(player.getUniqueId())) {
return;
}
// Check if player is watching quick buy menu
if (ShopIndex.indexViewers.contains(player.getUniqueId())) {
return;
}
org.bukkit.inventory.Inventory inventory = event.getInventory();
if (inventory == null) return;
InventoryHolder holder = event.getInventory().getHolder();
Bukkit.getLogger().info("Clicked Inventory Type: " + event.getInventory().getType());
Bukkit.getLogger().info("Inventory Holder: " + (holder != null ? holder.getClass().getName() : "null"));
if (!(holder instanceof CraftChest)){
return;
}
InventoryType inventoryType = inventory.getType();
if (inventoryType == InventoryType.ENDER_CHEST || inventoryType == InventoryType.CHEST) {
for (ItemStack item : inventory.getContents()) {
if (item != null && VersionCommon.api.getVersionSupport().isSword(item)) {
ItemMeta im = item.getItemMeta();
ITeam team = arena.getTeam(player);
if (team != null) {
for (TeamEnchant e : team.getSwordsEnchantments()) {
im.addEnchant(e.getEnchantment(), e.getAmplifier(), true);
}
}
nms.setUnbreakable(im);
item.setItemMeta(im);
}
}
}
}```
just check it
change your event priority
to highest
but you really should use a more robust inventory system
okay i will try
Hey, does someone know why when i'm trying to compile my plugin, it gets stuck in "Downloaded from spigotmc-repo..."?
It just keeps there and never compile
public void SetSkin(Player player) {
CraftPlayer craftPlayer = (CraftPlayer)player;
ServerPlayer serverPlayer = craftPlayer.getHandle();
GameProfile profile = serverPlayer.getGameProfile();
ServerGamePacketListenerImpl connection = serverPlayer.connection;
ClientboundPlayerInfoRemovePacket removePacket = new ClientboundPlayerInfoRemovePacket(Collections.singletonList(player.getUniqueId()));
connection.sendPacket(removePacket);
int randomSkin = new Random().nextInt(skins.size());
Property property = new Property("textures", skins.get(randomSkin).value, skins.get(randomSkin).signature);
profile.getProperties().removeAll("textures");
profile.getProperties().put("textures", property);
ClientboundPlayerInfoUpdatePacket addPacket = new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, serverPlayer);
connection.sendPacket(addPacket);
Level level = serverPlayer.level();
CommonPlayerSpawnInfo playerSpawnInfo = new CommonPlayerSpawnInfo(
level.dimensionTypeRegistration(),
level.dimension(),
0,
serverPlayer.gameMode.getGameModeForPlayer(),
serverPlayer.gameMode.getPreviousGameModeForPlayer(),
level.isDebug(),
true,
Optional.of(GlobalPos.of(level.dimension(), serverPlayer.getOnPos())),
serverPlayer.getPortalCooldown()
);
ClientboundRespawnPacket respawnPacket = new ClientboundRespawnPacket(playerSpawnInfo, (byte) 0x01);
connection.sendPacket(respawnPacket);
skinStorage.put(player.getUniqueId(), randomSkin);
}
I got my skin changer to work. The only issue is the respawnPacket that reloads the whole world or something and the skin layers get messed up assuming its the respawnPacket.
are you saying skins layes get messed up on respawn
or two separate issues
if its a separate issue, you need to set the DATA_PLAYER_MODE_CUSTOMISATION for the layers
There is three issues happening
When I use SetSkin()
- The player gets put in a Loading Terrain Screen (Takes like 30 seconds)
- The tab for the player is missing
- The skin layers are messed up. But when I do /kill they are fine.
yeah for the layer you have to set their customisation mode before you send the update packet
if you're settings the skin beforehand, which you are
not sure on the others
Dam
i think 2 is just a matter of sending add plaeyr again possibly?
What is the packet called?
oh you are doing add player
its part of player info update packet
you can try send it with udpate_Display_name maybe that will update the tablist
EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions = EnumSet.noneOf(ClientboundPlayerInfoUpdatePacket.Action.class);
actions.add(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER);
actions.add(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME);
Can I put in the same packet or.
yeah
ClientboundPlayerInfoUpdatePacket playerInfoPacket = new ClientboundPlayerInfoUpdatePacket(actions, list of players);
```
like that
whats list of players do you mean just player
Okay, what was the update skin layers packet?
yo
its part of teh info update packet, you have to set the player's entityData
hold up i got code
any1 know how to put the setup server?
I didn't see it
I may be blind
skin layers can be done just via data, so long as your NPC extends ServerPlayer
it's not an npc
Not an NPC.
its an actual player
easier then
oh is there another way?
sec have to open IDE as code is old
is that with the update player name aswell
Before and After of skin.
any1 know how to setup the server?
lol
I know its Cringe.
ServerPlayer#getEntityData().set(Player.DATA_PLAYER_MODE_CUSTOMISATION, (byte) 0xFF);
however, thats only useable in your own object I believe. you are probably right abour having to reflect
0xFF is no layers i think
FF shoudl be layers
this.getEntityData().set(DATA_PLAYER_MODE_CUSTOMISATION, (byte) 0x7F);
i use that
i think thatm ight exclude capes tho
Hello, does anyone know where I can find CraftScheduler.java? I have a problem with it.
DATA_PLAYER_MODE_CUSTOMISATION
Where does this come from?
thats the bukkit interface for the scheduler i believe
whats wrong with it
net. minecraft. world. entity. player. Player
Itβs protected
only accessible from inside the Object
hmm can anyone help me fix this?
yes.. tell us what the issue is and we will help
Oh i dont have The permissions to send a Screenshot
private List<SynchedEntityData. DataValue<?>> getSynchedEntityData(){
SynchedEntityData synchedData = asEntity().getEntityData();
SynchedEntityData.DataItem<?>[] dataItems = DataItemReflectionUtil.getDataItems(synchedData);
//add to list
List<SynchedEntityData.DataValue<?>> sendList = new ArrayList<>();
for (SynchedEntityData.DataItem<?> dataItem : dataItems) {
sendList.add(dataItem.value());
}
return sendList;
}
private <T> EntityDataAccessor<T> getAccessor(int id){
SynchedEntityData synchedData = asEntity().getEntityData();
SynchedEntityData.DataItem<?>[] dataItems = DataItemReflectionUtil.getDataItems(synchedData);
//add to list
for (SynchedEntityData.DataItem<?> dataItem : dataItems) {
if(dataItem.getAccessor().id() == id)
return (EntityDataAccessor<T>) dataItem.getAccessor();
}
return null;
}
//WARN REFLECTION
public static SynchedEntityData.DataItem<?>[] getDataItems(SynchedEntityData entityData){
try {
Field field = entityData.getClass().getDeclaredField("itemsById");
field.setAccessible(true);
SynchedEntityData.DataItem<?>[] dataItems = (SynchedEntityData.DataItem<?>[])field.get(entityData);
return dataItems;
} catch (NoSuchFieldException | IllegalAccessException e) {
return null;
}
}
i use this for my npc, you cna modify it to suit yourself
?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 you can use to upload images.
Lightshot: https://prnt.sc
Imgur: https://imgur.com/upload
Flameshot: https://flameshot.org
warn reflection hehe
lmao
My brain
it's just getting synched data fields from the entity class
if you go to wiki.vg you can figure out what id the player customisation accessor is
then whack that in to getAccessor
I'm not 100% sure if it's the best way to do it, but worked fine for me
I have no clue what todo now lmao.
This dosen't even solve no issues but the skin itself.
it might be easier just to use reflection to get the value of DATA_PLAYER_MODE_CUSTOMISATION
if you're not gonna reuse synched entity data stuff
I have never used reflection so I might just swap back over to an API.
Yeah, but NMS in itself is a pain lmao
only if you believe it is
I've tried making this at least 15+ times.
you're really close, i'm happy how to show you how to do the reflection
means you need to take a break
I need to make a system for modifying entity data values for my packet entities
Do the ids change every version? That would be annoying
which ids?
This does not solve the problem
The accessor ids
i believe they do
i might be wrong
but they are prone to change
is playtime your plugin?
Blah, thatβs annoying
Hey, I have a problem with files, I have a config that has a value set to it, will say number: 8 But in game, I have changed it. However when i load this value (onEnable method) it doesn't change. Why does this happen?
what do you mean in game you have changed it
Like, the value in the server files
like while the server is off?
No, when it is on
you'll have to flush the cache
FileConfiguration caches to memory so any updates won't be seen
how did you change the value?
No
edited teh file by hand?
yea
ask in #help-server and ask the dev, they would know best
just call Plugin#reloadConfig() after ytou manually edit it
Ok thank you very much!
I'll make a reload command then
However what does buoobuoo mean with flush?
English is not my native language sorry
reload flushes the cahce
aja
so the server keeps a copy of the config in memory, if you change it while it's running, it won't know
He means, when you start your plugin, the first time you access teh config its loaded into memory
from that point it is accessed from memory
I thought the server just saved the changes when it closes
no
no
Or is it better to just have a command for it
if you are makign changes via code you should save
you should really only ever reload by command
if you're at a point where you are relying on reloading your config automatically for functionality, you're generally doing it wrong
I wasn't even reloading
oooh
In a perfect world everyone would override reloadConfig to handle all their custom config reloading
But are changes not saved when the server shuts down?
I really thought it happened
The thing is that, I changed the value then restarted the server
Nothing is saved by default
oh, thats weird
and the value wasn't changed
You need to call saveConfig if you make changes in code
Yeah, that's what I came xd
Ik, but i'm saying manually
Then they should be fine
that just sounds like the file isn't saving properly
Unless a saveConfig call somewhere overrides them
like manually
I'm not using any saveConfig
I'll try with notepad instead of vs
And i'm not making changes by code in that file
This is by default 8
But changed manually and it is supposedly saved
But when i ask for it
(I restarted the server after change)
the plugin will not detect manual changes until the server restarts
That's what is weird for me
The thing is that I restarted
Does it work if you change it when the server is off
I mean, the value is already changed
then the file you are editing is not the actual config.yml the server is reading
it is a custom file
I'll remove all config files and try again
maybe it is a bug
If you can edit the data layers couldn't you just update the skin through that.
oh
all skins come from Mojang to the client
the server is just telling the client which skin to use
that didn't work?
I promise i'm restarting the server xd
show your config load/reading code
Sure
public class HoeEnchantsFile {
private final HarvesterTools plugin;
private FileConfiguration dataConfig = null;
private File configFile = null;
public HoeEnchantsFile(HarvesterTools plugin) {
this.plugin = plugin;
saveDefaultConfig();
}
public void reloadConfig() {
if (this.configFile == null)
this.configFile = new File(plugin.getDataFolder() + "/enchants", "hoeEnchants.yml");
dataConfig = YamlConfiguration.loadConfiguration(configFile);
InputStream defaultStream = plugin.getResource("enchants/hoeEnchants.yml");
if (defaultStream != null) {
YamlConfiguration defaultConfig = YamlConfiguration.
loadConfiguration(new InputStreamReader(defaultStream));
this.dataConfig.setDefaults(defaultConfig);
}
}
public FileConfiguration getConfig() {
if (this.dataConfig == null)
reloadConfig();
return dataConfig;
}
public void saveConfig() {
if (dataConfig == null || configFile == null)
return;
try {
this.getConfig().save(this.configFile);
} catch (IOException e) {
plugin.getLogger().log(Level.SEVERE, "Couldn't save " +
this.configFile, e);
}
}
public void saveDefaultConfig() {
if (this.configFile == null)
this.configFile = new File(plugin.getDataFolder() + "/enchants", "hoeEnchants.yml");
if (!configFile.exists()) {
plugin.saveResource("enchants/hoeEnchants.yml", false);
}
}
}```
saveDefaultConfig will ONLY save config.yml
It is a custom method
ah I see
It's the last one
um
Even changing the value when the server is off didn't work
comment out line 23 and check again if yoru value changes
this.dataConfig.setDefaults(defaultConfig);
Nope, that didn't work
The file is not null so that doesn't even run
then I see nothing wrong
uuh
Let me show how I load the value then
I do it in the onEnable method
I load this into a Object
and the get the values from that object
what is the definition of config?
This
Forget about "name" I was trying to use config.getName But returned "" xd
show where you define and assign config
you are reading from teh plugins config,.yml not hoeConfig
I don't really see anything wrong
what?
No
do you mean config?
reading from config
That's another class
config is the param of the method
I can't access config without putting plugin.config before
And if that is the case
the value that is returning should be 0 not 8
I asked you tyo show where you defien and assign config
Look at loadEnchantments() and loadEnchantment()
loadEnchantment(FileConfiguration config)
none of those assign to config
The problem I'm having is not with config.yml
then why did you post code reading from config. Thats my point
show me where you read from the problem config
all your loaded configs are assigning to the same variables
so only swordConfig is going to be used
Oh wait
I'm dumb
I'm creating the same object twice or more
so that's why it doesn't change :-;
I didn't realize because for testing purposes it was the same
uuh
how do I solve this know xdd
I have an idea ig
just making an enum for Tools and that
Lol, it wasn't the file it was me just being dumb
Thanks Elgar :3
is it possible with resource packs to enable/disable item texture layers conditionally? like if i wanted to make a tinkers construct-esque item building system to have items look different depending on what you put into em
you could probably mess with durability to do it, but otherwise no
only custom model data
which means you have to have a variation for every combination
actually i don't evne think layers can be toggled, so no
still definitely possible to do tinkers like stuff, just visuals will either look the same between variations or you have to make a different png for every single combination
yeah and thats not very maintainable
required textures would go up exponentially the more parts or upgrades i add
you could maybe do it with shaders?
i've never really messed around with them enough but i believe its possible
Hola, stupid question. but in vanilla Mc commands, when you spawn a particle, you have the Delta property. Does this exist in Java code?
For example: this is the mc command I am trying to recreate in java (I want the player to be able to make custom particle images (for example. a mcfunctions file with their particle commands that in the end form a picture) , so they have a file with the commands and I turn them into java code.
an example command:
particle minecraft:dust 1 0.65 0 0.3 ~-0.0529651 ~0.6532368 ~0 0 0 0 0 1 force @a
<Command> <Particle> <color> <Scale> <delta> <speed> <count> <force visible>
In code documentation, I don't see anywhere for the Delta info (it's the offset, but static. cuz offset in java makes it go all places I believe)
your probably ganna need to find a particle api for that kinda stuff. simple minecraft particles are doable but making custom particle images, if it was me, i would go find a dependency and depend on it.
hmm, fair enough i suppose
it does exist
it does?
oh you wanna display images?
if i change the block type of a stairs block, the stairs direction will change?
I did that
dang
use .serialize
that's pretty neat
on what?
right?
which one
if i change the block type of a stairs block, the stairs direction will change?
this is a 2d image without white background titled 45 degrees in 3d space
pretty sure both
but toBytes
and any kind of image worked on that?
yep
you have to write teh size of the array
public static String serialize(ItemStack[] obj) {
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream);
dataOutput.writeInt(obj.length);
for (int i = 0; i < obj.length; i++) {
dataOutput.writeObject(obj[i]);
}
dataOutput.close();
return Base64Coder.encodeLines(outputStream.toByteArray());
} catch (Exception e) {
throw new IllegalStateException("Unable to save item stacks.", e);
}
}```
did you use an api or made this yourself?
if i change the block type of a stairs block, the stairs direction will change?
I ~~stole ~~ got inspired from 2 different projects
why not?
is this a question if it will change? because you can always test this out :3
well I just need to save and load an inventory from and into a file
im just going off what your method is returning
LOL. mind sharing those projects with me? ...for inspiration of course
its changing but idk avoid the direction change
I can link you my github with that, it has the links to the originals as well
i'd love that
man, github desktop sucks with multiple git accounts
Contribute to ShadowOfHeaven-Me/AlixSystem development by creating an account on GitHub.
you can set a fixed state if you want
they allow multiple accounts on teh site, but not on desktop client
how heavy is it
the concern is the bandwidth
after my byte buffer magic it needs 0.01ms to be sent and written
but it weighs 17 KB on each refresh
i'm more interested in 2d, since it's just a pretty display when a player wins a game :3
which happens every 350 ms
thats what i told four days ago lol
well the 3d uses a 2d image
then what about deserialization?
oh wait are you polish?
I might've gone with the other approach without it
ye
you 2?
not polish, but I live in poznan
I ain't in a city
I'm a village guy
nearly perfect middle of poland
public static ItemStack[] deserialize(String encoded) {
try {
ByteArrayInputStream outputStream = new ByteArrayInputStream(Base64Coder.decodeLines(encoded));
BukkitObjectInputStream dataOutput = new BukkitObjectInputStream(outputStream);
ItemStack[] items = new ItemStack[dataOutput.readInt()];
for (int i = 0; i < items.length; i++) {
items[i] = (ItemStack) dataOutput.readObject();
}
dataOutput.close();
return items;
} catch (Exception e) {
throw new IllegalStateException("Unable to save item stacks.", e);
}
}
based on that I made this
would this be correct?
whats the output stream for
@faint tide you can use this and just set the rotation to 0 degrees
and yes it would
I just haven't renamed the local names
When using sqlite, would it make sense to have multiple sqlite files to not make them too big? For performance reasons
by just setting the Rotation quaternion to null
sqlite is one file
Um, what stops you from just having multiple?
Thanks for this. I'll look into it, I'm gonna look into my own thing to see if i can find a solution, and if I can't then I'll definetily try and learn from yours and give credit where credit is due π
would mean multiple dbs
if you prefer performance, go look at something else than sqlite
aight, you do you
gl
I mean I tested it with 228 000 entries and ConcurrentInt62Set scored ~0.0035ms on average while LongOpenHashSet scored ~0.005ms on average
On phone rn so can barely read but yeah looks good
appreciate it ;]
with contains with single-thread invocation
Well I suppose #add might have a high performance impact here - I shall see.
Could also be that I didn't correctly set the amount of buckets - who knows?
yeah okay it's the #add that is an issue in this algo - I'm not sure how much I stress #contains here
so, I actually managed to get this to work. what I did, is I took the first three Delta numbers (removed the Wave dash ~) and added these to the spawn location. which made the image render.
But right now I have the issue that the image only spawns in one direction. Do I need to rotate the Yaw for the spawn location to make the image face the player?
public void payout() {
this.loc = player.getEyeLocation().add(player.getEyeLocation().getDirection().setY(0).normalize());
spawnAnimation(this.loc);
}
---
public void spawnAnimation(Location loc) {
for (var CMD : Commands) { // Commands being all the particle command lines for the image)
Location loc = location.clone().add(CMD.Delta1, CMD.Delta2, CMD.Delta3);
location.getWorld().spawnParticle(this.particle, loc, CMD.Count, CMD.offSetX, CMD.offSetY, CMD.offSetZ, CMD.Speed, new Particle.DustOptions(Color.fromRGB(Math.round(CMD.colorRed * 255.0F), Math.round(CMD.colorGreen * 255.0F), Math.round(CMD.colorBlue * 255.0F)), CMD.Scale));
}
}
Then again, I thought getDirection() already rotated the location towards the player?
getDirection returns teh Vector the Location is facing. If you want the inverse getDirection().multiply(-1)
so i added that, but that didn't change the rotation
the particle image still spawned in one direction
guys do you have some advice or how you usually keep consistent chat messages? (example: the chat response stating that the player doesnt have the permission to do something always has the same color / formatting) I dont really like the idea of having this as a static string somewhere, has anyone any dynamic solutions?
just have a config file where your messages are located, and make the messages consistent with eachother
Currently you are just "moving" the location to where the animation should spawn to exactly one block away (normalize) into the direction the player is looking (getDirection), while ignoring / removing the height component (setY) of the direction and therefor moving it on the same "level" as the players eye location.
From that you are just calculating the offset location of each particle, purely based on the base location, without taking rotation into consideration anywhere.
Logicially the particles will therefor always only be adjusted on the world axis, with no relation to where the player is looking.
To fix this, you will need to rotate the offset locations around the Y-axis of the animation origin.
This could either be the Y-axis of the original location or the Y-axis of the center of the whole animation "image" (which would need to be defined or calculated beforehand).
The center for the image is the original loc given to spawnAnimation(Location loc). Which means I need to change the offset of that locations Y-axis, right?
That makes it easier, as you don't need to define an additional center location or calculate the center yourself.
What you want to do is rotate every particles (offset) location around the Y-axis of that base / origin location.
It's basically just a little bit of math formula implemantation.
i feel like this is a dumb question but how do you guys determine what should be run on the main game thread. ik like db stuff should be run on another thread but when im writing code i dont think about if it should be run outside the main thread or not and i feel like i should be thinking those things sort of as a background process in my head when i code.
everything that can be done on another thread
If it's io/some other expensive operation -> async, in any other scenario there is no reason to do async
80%-90% of things (in games mostly) actually need to run on the main thread for synchronization and other reasons.
The 10%-20% that can be run outside of that asynchronously are all things, that don't interact directly with anything that is in a context to the things (like the world in a game) you interact with - that means, everything that is not directly relying on underlying changes of synchronized data.
This is why database interactions usually can be run on another thread, as you basically just shoot a bunch of (collected) data in the general direction of the database and "forget" about it - and when you want to retrieve data, you make a call (and forget about it), until you get a reply (or not).
For what it matters, you really don't have to worry about asynchronous programming all too much - especially when you are quite new to programming in general.
As long as you don't run "blocking" code on the main thread (e.g. those database calls you would need to wait for) or anything that really would benefit from being run asynchronously, you are good for anything else.
Basically this yeah π
technically, async doesn't mean not on the main thread π€
I tried that with the interaction event. However, when I open the inventory it still does the animation.
Also, something a lot of people don't realize is, that creating and switching thread-contexts is one of the more expensive operations for CPUs - therefor the benefits of putting some "simple" calculations into another thread can easily be outweighted by simply just switching to that thread to run it.
yeah iβve just not done any multithreaded programming or much async at all so was just wondering
seems powerful and interesting but seems difficult but i donβt know if i have any good use cases for it
It's quite powerful and useful to know
though for basic plugins you probably won't need it
It might be related to the fact that my values have great random distribution
And that the most sig bits are zeroes
Since I use your structure to save ipv4 values
Found another way in another plugin: when you open an inv, change to spectator mode
hello
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getItem() != null && event.getItem().getType() == Material.NETHERITE_AXE) {
Location location = event.getPlayer().getLocation();
ItemDisplay display = (ItemDisplay) location.getWorld().spawnEntity(location, EntityType.ITEM_DISPLAY);
display.setItemStack(event.getItem());
rotateDisplay(display, 0.5f);
}
}
private void rotateDisplay(ItemDisplay display, float speed) {
new BukkitRunnable() {
@Override
public void run() {
if (display.isDead()) {
this.cancel();
return;
}
Transformation transformation = display.getTransformation();
transformation.getLeftRotation().rotateZ(-speed);
display.setTransformation(transformation);
}
}.runTaskTimer(RandomThings.getPlugin(RandomThings.class), 0L, 1L);
}```
how do i make the itemdisplay face the player's direction?
am i the only weird one who appends this to every inner member field access from a class?
some people do that
it makes me clear where field belongs, + eliminates naming issues with field assignment in constructors
use the scheduler please instead of summoning random bukkitrunnables
should start counting how many times ive said this
Any ideas why doing import org.bukkit.Material isn't working check both screenshots for hierarchy of where Material.class is
https://imgur.com/a/CboGZWd
Update IJ
also that's Paper
yeah ik but idk where to ask about paper stuff
in the Paper discord ofc
oh i thought it was for people editing papers source code on git
but thats all good
cheers
nothing wrong with using BukkitRunnable
I use it if I have a local field I need to alter as it loops.
does minecraft use kotlin?
CompletableFuture<Unit> initialStage, boolean profiled) {
Unit object is kinda sus since its like Kotlin's Unit
Imagine if mc used kotlin we would be cooked bro
:pepela:
Decompiling that mess
we would NOT be π
Anything change in the PrepareAnvilEvent for 1.21? I have a set up to apply item skins (changing custom model data) and it seems to have stopped working, I setResult, it flashes then disappears
yea true
Not sure, but many things regarding registries took a change
enchantments are now fully server sided
oh I don't touch enchantments
just setting and getting custom model data. any changes with itemMeta?
Hi
https://wiki.vg/Protocol#Player_Action
How server can know the droped item ?
there is nothing that precludes the content of the item dropped in the packet
public class PrepareAnvilEventListener implements Listener {
@EventHandler
public void onPrepareAnvilEvent(PrepareAnvilEvent event) {
AnvilInventory inventory = event.getInventory();
ItemStack item = inventory.getItem(0);
ItemStack skinItem = inventory.getItem(1);
if(item == null || skinItem == null) return;
EasyItemSkins.debug("Item 1 = " + item.getType() + " Item 2 = " + skinItem.getType());
if(!SkinUtils.isItemSkin(skinItem)) return;
EasyItemSkins.debug("Item 2 is a skin item");
ItemSkin skin = SkinUtils.getItemSkinFromSkinItem(skinItem);
if(!SkinUtils.isCorrectSkin(item, skin)) return;
EasyItemSkins.debug("Item 2 is the correct skin for Item 1");
ItemStack skinnedItem = SkinUtils.applySkin(item, skin);
event.setResult(skinnedItem);
}
}```
this is running, and it attepts to set result
am i the only one who read that as "flashing contest"?
nope
ive only ever worked in one core plugin, but im starting to make independent plugins that are made available for more than just one network. im currently working on something that needs to interact with the servers economy, from what ive noticed all i really need to do is hook into the vault api and economy plugins handle the rest? seem accurate?
if those economy plugins support vault, yes
ye ^ that's what i figured
I'm sat next to an AC π
yeah I just turned it on
tbf I was at the gym where it was more like 38
because not working out when it's hot outside is just making excuses
though I do wish I had a way to put ice in my water
Theres the new invention called a refrigerator.
yeah, wish mine was bigger
or had one of those ice dispensers
the freezer is simply filled to the brim
really that thing is pressurized right now
yes in the space I don't have
i remember i forgot to take it out and it took a day to fully defrost
Hey could someone tell me how to create a npc in version 1.20.4?
have you even tried something?
help, I've tried nothing and I'm out of ideas
my poor ac is fighting its little heart out
it's a good unit it's just competing with the massive heat from outside plus my battlestation
poor thing
ac-chan can do it
that's kind of a lie, it does tend to overheat on days like these
but it eventually gets there
are you trying to hide the player from themselves?
if they're alone who would they be hidden from
hideEntity works fine. show code.
so im looking into minecraft default datapack for new data-driven enchantments
and i stumbled upon this
does this mean that in some rare case when you're enchanting using enchanting table, it could cost you 51 levels to enchant efficiency?
wtf
or is this xp amount not levels
i get that:
max_level maximum level of the enchantment (Efficiency I/II/III/IV/V)
max_cost/min_cost:
base -> cost of xp for the first level
per_level_above_first -> cost of xp per level (base + n * per_level_above_first)
not sure if that's right tho
Hi everyone!
I'm working on a plugin that places *SWEET_BERRY_BUSH * blocks where a thrown potion lands. I want these bushes to immediately reach their maximum age, but I'm unable to get them to grow. Here's my code:
public void placeBlock(Location location, Material material) {
Block placeBlock = location.getBlock();
placeBlock.setType(material);
BlockData blockData = placeBlock.getBlockData();
if (blockData instanceof Ageable) {
Ageable ageable = (Ageable) blockData;
ageable.setAge(ageable.getMaximumAge());
placeBlock.setBlockData(ageable);
getLogger().info("Set age to maximum for " + placeBlock.getType());
}
new BukkitRunnable() {
@Override
public void run() {
if (placeBlock.getType() == material) {
placeBlock.setType(Material.AIR);
}
}
}.runTaskLater(this, 200L);
}
Problem: The *SWEET_BERRY_BUSH * blocks never reach their maximum age and remain in their default state.
What I've tried: I logged the age setting, but I don't see any errors in the logs. The place-material and lifetime values are correctly set in the config.yml file.
Can anyone help me understand what might be going wrong or suggest anything else to try? Thank you!
another one using a bukkitrunnables instead of the scheduler
what Ageable are you importing?
org.bukkit.entity.Ageable;
will you not ninja me
no
any better way to get enchantment registry without joining the server in minecraft
@SuppressWarnings("unchecked")
private Registry<Enchantment> getMinecraftEnchantmentRegistry() {
return (Registry<Enchantment>) Registries.REGISTRIES.get(RegistryKeys.ENCHANTMENT.getValue());
}
i dont like this nasty unchecked cast
but i cant seem to find a hook where i can access this type safe way from main menu screen (fabric)
ik this isnt right place to talk about clientside mods, but knowing well that this is more a question regarding minecraft internal code, maybe you guys know?
You should be doing it on world join
i cant
Doing it from the main menu isn't safe/reliable as the data may vary
i need to fetch it in main menu
im hooking into datapack reload
so its safe
So not the main menu?
datapack reloads at splash screen too
i can, but i cant get the reference to registry
also for what purpose do you need it in the main menu?
i need to read default minecraft enchantments in registry
and they're only loaded at startup of the game
from what i see
yeah but why do you need them
i need to sync them in another data structure, im developing a mod for enchantments
How i can check when player uses ANY pickaxe not only for example diamond or ston
I still don't see why you need them in the main menu
because i need to resync my data structure when datapack reloads, and since 1.21 enchantments are data driven, they're defined in datapacks
so i need to get default minecraft enchantments asap
since singleplayer worlds do not reload default datapack
when you join
1.21
will check in a bit
i have another idea
that might work even better
instead of checking for datapack reload
i can use fabric-api's RegistryEntryAddedCallback event
which allows you to listen for registry changes
oh wow
i though where's remove method in registries
apprently it doesnt have one
strange
public interface MutableRegistry<T> extends Registry<T> {
RegistryEntry.Reference<T> add(RegistryKey<T> key, T value, RegistryEntryInfo info);
boolean isEmpty();
RegistryEntryLookup<T> createMutableEntryLookup();
}
Registries get frozen
yea but why add add() but not remove() its name is kinda not fitting
might get entirely wiped on reload ig
Registry should allow to remove entries
in minecraft sense it wouldnt make sense
since those are mostly loaded by datapacks anyways
lol i've gotten around this problem in a kinda hacky way but it works
so i hook into fabric-api's two events, one for datapack reloading and one, for player join
SimpleSynchronousResourceReloadListener listener = new RegistrySyncResourceReloadListener(mod.getEnchantments(), mod.getItemTypes(), MinecraftClient.getInstance());
ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(listener);
ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> listener.reload(client.getResourceManager()));
basically when player joins any kind of world it invokes the listener which would resync data structure with default minecraft datapack values (since there's no safe way to access enchantment registry at splash screen, and datapack reload event is too early to retrieve it from there) and if there is any datapacks, we take care of it by datapack reload event