#help-development
1 messages · Page 908 of 1
I'm just trying to run a spigot plugin in a development enviroment to test a few things. I have zero plugin dev, but copious modding experience. There has gotta be a thing where I can run the plugin in the development enviroment without having to compile it each time right?
ty
servers aren't friendly with hot reloading if you need you can just set this up yourself
spigot nor paper comes with any utilities to just start a server from your IDE out of the box afaik
....
I'm still trying to wrap my monkey brain around this!! How ta fuq do I go about making a api module for my plugin
. I want to depend on some libraries I relocate but if I add them as a compileOnly dependency SHIT EXPLODES and all hell breaks loose.
I just wanna test this plugin without having to compile it each time.
fantastic gradle plugin to start a server straight from your IDE for your plugin ^
should support hot reloading fine when started in debug mode
See @river oracle when coll sends the gif its more threatening
yeah see this is what I mean
I need staff now
That’s cuz I actually have a hammer
and you look more like yoshi yea
Y2K has one of those novelty foam hammers
I should have never turned down the offer of reccomendation from Conclure. I mean I could have threateningly sent the gif!!!
actually
my name is Y2K_ to you buddy
only the real ones call me miles
I hate to be that guy perpetuating the very serious paper spigot beef, but how could a paper contributer ever be a real one 
on the bright side I will send you a video of my cat as a peace offering
@eternal night I sent the peace offering 
wait
this you ?
with the shitty little 8 there
yeah :P wait till I get inventory PR going
I am more of a spigot contributor than you are
I can separate that into atleast 10
how can you be the real one
😨 listen man we can talk this out
@young knoll ban him bro ban him
he has too many valid poitns
I CANT TAKE IT
lay off bro I just sent you a video of my cat couldn't you be a bit nicer to me
ayo check under Y2K_ or something I think I have like 1 or 2 commits under than too
I am a dog person 💔
1 commit
okay we are beefing now
under Y2Kwastaken

yo guys do you like the open closed principle
you do a lot of talk for someone who hasn't contributed to Inventory PR
wrong crowd man I'm not a nerd I just code shit
who tf cares about OOP princples
Pleb uni I presume
I'm actually in highschool
I'm just dual enrolled full time at my local accreddited university
what how lmao
das public bro
genuinely wonder if this image is a good or bad thing lol
oh
privacy is dead 
true we are on discord
its all stored plain text 
You’ve done 8 PRs?
you can hide your contribution history
Tbf I thought it was less
but it makes you sus
Could not create task of type 'RunServer'.
Could not create an instance of type xyz.jpenilla.runtask.pluginsapi.DownloadPluginsSpec.
Could not generate a decorated class for type DownloadPluginsSpec.
Cannot have abstract method NamedDomainObjectSet.named().```
what gradle version do i need to use
8.6-all isn't latest?
do you use a root build.gradle.kts and then modules inside of its settings.gradle.kts
Yes i use a kotlin gradle
Enjoy 
isn't byte final anyway
ye its a final class ion need super
yea but generics don't care
It's not my plugin like I explained, however here's the source
https://github.com/GrimAnticheat/Grim/blob/2.0/build.gradle.kts
that project is using gradle 7.4
in its wrapper
I presume those are not compatible 
I just changed the version to 8.6-all
works perfectly fine for me
with the plugin added?
yea
Paper tax
the diff in question ^
(emitted changes to gradlew and gradlew.bat)
send me your whole build.gradle please
make absolutely sure your gradle wrapper is running 8.6
yea idk why but your impl works fine
nice 😅
idk how well it does hot re-loading, I think partially depends on IJ quirks
like
it does hot-reloading
it might not do deletion instructions
Is that more or less jank than /reload
Not a issue
Well, best of luck with it 
Idk replacing bytecode live sounds pretty janky
I mean, the JVM at least properly supports it 
It’s been a while but last I remember trying it I could only edit stuff
Trying to add or remove anything just imploded
Is this a deez nuts setup
DCEVM
but its kinda dead
most stuff is part of JetBrainsRuntime tho
but yea, for removal you need a custom flag too
Smh IntelliJ isn’t the only ide
Their runtime is packaged separately

This is my anvil listener code. Btw no outside classes with InventoryClick affect it, but for some reason when I for example combine a pickaxe and a custom enchanted book with Protection and a compatible custom enchantment the output slot does show the item with the correct lore and custom enchantment, but I cant take it out. and it doesnt get past: if (event.getSlotType() == InventoryType.SlotType.RESULT && event.getRawSlot() == 2) { so it is not like the methods get activated again.
Here is my code:
Thank you for helping in advance
Ah it was -XX:+AllowEnhancedClassRedefinition
-XX:+AllowEnhancedClassRedefinition -XX:+AllowRedefinitionToAddDeleteMethods -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 -Xlog:redefine+class*=info -XX:HotswapAgent=fatjar
right downloading the fucking hotswap
did they merge t hat into JBR
I recall they had it in DCEVM 11
it does not
fucking sadge
i didnt know about it till like a month ago and got annoyed when my lambdas wouldnt hotswap
Those are some wild startup args
hotswap agend is wild
What’s fatjar
a flag for the hotswap agend
Is it meant to point to something tho
no
did you download JBR and place the hotswap agend release in the folder it belongs to?
das the important part

No I’m not even on my pc :p
put it in libs/hotswap iirc
i wasnt
facts
got a question for y'all, since metadata is hella slow compared to other things, and currrently i am accessing the player's pickaxe's metadata every block which a no no, on my part
how else would i approach this
store the data i need in memory? Or what
You can do that, yeah
okay.. So how would i do this?
should i store it in the player's metadata instead then grab it everytime they join?
then store it in memory, ect
I recoded it now using PrepareAnvilEvent, but still I cant take the item out of the output slot.
Hmm, I’ve never had issue when doing it that way
Oh wait wait
I think you need to set a non-zero cost
oop, sorry lmao. Just some integer values and such for the pickaxe enchants
which im grabbing every block broken and is hella slow (as shown in the profiler)
which is a no no
store the data urself and just track the slot location
👍
i could also lock the pickaxe in slow 1
people dont like that
sounds like you had way too much pdc
some people have it in there 7th slot witha keybind
i'm creating it only once but im grabbing each enchant value everytime
ah yeah that
alr, wouldn't it just be easier to store it in the player's PDC?
instead of the item and i can grab it when the join and unload it when they leave
might be fine to do that then
just do periodic saving for modification and crash protection
sorry
all im storing
👍 ty
will do
I mean if it’s in the players pdc it’ll already be periodically saved
Assuming you update directly to the pdc
But putting it in a map is probably better
something something getting the itemmeta is expensive
if (attacker instanceof Spider) {
if (AttackerName.contains("§5King of Spider's Servant")) {
new BukkitRunnable() {
@Override
public void run() {
Vector up = player.getVelocity().setY(0).setX(0).setZ(0);
player.setVelocity(up);
player.sendMessage("Debug3333");
}
}.runTaskLater(this, 20L * 1L);
}
}```
any1 know why the bukkitrunnable doesn't run
ill swap to PDHs later
pretty sure Bukkit.getScheduler() is the more accepted way of doing it
AttackerName.contains("§5King of Spider's Servant") wont match
oh
use PDC
dont see why that owuldnt run otherwise
is it inside the main class?
'this' should be plugin instance
this is always the current instance of whatever class you use it in
?learnjava
For Beginners:
Codecademy - Learn Java: Interactive Java programming course from basics to more advanced concepts. Perfect for absolute beginners.
https://www.codecademy.com/learn/learn-java
JetBrains Academy - Java Developer Track: Learn by doing with projects and challenges. It covers Java fundamentals to advanced topics.
https://www.jetbrains.com/academy/
Udemy - Java Programming Masterclass for Software Developers: Updated courses that cover Java 8 to Java 17 features. Suitable for those who prefer structured learning.
https://www.udemy.com/course/java-the-complete-java-developer-course/
For Intermediate to Advanced Learners:
Oracle Java Tutorials: The official guides by Oracle for Java programming—great for understanding the depth of Java.
https://docs.oracle.com/javase/tutorial/
Baeldung - Learn Java and Spring: Focus on Spring Framework and modern Java technologies. Best for intermediate learners aiming to expand their knowledge.
https://www.baeldung.com/
Practice and Hands-on Learning:
Exercism - Java Track: Solve exercises and get feedback from mentors. Great for practicing coding skills.
https://exercism.io/tracks/java
LeetCode: Practice your coding skills and prepare for technical interviews with Java.
https://leetcode.com/
Free Resources and Documentation:
Java Programming and Documentation: A comprehensive collection of Java programming guides, tutorials, and API documentation.
https://docs.oracle.com/en/java/
Community and Support:
Stack Overflow: A vast community of developers. Great for getting help with specific problems or understanding concepts.
https://stackoverflow.com/questions/tagged/java
r/learnjava on Reddit: Join the community of Java learners and get advice, share resources, and discuss projects.
https://www.reddit.com/r/learnjava/
Remember: Learning to program takes practice and patience. Don't hesitate to experiment with code and participate in community discussions. Happy coding! 🎉
that was the error
however
if (attacker instanceof Spider) {
if (AttackerName.contains("§5King of Spider's Servant")) {
new BukkitRunnable() {
@Override
public void run() {
Vector up = player.getVelocity().setY(0).setX(0).setZ(0);
player.setVelocity(up);
player.sendMessage("Debug3333");
}
}.runTaskLater( TEST.getPlugin(), 20L * 1L);
}
}```
this doesnt cancel momentum
soo
no clue why
how do you deserialize a HashSet<>?
more specifically
Set<String> set = memorySection.getKeys(false);
for(String path : set){
String rawPath = path;
path = memorySection.getCurrentPath() + "." + path;
if(rawPath.equals("chunks")){
HashSet<Long> chunks;
chunks = (HashSet<Long>) Sylv.data.getConfig().get(path);
result.setChunks(chunks);
}
}
what do I use instead of .get() which returns a MemorySection, because there is stuff like, "getList()" but no "getSet()"
do i have to turn the HashSet to a list before serializing
a set and a list are really similar
You could just load it as a stringlist and convert?
Can’t you do new ArrayList(set)
Yeah it takes a Collection
no u
Hello, I need to implement a cooldown on my custom item, but for some reason the cooldown applies to the vanilla item, how can I fix this? (cooldown is implemented in the form of logic like end pearls)
Is it possible to distribute it only to your subject?
What
If you mean to only apply it to a specific item, no, you cannot do that
That's not how Minecraft's cooldown system works. It applies to the whole item type, not a specific item stack
I feel like it'd be a pain in the ass to track that
otherwise you'd just be able to switch to a new ender pearl and use it instead
It would just have to be timestamped in the NBT, not too bad all things considered
idek what that means
Oh, hash the meta and assign a value to it lol
yeah
but then if its meta changes
What if it just has empty meta
0
you aren't gonna be expecting ppl to /rename their enderpearls in 0.1ms
help im sleepy
You never know
oh ok, thanks
You could probably jank it with some resource pack magic
prob
just like
actionbar an overlay
bunch of offsets n stuff
it'd look a bit janky
but if you fine tune it all
But if you create an item with the NBT tag and put a cooldown on it, is this even feasible?
you can't really implement this yourself without a mod the real strategy here is to timestamp your PDC with bukkit. The downside is you don't get that cooldown effect you likely desire.
I'd suggest maybe doing something with the item/meta to make it look different when its cooling down. If you're already using a texture pack applying different model data is the obvious solution here
got it, thanks for the answer
a question nms is for a server version right?
if i want to make plugin work on all versions i would have to do extra coding right?
if it requires nms yeah
if you only need api you just use the lowest api you wanna support
wym?
do you use nms currently
How can I send "you are swear1 "?
Code:
public class AntiSwear implements Listener {
public static String maskSwearWord(String word) {
if (word.length() <= 2) {
return word;
}
return word.substring(0, 2) + "*".repeat(word.length() - 2);
}
private static final String[] knownMessage = {
"swear1",
"swear2"
};
@EventHandler
public void onPlayerSendMessage(AsyncPlayerChatEvent event) {
Player player = event.getPlayer();
String message = event.getMessage();
String blocketmessage = "Swear Word";
for (String knownMessage : knownMessage) {
if (message.contains(knownMessage)) {
player.sendMessage(blocketmessage);
String maskedMessage = message.replace(knownMessage, maskSwearWord(knownMessage));
event.setMessage(maskedMessage);
for (Player allplayer : Bukkit.getOnlinePlayers()) {
if (allplayer.hasPermission("group.admin")) {
allplayer.sendMessage("Der Spieler " + player.getName() + " hat versucht " + message + " zu sagen");
}
}
}
}
}
}
You want to use a loop with an int counter not enhanced for loop and then print counter value
Is there no getClientViewDistance in 1.12.2?
I doubt the client had that in 1.12.2
int chunkDistanceX = Math.abs(playerChunk.getX() - npcChunk.getX());
int chunkDistanceZ = Math.abs(playerChunk.getZ() - npcChunk.getZ());
return chunkDistanceX <= viewDistance && chunkDistanceZ <= viewDistance;
}``` I need to process the player's approach to the NPC in playermovevent, or more precisely the moment when the player sees the npc in order to send packets
I am currently sending packets for fake nms npc only when logging into the game
view-distance=10 that is, can I use the default value from server.properties?
Sure
it is too big, I have moved to a very large value and it is still being executed
that is, I will move 100-200 blocks away and only then will it stop
would it be possible to replace a player with a zombie? So instead of displaying a player to other players it displays a zombie
I thought of that before, I'd like to know the answer too
I mean there was that diguise plugin that did it
Sadly you can’t do it for the player hidden
what is the difference between CLIENTBOUND and SERVERBOUND nms fake entity
Is there a way to get blockface of bed?
this code doesn't works 😦
Bed bed = (Bed) block.getBlockData();
System.out.println(bed.getPart());
Location loc = block.getLocation();
bed.getFacing();
Well this code has a lot of dead code in it. What do you expect it to do?
I wanna get another location of bed block
Then get the block in the facing direction
how can I get the facing direction of block?
Bed bed = (Bed) block.getBlockData();
BlockFace facing = bed.getFacing();
Then show your code
Wrong import
is org.bukkit.block.data.type.Bed wrong?
It throws ClassCastException
Get the type of the block
Did you check if the Block is actually a Bed first?
And print it out, doesn't seem like the block is actually a Bed
yeah I checked 😓
Well, check again 😆
Ok before anyone gives any more advice:
Show your whole code and any exception you encountered.
This could have been solved minutes ago
?paste
?nocode
It’s hard to answer a programming question without code
Oh no! You ran into a problem. But no worries, people are willing to help, but first they need to see your code. This is because otherwise, they would be providing help based on guesses instead of concrete knowledge. Whether it be a compile error, runtime error, or an unexpected output, I'm sure that if you were to provide code, you'd receive a quick solution.
https://paste.md-5.net/ukotocixol.java
It is caused in line 174 (public void destroy)
OH
300 iq move
my eye is gone because of lot of code :🥲
That's why you should separate things out a bit imo
But that's for a different topic
?
anyways, thanks 🙂
Btw... what am i seeing here?
Does it have any problems?
that looks like
pdc.clear();
But with a lot of unnecessary code
OMG
please tell me someone)
there is no clear method in pdc
ClientBound means its heading is bound to the client (The packet will be sent to the client from the server)
ServerBound means the heading is bound to the server (The packet will be sent to the server from the client)
Those have nothing to do with nms fake entities. Those are only prefixes for packets so you know where they will be sent to.
Why dont you just create a new empty pdc? (I assumed it was a map)
cause it's final field
can you take a look at my current code of my nms npc entity?
What version? I was honestly about to prepare breakfast and coffee...
now it looks much better, but there are questionable points that make something not work as expected
1.12.2 it shouldn't take you long, you can come back to it when you have free time) I appreciate your help
Sure, send it
The NPC entity spawns well only when the player enters the sevrer.
[11:50:51 INFO]: visible```
after deleting the entity and when I go back to it, it only shows up in the tab but does not spawn
Those two lines should be removed.
You dont want a fake entity to be added to the world.
I'm also worried that the entity will disappear for other players and not just for 1 player who has moved away from the entity.
Btw in 1.12 you can just listen to the ChunkLoadEvent and send All NPCs in that chunk to all players.
Then in the ChunkUnloadEvent you simply hide them from all player.
The client decides himself when to display them.
No need to listen for all that PlayerMove stuff
thanks
Hm. Honestly if you want a proper fake entity, then you dont need to extend EntityPlayer.
Just create a new class with all the needed properties (GameProfile etc) and then send packets to players.
Here is how that looks for one of my implementations:
The sendTo simply looks like this
Send the despawn and remove info packet
1.12.2)
Yes in 1.12 it should be the same. Despawn packet or its called entity destroy i think, and after that you send the info hide packet
or its called info update with the enum action REMOVE
This one hides the entity, right
Cant remember 1.12 protocol by heart. That came out before i started developing
should I send packets to all players or should I send packets to all players in the chunk?
ChunkLoadEvent
To all players
the entity stopped spawning after deleting those two lines
Good. This means almost all of your code was flawed.
Now make sure to send those packets and debug it.
exactly, I did not send the PlayOutNamedEntitySpawn packet before, it kicked me with errors
Maybe it will work now
error
```
cause
Well... sending an empty packet confuses the client ofc.
Show me your method setupSpawnPacket please
so connection.sendPacket(new PacketPlayOutNamedEntitySpawn(entity.getBukkitEntity().getHandle()));
entity.getBukkitEntity().getHandle() is the same as just entity
*If entity is your EntityPlayer
unfortunately, I see the entity only in the tab ```java
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) throws IOException {
Player p = event.getPlayer();
if ((int) p.getLocation().getX() >> 4 == Npc.nurseChunk.getX() && (int) p.getLocation().getZ() >> 4 == Npc.nurseChunk.getZ()) {
CraftPlayer ep = hasEntityPlayer(p.getLocation().getChunk());
if (ep == null) {
EntityNurse entity = EntityNurse.create("Nurse", Npc.plugin.getServer().getWorld(Npc.plugin.getConfig().get("world").toString()), Npc.nurseLocation);
PlayerConnection connection = ((CraftPlayer) event.getPlayer()).getHandle().playerConnection;
connection.sendPacket(new PacketPlayOutNamedEntitySpawn(entity.getBukkitEntity().getHandle()));
PacketPlayOutPlayerInfo info = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, entity);
connection.sendPacket(info);
}
else {
PlayerConnection connection = ((CraftPlayer) event.getPlayer()).getHandle().playerConnection;
connection.sendPacket(new PacketPlayOutNamedEntitySpawn(ep.getHandle()));
PacketPlayOutPlayerInfo info = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, ep.getHandle());
connection.sendPacket(info);
}
}
}```
public static EntityNurse create(String name, World world, Location location) throws IOException {
MinecraftServer nmsServer = ((CraftServer) Bukkit.getServer()).getServer();
WorldServer nmsWorld = ((CraftWorld) world).getHandle();
UUID uniqueId = UUID.randomUUID();
GameProfile playerProfile = new GameProfile(uniqueId, name);
EntityNurse nurse = new EntityNurse(nmsServer, nmsWorld, playerProfile, new PlayerInteractManager(nmsWorld));
nurse.getProfile().getProperties().clear();
nurse.getProfile().getProperties().removeAll("textures");
nurse.getBukkitEntity().setRemoveWhenFarAway(false);
nurse.setCustomName("nurse");
nurse.setLocation(location.getX(), location.getY(), location.getZ(), location.getPitch(), location.getYaw());
nurse.playerConnection = new PlayerConnection(nmsServer, new NetworkManager(EnumProtocolDirection.SERVERBOUND), nurse);
return nurse;
}```
Stop filtering your spawns by distance or if they are in the same chunk.
Also: You need to send the player info before you can send the named entity.
Bc otherwise you are trying to spawn a player with completely unknown properties.
private static CraftPlayer hasEntityPlayer(Chunk chunk) throws IOException {
for (Entity entity : chunk.getEntities()) {
if (entity.getCustomName() != null && entity.getCustomName().equals("nurse")) {
return (CraftPlayer) entity;
}
}
return null;
}
@EventHandler
public void onChunkLoad(ChunkLoadEvent event) throws IOException {
Chunk chunk = event.getChunk();
CraftPlayer ep = hasEntityPlayer(chunk);
if (ep != null) {
System.out.println("visible");
for (Player p : Bukkit.getOnlinePlayers()) {
PlayerConnection connection = ((CraftPlayer) p).getHandle().playerConnection;
PacketPlayOutPlayerInfo info = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, ep.getHandle());
connection.sendPacket(info);
connection.sendPacket(new PacketPlayOutNamedEntitySpawn(ep.getHandle()));
}
}
}
@EventHandler
public void onChunkUnload(ChunkUnloadEvent event) throws IOException {
CraftPlayer ep = hasEntityPlayer(event.getChunk());
if (ep != null) {
for (Player p : Bukkit.getOnlinePlayers()) {
PlayerConnection connection = ((CraftPlayer) p).getHandle().playerConnection;
connection.sendPacket(new PacketPlayOutEntityDestroy());
PacketPlayOutPlayerInfo info = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, ep.getHandle());
connection.sendPacket(info);
System.out.println("invisible");
}
}
}``` the next problem is that most likely hasEntityPlayer does not work, because even if I teleport 1000 blocks away from the entity and return, I do not see invisible and visible messages in the console
You never add the entity to the world, so the server has no idea that it exists so you cant rely on the
server to know if its in a chunk or not. Thats something you have to track yourself.
i can add entity id argument to the packetconnection.sendPacket(new PacketPlayOutEntityDestroy(ep.getEntityId()));
Hi, I am writing a plugin for minecraft and I have a question. How to make a file with localization correctly. So that plug-in users can change any plug-in text into their own language in the config. I would also like the localization file to be uploaded only 1 time.
Why not just add an entity to the world?
Anyways you should take two steps back and maybe create a few more classes.
This is currently so patched up and messy.
Create an NPCManager which tracks all your NPCs and in which chunks they are.
- Create a config file
- Load its values when the server starts
- Use the values in your code
?
does your npc plugin have a github?
I want to see it
when I added the entity to the world, minecraft crashed)
Do all bukkit async tasks run on the same seperate thread, or does each async task create its own thread?
Was a while back when i looked into this but i think they use some sort of thread pool or factory.
So not the same thread for all tasks.
Nope thats closed source.
Dont add them to the world
This makes them not virtual anymore
So if my server has only 3 threads (one for the main) does that mean I can only have two async tasks running at the same time? Or how many can I have?
I don't quite understand how I can track entities in a separate class and how to use this class.
no.. threads are a separate thing. you can run a lot more async tasks
and how to interact with entity?
playerinteractentityevent
not working
You should def use an NPC library like citizens then and write a few more plugins.
Because this approach (Having a manager class and tracking stuff) is something you will need for every plugin.
hey gang just wondering if there's a way to create an itemstack of a item frames that have their visibility toggled off?
you can add a custom PDC tag to the itemstack and then in HangingPlaceEvent, check the itemstack and if it has that tag too, then make the placed itemframe invisible
Alex what time is it
11:44
Thx
crud ok a little messier than I was hoping but ok ok, thank you 🙂
Pretty much yes
but u can have a lot more than 3 threads
3 threads is not realistic
when a thread is blocked (lets say it awaits some io stuff) its then suspended
he's probably talking about some mc hosting company that sells "4gb 2 vcores (threads)" or sth similar and the answer is, he can still schedule 100+ async tasks
yeah the whole physical/virtual/OS thread thing can be confusing
Myea, tho its not always practical
The amount of available processors is usually a good number to base ur thread pools and other mechanisms on (well ofc doesnt rly apply to virtual threads)
When i create more threads than my PC has and let them do tasks at the same time will it crash?
ofc not - open your task manager
Probably not
Depends on the tasks ur making the jvm do memory limit is a thing
I only have 8 cores and not 1500
I think ur lying
Threads are infinite?
I thought there where always 8 cores and then 16 Thresds so always double
physical threads =/= virtual threads
Okay
there is a limit to how many threads you can address in java but it's pretty high
high enough to the point where if you are hitting that limit you are doing something very wrong
You have os threads then jvm threads getting mapped to those, and then virtual threads and coroutines getting mapped to the jvm ones more or less
a mapping can usually even be surjective
What if i have a thread for each method will i have the fastest program ever?
depends
However, you can't just creat a 100 threads and say I have 100x performance. This is where the cores come into picture.
Usually you either wanna minimize waiting time (that is doing something async like downloading a file), or u wanna distribute a computation that takes long time
when distributing a computation, its rarely ever worth to allocate a billion threads or so, as its still only gonna use what cpu hardware resources u have available, so limiting it to the amount of available processors is usually reasonable
Ok
Is it possible to make the plugin API a separate plugin like in Citizes and his API?
it would be more accurate to make it public for maven, but the implementation itself is not
public class NPCManager {
private static Map<UUID, CraftPlayer> npcMap = new HashMap<>();
public static CraftPlayer hasEntityPlayer(Chunk chunk) throws IOException {
for (CraftPlayer p : npcMap.values()) {
System.out.println(((int) p.getLocation().getX() >> 4) + " " + chunk.getX() + " " + ((int) p.getLocation().getZ() >> 4) + " " + chunk.getZ());
if ((int) p.getLocation().getX() >> 4 == chunk.getX() && (int) p.getLocation().getZ() >> 4 == chunk.getZ()) {
return p;
}
}
return null;
}
public static void addNpc(CraftPlayer npc) {
npcMap.put(npc.getUniqueId(), npc);
}
public static void removeNpc(UUID npcId) {
npcMap.remove(npcId);
}
public static CraftPlayer getNpc(UUID npcId) {
return npcMap.get(npcId);
}
public static List<CraftPlayer> getAllNpcs() {
return (List<CraftPlayer>) npcMap.values();
}
} -12 -3 -2 -12
[14:30:39 INFO]: -12 -22 -2 -12
[14:30:39 INFO]: -12 -2 -2 -12
[14:30:47 INFO]: -12 -23 -2 -7
[14:30:47 INFO]: -12 -23 -2 -6
[14:30:47 INFO]: -12 -23 -2 -5
[14:30:47 INFO]: -12 -23 -2 -4
[14:31:07 INFO]: -12 -23 -2 -7
[14:31:07 INFO]: -12 -23 -2 -5
[14:31:07 INFO]: -12 -23 -2 -6
[14:31:07 INFO]: -12 -23 -2 -4
[14:31:58 INFO]: -12 -23 -2 -7
[14:31:58 INFO]: -12 -23 -2 -6
[14:31:58 INFO]: -12 -23 -2 -5
[14:31:58 INFO]: -12 -23 -2 -4
[14:32:07 INFO]: -12 -23 -2 -7
[14:32:07 INFO]: -12 -23 -2 -5
[14:32:07 INFO]: -12 -23 -2 -6
[14:32:07 INFO]: -12 -23 -2 -4``` something is wrong with the chunk coordinates(hasEntityPlayer)
how do I do this in a better way?
what is wrong with the coordinates?
No. The method is useless to begin with. The server doesnt know that the entity exist and it also should never know that the entity exists.
@EventHandler
public void onChunkLoad(ChunkLoadEvent event) throws IOException {
Chunk chunk = event.getChunk();
CraftPlayer ep = NPCManager.hasEntityPlayer(chunk);
if (ep != null) {
System.out.println("visible");
for (Player p : Bukkit.getOnlinePlayers()) {
PlayerConnection connection = ((CraftPlayer) p).getHandle().playerConnection;
PacketPlayOutPlayerInfo info = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, ep.getHandle());
connection.sendPacket(info);
connection.sendPacket(new PacketPlayOutNamedEntitySpawn(ep.getHandle()));
}
}
}
@EventHandler
public void onChunkUnload(ChunkUnloadEvent event) throws IOException {
CraftPlayer ep = NPCManager.hasEntityPlayer(event.getChunk());
if (ep != null) {
for (Player p : Bukkit.getOnlinePlayers()) {
PlayerConnection connection = ((CraftPlayer) p).getHandle().playerConnection;
connection.sendPacket(new PacketPlayOutEntityDestroy(ep.getEntityId()));
PacketPlayOutPlayerInfo info = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, ep.getHandle());
connection.sendPacket(info);
System.out.println("invisible");
}
}
}```then how do I use these two methods?
what should I do next, I created the npcmanager class
but it doesn't make sense yet.
Packet based NPC's don;t exist on the server
Only your plugin knows about them, and the client you told
then how to implement what 7smile7 was talking about
Then in the ChunkUnloadEvent you simply hide them from all player.
The client decides himself when to display them.```
Correct, so YOU track where your fake NPC's are
how to determine which NPC is in loaded chunk
just save it bro
?
when you created it you shoudl have given it a position
?
1.12.2)
ofc
but it shouldn't be a separate plugin
how will the API get access to the implementation if to create a repository the implementation must be open source
why would the API need access to the implementation?
here's an example. The API is just some interfaces that doesn't do anything: https://github.com/JEFF-Media-GbR/AngelChestAPI
then the actual plugin shades the API and implements it. You only have to publish the API
@EventHandler
public void onChunkLoad(ChunkLoadEvent event) throws IOException {
Chunk chunk = event.getChunk();
if (chunk == null || !chunk.isLoaded()) {
return;
}
System.out.println("NurseChunk X: " + Npc.nurseChunk.getX() + ", Z: " + Npc.nurseChunk.getZ());
System.out.println("Loaded Chunk X: " + chunk.getX() + ", Z: " + chunk.getZ());
if (Npc.nurseChunk.getX() == chunk.getX() && Npc.nurseChunk.getZ() == chunk.getZ()) {
for (CraftPlayer npc : NPCManager.npcMap.values()) {
System.out.println("visible");
for (Player p : Bukkit.getOnlinePlayers()) {
PlayerConnection connection = ((CraftPlayer) p).getHandle().playerConnection;
PacketPlayOutPlayerInfo info = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, npc.getHandle());
connection.sendPacket(info);
connection.sendPacket(new PacketPlayOutNamedEntitySpawn(npc.getHandle()));
}
}
}
}``` I haven't been able to figure out these chunks for a long time. is there an event for loading a chunk on the client side or is that not the case? it's just that nursechunk and loadedchunk show me completely different chunks coords, although I'm right in the npc chunk
I'm not using the position of an entity that the server doesn't know about, but a variable with coordinates, but it still doesn't work
Show your manager class.
Without that you have exactly a 0% chance getting this to work
public static Map<UUID, CraftPlayer> npcMap = new HashMap<>();
public static void addNpc(CraftPlayer npc) {
npcMap.put(npc.getUniqueId(), npc);
}
public static void removeNpc(UUID npcId) {
npcMap.remove(npcId);
}
public static CraftPlayer getNpc(UUID npcId) {
return npcMap.get(npcId);
}
}```
I do not know what to add to the manager
What do you want it to do?
you really should stop adding static to everything
but in this case, it shouldn't cause any problems.
static is almost always a problem.
Start by making all your fields private and and remove the static keyword from everything.
After that you should create a class called ChunkPosition which holds x and z ints.
Then expand your class with a Map<ChunkPosition, List<NPC>>
the few cases where it's okay is like constants or the singleton pattern
Static managers are fine arent they?
They're using static on a lot more than just that
pretty much all of their code is static
Really?
i wouldn't make my manager classes static
^ this too
Sometimes its appropriate to make your managers singletons, but they shouldn’t inherently be static, only if there is good reason to do so
Hello i have a problem with VaultAPI, I try to do an economy plugin with the vault API, I have add the depedencies in my plugin ans I have install vault in the server but when I start the server the plugin was disabled for "No vault plugin foud", do you know how I can fix that ?
Your vision is quite narrow if this is the only reason for u to make something static, you have to consider eventual consumers of your class, maintainability in the long run, does it incorporate statefulness - in such case what about thread safety, is your manager going to be testable, etc
Where can i get ideas to code? i am not creative so i cant really come up with ideas 😭
Create a chatmanager
explain a bit more
Nobody have a response for me ? #help-development message
?nocode
It’s hard to answer a programming question without code
Oh no! You ran into a problem. But no worries, people are willing to help, but first they need to see your code. This is because otherwise, they would be providing help based on guesses instead of concrete knowledge. Whether it be a compile error, runtime error, or an unexpected output, I'm sure that if you were to provide code, you'd receive a quick solution.
something like this?```java
manager = new NPCManager();
try {
manager.addNpc(EntityNurse.create("nurse", Npc.plugin.getServer().getWorld(Npc.plugin.getConfig().get("world").toString()), nurseLocation).getBukkitEntity(), nurseChunk.getX(), nurseChunk.getZ());
} catch (IOException e) {
e.printStackTrace();
}
EventListener eventListener = new EventListener(manager);
getServer().getPluginManager().registerEvents(eventListener, this);
public class NPCManager {
private Map<ChunkPosition, List<CraftPlayer>> npcMap = new HashMap<>();
public void addNpc(CraftPlayer npc, int chunkX, int chunkZ) {
npcMap.computeIfAbsent(new ChunkPosition(chunkX, chunkZ), k -> new ArrayList<>()).add(npc);
}
public List<CraftPlayer> getNpcsInChunk(int chunkX, int chunkZ) {
return npcMap.getOrDefault(new ChunkPosition(chunkX, chunkZ), Collections.emptyList());
}
private static class ChunkPosition {
private final int x;
private final int z;
public ChunkPosition(int x, int z) {
this.x = x;
this.z = z;
}
}
@EventHandler
public void onChunkLoad(ChunkLoadEvent event) throws IOException {
Chunk chunk = event.getChunk();
if (chunk == null || !chunk.isLoaded()) {
return;
}
for (CraftPlayer npc : manager.getNpcsInChunk(chunk.getX(), chunk.getZ())) {
System.out.println("visible");
}``` still not working
You were asking for ideas 🤷♂️
Yeah i know
Inside my main class
public static Economy econ = null;
on enable{
if (!setupEconomy() ) {
getLogger().severe(String.format("[%s] - Disabled due to no Vault dependency found!", getDescription().getName()));
getServer().getPluginManager().disablePlugin(this);
return;
}
}
private boolean setupEconomy() {
if (getServer().getPluginManager().getPlugin("Vault") == null) {
return false;
}
RegisteredServiceProvider<Economy> rsp = getServer().getServicesManager().getRegistration(Economy.class);
if (rsp == null) {
return false;
}
econ = rsp.getProvider();
return econ != null;
}
public static Economy getEconomy() {
return econ;
}
error
[13:23:57] [Server thread/INFO]: [KingdomCore] Enabling KingdomCore v1.0.0
[13:23:57] [Server thread/ERROR]: [KingdomCore] [KingdomCore] - Disabled due to no Vault dependency found!
[13:23:57] [Server thread/INFO]: [KingdomCore] Disabling KingdomCore v1.0.0
but like what does the chatmanager do?
why do you print "No Vault dependency found" when you're actually checking for an economy provider?
well it looks like you don't have any economy plugin installed
Maybe Filter Bad words
You likely don;t have an Economy plugin
Yes but I try to do a economy plugin but I need the api from vault to do it
then why are you disabling your own plugin?
you are supposed to register the economy provider yourself
that's just the vault api docs copypaste
idk that a good question xD
yep
you have to implement the Economy class yourself and then register it
or install essentialsx...
I said earlier that the problem is not static abusing, although yes, the code looks better this way
Sry for the question I think I just tired xD Have a good day lmao
then depends on what kinda economy plugin yk
economy plugin can extend in twenty million branches
like, inflation, corruption etc
damn
not just i give money you get money monke
here is top bal
i want my money to depreciate
that plugin would need to also be a shop plugin and stuff yk
economy 2000
2024*
lol
let's call our plugin Rubleconomy
what better way to represent a plugin with inflation and corruption than the ruble
trueee
actually let it be just an "ActualEconomy" and then there are modes like "ruble", "usd", "yen", etc
that define the rate of inflation, corruption and pricing of goods
alrigth
and i guess like
pull actual data from some rest
for accurate currency conversion and pricing
How can I make it so that you can write everything in but only the word is filtered?
e.g. "you are swear1 "
Code:
public class AntiSwear implements Listener {
public static String maskSwearWord(String word) {
if (word.length() <= 2) {
return word;
}
return word.substring(0, 2) + "*".repeat(word.length() - 2);
}
private static final String[] knownMessage = {
"swear1",
"swear2"
};
@EventHandler
public void onPlayerSendMessage(AsyncPlayerChatEvent event) {
Player player = event.getPlayer();
String message = event.getMessage();
String blocketmessage = "Swear Word";
for (String knownMessage : knownMessage) {
if (message.contains(knownMessage)) {
player.sendMessage(blocketmessage);
String maskedMessage = message.replace(knownMessage, maskSwearWord(knownMessage));
event.setMessage(maskedMessage);
for (Player allplayer : Bukkit.getOnlinePlayers()) {
if (allplayer.hasPermission("group.admin")) {
allplayer.sendMessage("Der Spieler " + player.getName() + " hat versucht " + message + " zu sagen");
}
}
}
}
}
}
uh
I'd prob just use regex for this tbh
You could also go with an iterative solution
?
Can someone tell me the name of some app to see .jar codes?
jd-gui, recaf
Had one but don't remember the name
k thanks
Recaf lets you edit code and has a dark mode but jd-gui feels faster
Yea, i used jd-gui
I've already seen that it doesn't work
Do I need to create the NamespacedKey once and save it somewhere and then use it? Or can I create a new one several times?
Soo, how to get If entity is in the block of nether portal without entity teleport event
?
PlayerMoveEvent for players otherwise you don't
I'll try, but i'm not sure that it will work
IT WORKS
Thanks
Im trying to make it so composter gets filled instantly after the composter level gets above 1. This code works but updates the composter to filled only if I left click or right click with a non compostable item. I think when I right click with a compostable item in hand, instead of my code running and instantly setting the level to filled, minecraft overwrites it with it's code of progressing the level of composter normally. any way to fix it?
Hey! I am just wondering what the best way to store and load player inventorys would be?
e.g:
user leaves - save users inventory in db
user joins - load users inventory from db with all the correct information such as name, lore, nbt data etc
I dont want to be spoonfed i want to be given a path u can say
Does anyone know how to fix this?
java.lang.IllegalStateException: Cannot query another world's (world_nether) chunk (-3, -1) in a ServerLevelTickThread
show the full stacktrace
BukkitObjectInput/OutputStream can convert items to/from byte[]
what the heck is sparklypaper :X
?whereami
Btw it supports spigot plugins lol
So does paper
Alright thanks i will have a look
That doesn't make this paper support
Seems like the do some wacky one thread per world thing
So that's probably your issue
Yeah, it separates every world with Parallel World Ticking, so, nether portal can't teleport mobs, and I was trying to fix it, but it didn't work
a fun fork!
Some of their patches made it into paper
some other are too experimental to pull or very specific to the usage of the software
the maintainer is a chill guy tho
Oh did we absolutely destroy a vanilla mechanic? oopsies
happens
:/
Smh I really should just sell my revolutionary paper fork that removes all ticking
For optimization it's really good
$349.99
At least its not one of the "oh I just collect patches from every fork under the moon" fork
More patches = more good
there was a folia fork somewhere that added synchronized to everything to "improve plugin compat"

We need more of such revolutionary thinking
I would recommend you to tackle something a bit easier. NPCs are already really hard.
Have you written a lot of other plugins before?
I don’t understand how to separate the api and its implementation from each other so that another plugin can connect and use the api and its implementation through maven, but so that the implementation itself in the form of source code or a Jar file is not available
i mean how create repository for this
You provide two jars. One with only the api (and can be shaded).
And one with the api and its implementation (this will be deployed on the server)
but if I connect only the API, I will have access to the implementation
The jar with only the API doesnt have an implementation
very little. about 6
Sorry, I misspoke, I mean I won’t get it
Oh yeah. You dont want that. The api doesnt need to know the implementation.
I handed over my code. can you take one last look at it, now it should meet requirements?
?paste
🙂
and how to access 1 API implementation created for its interface?
Hey, was wondering if there was a fastest way to do this checks?
Use a map
https://paste.md-5.net/amezonitaj.java the only problem is the playerinteractentity event doesn't work and chunkloadevent isn't called all the time when I'm near the entity
iirc there is Block#getDrops
but overall it works better.
I just don’t understand how the api will understand that I am accessing 1 of its implementations through the api
oh, ok thanks
if I connect only api
I had to use the block position because the regular one didn't work in chunkloadevent(*16)
You need a gateway where the api user can request the implementation at runtime
The manager looks good so far
what the gateway
wdym
seeing the word nurse over and over is starting to scare me
chunk.getX()*16, chunk.getZ()*16 this makes no sense.
Just use the chunkX and Z
isNPCVisible remove this method
but it doesn't work without multiply by 16 in chunkloadevent
What exactly doesnt work?
it just throws different coordinates of chunks when I am in the npc chunk, but not the coordinates of the npc chunk themselves.
playerjoinevent is working but chunkloadevent is not
without blockposition
Remove this method
public static boolean isNPCVisible(int chunkX, int chunkZ) {
int chunkDistanceX = Math.abs(chunkX - Npc.nurseChunk.getX()*16);
int chunkDistanceZ = Math.abs(chunkZ - Npc.nurseChunk.getZ()*16);
return chunkDistanceX <= 1.0F && chunkDistanceZ <= 1.0F;
}
And then use the chunk X and Z.
To get the chunk X and Z from your entity you have to divide its location X and Z by 16
Here as well
and there manager.addNpc(EntityNurse.create("Медсестра", Npc.plugin.getServer().getWorld(Npc.plugin.getConfig().get("world").toString()), nurseLocation).getBukkitEntity(), nurseChunk.getX() * 16, nurseChunk.getZ() * 16);
I need to remove the multiplication by 16 everywhere?
Yes. Multiplying by 16 everywhere is kind of pointless. The only thing you need to do is divide the location by 16
if I divide the coordinates of the chunk by 16, do I get the absolute coordinates?
I just need to compare the distance between the npc and the unloaded chunk
No it gives you a useless value
Why?
if the distance, for example, is more than 10, i need to send remove entity packets
ChunkUnloadEvent
Oh I'm confused
ChunkLoadEvent:
- Get all NPCs in this chunk from your manager
- Send all players the spawn packets for the NPCs
ChunkUnloadEvent:
- Get all NPCs in this chunk from your manager
- Send all players the despawn packets for the NPCs
You never need to check any distance to anything
@EventHandler
public void onChunkLoad(ChunkLoadEvent event) {
Chunk chunk = event.getChunk();
for (CraftPlayer npc : manager.getNpcsInChunk(chunk.getX(), chunk.getZ())) {
System.out.println("visible");
for (Player p : Bukkit.getOnlinePlayers()) {
PlayerConnection connection = ((CraftPlayer) p).getHandle().playerConnection;
PacketPlayOutPlayerInfo info = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, npc.getHandle());
connection.sendPacket(info);
connection.sendPacket(new PacketPlayOutNamedEntitySpawn(npc.getHandle()));
npcSpawned.put(p, true);
}
}
}
@EventHandler
public void onChunkUnload(ChunkUnloadEvent event) throws IOException {
for (CraftPlayer npc : manager.getNpcsInChunk(Npc.nurseChunk.getX() , Npc.nurseChunk.getZ() )) {
if (npc != null) {
for (Player p : Bukkit.getOnlinePlayers()) {
if (npcSpawned.containsKey(p) && npcSpawned.get(p)) {
PlayerConnection connection = ((CraftPlayer) p).getHandle().playerConnection;
connection.sendPacket(new PacketPlayOutEntityDestroy(npc.getEntityId()));
PacketPlayOutPlayerInfo info = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, npc.getHandle());
connection.sendPacket(info);
npcSpawned.put(p, false);
System.out.println("invisible");
}
}
}
}
}```can you tell me where I should apply the division by 16
First you are going to remove your "npcSpawned" collection because you are not using it in any meaningful way.
Next you should clean up those methods there is too much nesting going on.
Inside your NPC class add the following methods:
public void showTo(Player player) {
}
public void hideFrom(Player player) {
}
After that you simply apply those methods for chunk loads and unloads.
@EventHandler
public void onChunkLoad(ChunkLoadEvent event) {
Chunk chunk = event.getChunk();
for (CraftPlayer npc : manager.getNpcsInChunk(chunk.getX(), chunk.getZ())) {
for (Player player : Bukkit.getOnlinePlayers()) {
npc.showTo(player);
}
}
}
@EventHandler
public void onChunkUnload(ChunkUnloadEvent event) throws IOException {
Chunk chunk = event.getChunk();
for (CraftPlayer npc : manager.getNpcsInChunk(chunk.getX(), chunk.getZ() )) {
for (Player player : Bukkit.getOnlinePlayers()) {
npc.hideFrom(player);
}
}
}
The division comes into play for your NPC manager:
public void addNpc(CraftPlayer npc) {
int chunkX = npc.getX() / 16; // Something like that. Location X / 16
int chunkZ = npc.getZ() / 16; // Same here
npcMap.computeIfAbsent(new ChunkPosition(chunkX, chunkZ), key -> new ArrayList<>()).add(npc);
}
@sterile flicker I changed the unload method again, because your nurse chunk in there is also weird
Hi , i am writing a plugin about ip but is there a question on my mind that can Player spoof ip and use other Player's ip?
Also: You wont be able to use CraftPlayer in your manager. It needs to be your custom NPC or else they dont have your custom methods.
The packets going back wouldnt reach the sender again. Spoofing can only be done with a man in the middle attack.
So its very rare to have that happen.
so do you mean only in the middle attack or when server is attacking is possible ?
The IP address is taken from the TCP packet (Which builds on the IP packet containing the IP address).
All packets will be sent back to the sender listed in the packet. If you dont actually have that IP address, then the routing
will send those answer packets back to the original owner of that IP address, making your "spoof" practically useless.
You would have to own the entire route or a critical choke point between the attacker and the server.
So right at your servers host location, or right at the house of the spoofed player.
if (player.getItemInUse().containsEnchantment(Enchantment.SILK_TOUCH))
block.getWorld().dropItemNaturally(block.getLocation(), brokenBlock);
Why is this returning null?
*But keep in mind that ISPs can distribute dynamic IPs
This doesnt return anything
The value of #getItemInUse()
Well, because it can be null.
This will only return something if the player is actually using an item right now.
(eating food, drawing back a bow, blocking, etc.)
Using this on BreakBlockEvent and trying to get if the pickaxe has an specific enchantment, doesn't that method return that?
It is returning null using a pickaxe
but in summary do you mean at all is rare to happen and anybody can't do it ?
do i right understand ?
event.getPlayer().getInventory().getItemInMainHand()
oh, okay, i'll try thanks
Yeah, an IP attack is very rare
I noticed one bug, when I die and respawn next to the NPC, it is not visible
Mojang's /give command accepts item names in the following fashion enchanted_book{StoredEnchantments:[{id:"minecraft:unbreaking",lvl:5s}]}. Does anyone here know how this is done, or how I can do the same thing?
It's called SNBT
declaration: package: org.bukkit.inventory, interface: ItemFactory
^^ and you can use this
Thanks @young knoll and @chrome beacon . I'd have never found that. ❤️
Is there not a method to convert an itemstack to that format
wacky
I have this case opening thing and now i want to add it so that there is a large list of items that can spawn from it, but each item has its own rarity. The chest takes 4 random items based on rarity and spits them out. How do i go about making such system?
I would look into a weighted random system
Are there examples of that algorithm i could look at. Preferably java or kotlin
Yeah i have that as well. Just modified it a little bit.
Oh so you have a string of items and a string of weights
Then you sum up all the weights
Then pick a random number between 0 and weight sum
And then the part i dont get is you some how take that and turn it back into the item
By a binary tree search. But thats hidden in the TreeMap
Im currently using the RangeMap from guava for this instead of a TeeMap
Whats the difference
?paste
I have been trying to make user's inventory save in the db for a while now and load ofc and since i am making this ticket obviously its all bad code and dosent work. So iam here for guidence on how to achieve this goal before i go insane.
Please ping me once you respond.
https://paste.md-5.net/ejefuvicaq.cs , Hi How to fix it ?
what exactly is the issue? what's your current code?
This isn't overly difficult
perhaps maybe you just don't know what type to make the inventory stuff to properly save in the DB?
the code is terrible i deleted that shit but basically
when i have attempted to save itemStack data to the mongodb it was working partially the nbt data didn't go through though, and whenever i searched on google the information to me was irrelevant.
I am using spigot 1.8.8
I am unable to use realistically higher versions since my pc starts lagging everytime i boot up the server
We are all at diffrent stages of learning
itemstack, itemstack[], inventory <> byte[] / base64: https://github.com/mfnalex/JeffLib/blob/master/core/src/main/java/com/jeff_media/jefflib/ItemStackSerializer.java
itemstack, itemstack[] <> json: https://github.com/mfnalex/JsonConfigurationSerialization
i will have a mess around with this
my code and error is in https://paste.md-5.net/ejefuvicaq.cs , How to fix it ?
what are those GuiItem etc things?
Triumph GUI
i used Triumph GUI
and i used document or wiki of Triumph GUI
Hey guys, have any of you used the 1.20.4 NMS for duning the Scoreboard, When yes -> please DM me
economyshopgui 1.20.4 red bug
why do you keep spamming this useless message into every channel? what is that even supposed to mean?
In case of ServerInfo is there a implementation available or I need create my own class for it?
or 1.20.3^^
?ask
If you have a question, please just ask it. Don't look for staff or topic experts. Don't ask to ask or ask if people are awake or available. Just ask the question to the channel straight out, and wait patiently for a reply. Make sure you use the right channel regarding the topic of your question. Create a thread in case the channel is already in use!
-.-
the MinecraftServer implements it
BungeeServerInfo https://github.com/SpigotMC/BungeeCord/blob/master/proxy/src/main/java/net/md_5/bungee/BungeeServerInfo.java
oh too late
It was stuppid from my side, I should find it before give the question, sorry
the better question is, why do you need the implementation?
because if you want to create a ServerInfo you shall use ProxyServer#constructServerInfo https://javadoc.io/doc/net.md-5/bungeecord-api/1.16-R0.4/net/md_5/bungee/api/ProxyServer.html
the plugin 1.20.4 EconomyShopGUI-6.4.1 does not work
Does anyone know how I have to use the NumberFormat in 1.20.3 for a packet scoreboard? -> For the "ScoreboardObjective"
Cool, thanks for info
thx, this will definitely help me with my own spigot/java development
You’re gonna have to be a lot more specific.
I wish force client to connect another Bungeecord server after registering it in the system.
ScoreboardObjective? Do you mean net.minecraft.world.scores.Objective?
No, realy "net.minecraft.world.scores.ScoreboardObjective"
?mappings
Compare different mappings with this website: https://mappings.cephx.dev
yeah the proper name is Objective. I'd just pass in an instance of one of the existing formats and see what happens lol
just throw in a BlankFormat
i current using: NumberFormat numberFormat = BlankFormat.a;, you mean this?
idk, you should use mojang mappings instead of the obfuscated names
either StyledFormat.SIDEBAR_DEFAULT or new BlankFormat()
i try
ofc it depends on how you want it to get displayed. do you even want to show the score number?
or do you just want to use the scores to sort some arbitrary lines of text?
its not importent, that it have numbers
if you want to show the numbers, use StyledFormat.SIDEBAR_DEFAULT (or create a custom one with new StyledFormat(Component)), otherwise BlankFormat.INSTANCE
i try, but i dont know what i make wronge. I use not the mapped Src.
`` PacketPlayOutScoreboardObjective removePacket = new PacketPlayOutScoreboardObjective(objective, 1);
PacketPlayOutScoreboardObjective createPacket = new PacketPlayOutScoreboardObjective(objective, 0);
PacketPlayOutScoreboardDisplayObjective display = new PacketPlayOutScoreboardDisplayObjective(DisplaySlot.b, objective);
sendPacket(player, removePacket);
sendPacket(player, createPacket);
sendPacket(player, display);``
i dont know what i make here wrong lol
that i dont see any of the Scoreboard. i used the same code in 1.20.1 but there is any changes of the NMS
mag ich nicht xD
bringt mir auch nichts
lol
Show the code where you're creating the objective
`` NumberFormat numberFormat = StyledFormat.c;
ScoreboardObjective objective = scoreboard.a(displayName,
IScoreboardCriteria.a, IChatBaseComponent.a(chatData.message("%1%§lLobby")),
IScoreboardCriteria.EnumScoreboardHealthDisplay.a, true, numberFormat);
PacketPlayOutScoreboardObjective removePacket = new PacketPlayOutScoreboardObjective(objective, 1);
PacketPlayOutScoreboardObjective createPacket = new PacketPlayOutScoreboardObjective(objective, 0);
PacketPlayOutScoreboardDisplayObjective display = new PacketPlayOutScoreboardDisplayObjective(DisplaySlot.b, objective);
sendPacket(player, removePacket);
sendPacket(player, createPacket);
sendPacket(player, display);``
public void sendPacket(Player player, Packet<?> packet) { ((CraftPlayer) player).getHandle().c.a(packet); }
Just came here. Why are we using nms for scoreboards?
no clue
so you'd rather use obfuscated names and make your life and lives of the people helping you harder
😵💫
I think whatever he is doing should be done via the spigot api and not nms in the first place
i know.. But im only using the nms for my Scoreboard. i think its okey for this small packets
any particular reason against using the api?
i know what you mean. But im only want using the Tab-Prefixes with the Spigot-API Scoreboard
here, i do the remapped https://i.imgur.com/J9irrTN.png

public void onPlayerJoin(PlayerJoinEvent event) throws Exception {
Player p = event.getPlayer();
for (CraftPlayer ep : manager.getNpcsInChunk(p.getLocation().getChunk().getX(), p.getLocation().getChunk().getZ())) {
if (ep != null) {
System.out.println("sended packets");
manager.showTo(p, ep);
npcSpawned.put(p, true);
}
}
Npc.injectNetty(p, manager);
}``` unfortunately, the length of the array manager.getNpcsInChunk is now zero and ```System.out.println("sended packets");
manager.showTo(p, ep);
npcSpawned.put(p, true);``` is not executed
by the way, I have implemented the decoder injector, "npc_interact" into the code
he works
but when 2 player join, the NPC disappears
You are only sending the NPCs which are currently in the chunk the player is logging in. That makes no sense.
The player needs to receive every loaded npc on the server when he joins.
Could anyone check this out if you get the chance? I am trying to change nametag colors in this plugin and I have still not been able to find a solution. The server uses paper 1.18 https://jd.papermc.io/paper/1.18/index.html , and I cant seem to get the nametag color to change no matter what, is it possible? Any help would be greatly appreciated.
?nms
it looks like I did something wrong with the injector to process a click on the NPC or sent packets wrong, but now I log on to the server my messages are only visible in the console, I can't open the menu and I get kicked off timed out after a couple of seconds
Can i set someones glow effect color without changing any scoreboard stuff?
If you're using neznamy's tab you can set it with a placeholder 
😔
@echo basalt have you actually used the rotation methods you have on your blockdisplaypacketentity class?
I believe I used the scaling ones, but not rotation
how the hell are these even meant to work man
I am making a quaternion based on a eulerangle rotation and it just disappears
lmfao
you might need interpolation idfk
just look at how craftblockdisplay wraps it
brb buying chicken
ok I'm getting trolled, no way
[20:14:24 INFO]: INITIALIZATION Left rotation: ( 0.000E+0 0.000E+0 0.000E+0 1.000E+0)
[20:14:24 INFO]: INITIALIZATION Right rotation: ( 0.000E+0 0.000E+0 0.000E+0 1.000E+0)
works
[20:14:24 INFO]: Left rotation: ( 0.000E+0 0.000E+0 0.000E+0 1.000E+0)
[20:14:24 INFO]: Right rotation: ( 0.000E+0 0.000E+0 0.000E+0 1.000E+0)
made the model disappear
am I on drugs
Lmao
make it NaN
actually it flips to 0 0 0 0 a couple of ticks later so that might be it?
I've come with another question. Is there some type of registry for namespaced keys? I'm currently just using the values from the Material enum, but that feels wrong.
do any know what i put in in PacketPlayOutScoreboardScore?
net.minecraft.network.protocol.game.PacketPlayOutScoreboardScore
the last 3, i know what i know what i put it in
Use mojang mappings pls
can you make me a picture what i must have in them?
?mappings
Compare different mappings with this website: https://mappings.cephx.dev
?switchmappings too
What is the best way to add a fake enchantment glint to items without effecting the item in any other way?
can someone explain nms like really simple?
nms is short for a package name net.minecraft.server
Its basically the code mojang wrote for creating a minecraft server.
Thats all.
oh
that is really simple
But people didnt want to use mojangs code (as it changes a lot)
So they created bukkit (which keeps the same code "visible" for developers)
Bukkit/Spigot makes sure that what you are writing once, will work for all the nms versions.
nms -> Changes every version
spigot -> Should rarely change
The idea was to write code once and make it work for the future without updating
Thats why if you write a 1.8 plugin, it will work all the way to 1.20 (mostly)
does that also work backwards?
Not really because Spigot constantly adds new features to their api, and we cant really add those features to older versions
Makes sense
But we encourage you to use the latest version for your development and server
also whats the difference between jdk 1.8 and jdk 17 some people say to use 1.8 jdk
Unless you're writing plugins for old versions of Minecraft, you should use 17.
1.8 is really old at this point
^
I gotta make a friend system
p sure past conversations here recommended using some sort of graph
how am I gonna do this to not completely break cross-proxy
gotta add a bunch of packet wizardry

redis?
hm
that's one of the solutions
store all the online player friend data on redis
but then if a guy accepts a friend request from an offline player I gotta load it from the db
eh whatever not that complex
yes, but you could also just add the friend to the offline player to the db and add the friend in memory to the other one?
my original idea was that each proxy would have data for their online players and I'd add a bunch of packets so the proxies talk to each other
be like "ayo this the new data"
and do like 5 trillion checks
wasnt this what we talked about 1 week ago?
not exactly no
But then imma have friend menus and only the proxies have data context
hm
Should I make a friend service 🤔
i think redis is the best solution if you have that many servers, smile told me about having 1 master server with the data and the rest are relying on the master
I think the solution is just redis & persistence
bunch of interface magic
Maybe I toss it all on the spigot module and call it a day
Or you simply only edit your data in the Database/Redis and keep a read-only view.
I have an auto synchronized collection for that.
Write:
- Write <K, V> to local map
- Write <K, V> to redis
- Send <K> on a redis topic to notify update
- Every subscriber loads <K, V> into local map from redis
Read:
- Read from local map
Synchronized Compute (for currency etc):
- Ack lock from Redis
- Read <K, V> from Redis
- Predicate -> Compute on <V>
- Write modified <V> to Redis
- Release lock
- Send <K> on a redis topic to notify update
- Every subscriber loads <K, V> into local map from redis
This way im assuring a 100% consistent data state with an eventually-consistent read-only cache on multiple instances.
Hm
I'm still thinking of using redis but I also gotta fetch friend data from mysql
don't think mongo's set up
mongo < sql
*>
?
mongo's nicer
why's that?
but I can't use it here
I like mongo because i will never have to write a schema or any queries ever.
Back the Codec with Gson and boom, store everything without having to write a serializer.
I also don't need the "local caching" as it adds a bunch weird complexity given I'll also need proxy logic for like
getting what server your friends are on type deal
I literally wrote this
so I don't mind just like
having 2 redis caches and fetching a read only snapshot every time I mess with the data
Use MongoDB like a Map for anything
This has always bitten me in the ass
schema's are nice because they ensure you dont put anything where it doesnt belong
sometimes your data doesn't have a fixed schema
But yeah as for gson in mongo the problem is like
weird generics
For example at a server I worked for I made a settings system that supported complex types
And I couldn't just yeet generic setting values because I needed context of how I'd read it
And adding the class name to every value just adds overhead
It also gave me weird issues if I were to change the class spec
So I just went back to the classy ways and wrote codecs



