#help-development
1 messages Β· Page 1029 of 1
Oh you just need the pipeline?
I have 3 ways:
Gimme a sec
yeah its easily possible to do this with protocol lib but surely we just use obfuscated methods because making server owners add 1 extra plugin is cringe :grubomg:
- Going to the Channel location with reflection like this:
Contribute to ShadowOfHeaven-Me/AlixSystem development by creating an account on GitHub.
- Adding a server channel handler that waits for channelActive, intercepts the name packet and add it to a Map and then removes in PlayerJoinEvent
- Using PacketEvents
Not ProtocolLib
Cuz it's better
I'm not sure whether this works anymore cuz I use the third method
But it should
so with this i can just make a call to inject?
It's called "injector" but it actually only finds the Channel
When you do "inject" it adds a packet handler
ok just gotta figure out how to properly use this-
Just copy what's in the "nms_impl" package and the necessary methods and Fields from ReflectionUtils
i have to initialize the interface no?
Wdym?
What do you mean by that?
Im waking up with a confusion. Thanksπ
Does anyone have a possible fix?
pain
yeah its having me initialize it in my class
ChannelInjector channelInjector = new ChannelInjector() {
@Override
public Channel getChannel(Player player) throws Exception {
return null;
}
@Override
public String getProvider() {
return "";
}
};```
The other two classes
In "nms_impl"
Implement this class
Use this instead
?paste
Please
Yes
and ReflectionUtils?
The Channel's location is different on 1.20.2+ and pre to that
im using 1.20.4
Just the necessary
Will you only be using that version?
im only supporting 1.20.2+
Then ye
so i only need newer?
Add only the NewerNmsChannelGetter
Anyone by chance have a solution as to why the itemname is entirely bold if only one character is bold and then sets everything else to bold?
https://paste.md-5.net/kuharuqafe.php
&#fe0505<&#fd0909e&#fc0e0es&#fb1313t&#fa1818i&#f91c1cn&#f82121g&#f62626t&#f52a2ah&#f42f2fe &#f33434i&#f23939t&#f13d3de&#f04242&lm&r
Wanna print the next line too
Sorry?
what in the everliving fuck is this
Use a minimessage ahhhhhhhhhhhhhhhhhhhhhhhhhh
what the fuck
What?
lol
how do you load an existing world from a given directory
worldcreator
new WorldCreator(new NamespacedKey(plugin, "your world name")).createWorld()
no nvm
Bukkit.createWorld(worldCreator)
okay both work lol
its an existing world tho
no the world eixsts
wdym the world exists
there's no "world file"
huh
what i mean is
that world folder has its contents
like its already created it just only needs to be loaded
well then wdym by this
with the contents, not a registered server world
yes it has contents
.
yeah and that was my question
i see thanks
Does worldcreator copy the content of the original world? like the builds?
no i don't think so
Ah, what do I do if I want to copy the builds?
it generates a new one if it can't find a world at the location of the name
Do I stick to pasting schems?
means you can name a world minecraft:/boot/mc and it'll be saved there
copy the directory remove the uid.dat and load the new dir
The uid dat is deleted and it does generate a new world
just that it does not copy the builds
show your code
copy the dir
then load from the new dir name
@quaint mantle eg i use a system like this https://pastes.dev/Er4A1qOIae
Why kt though
because i use kotlin
override val gameMap = GameMap(File(plugin.dataFolder, "maps/duel/$mapType"), identifier)
does anyone know of any protocol lib bugs/changes in spigot 1.20.6 that causes a field index 0 is out of bounds for length 0 for player info action?
back in 1.19.3 it used to be getPlayerInfoActions()
can I remove a specific path finding for a mob?
what I am trying to do is to disable villager ai but to keep the golem thingy
how install nameless templates? someone know?
Use PacketEvents
with NMS, yes. But I'm not sure if villagers use regular pathfinding - don't they use a "Brain" thingy?
setAware might work
so, setAI to false and setAware to true?
to my knowledge, that api can be used to listen for packets, not to create and send them?
you can send packets with packetevents too
using PacketEvents.getPlayerManager.sendServerPacket()
and then you just instantiate the wrapper class of your packet and put it into the function
why is this server suddenly obsessed with packetevents
@wide coyote @pseudo hazel thank you both very much, you relieved me from an enormous protocol lib headache I've had for the past two days, works like a charm
here's your answer btw
because its good
and I guess the person who made is frequently talking in this server, which probably helps
[10:44:36 INFO]: [ItemsAdder] Enabling ItemsAdder v4.0.1-alpha-test-3
[10:44:36 ERROR]: [ItemsAdder] ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
[10:44:36 ERROR]: [ItemsAdder]
[10:44:36 ERROR]: [ItemsAdder]
[10:44:36 ERROR]: [ItemsAdder]
[10:44:36 ERROR]: [ItemsAdder] This server version is not supported: 1.20.1
[10:44:36 ERROR]: [ItemsAdder]
[10:44:36 ERROR]: [ItemsAdder]
[10:44:36 ERROR]: [ItemsAdder]
[10:44:36 ERROR]: [ItemsAdder] ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
[10:44:36 INFO]: [ItemsAdder] Disabling ItemsAdder v4.0.1-alpha-test-3
seems like that server version isnt supported for the plugin
Is it possible to register a custom recipe where ingredients have an own RecipeChoice implementation
like I need to use the ExactChoice recipechoice that checkes using equals check (ExactChoice uses isSimiliar method internally)+
People throw their messages in here as if it was chatgpt
Hey guys, I'm creating a plugin and I've got a problem
I tried to save two dimensional array on config
code :
@AllArgsConstructor
@Getter
@Setter
@SerializableAs("CookingRoom")
public class CookingRoomImpl implements CookingRoom {
private ItemStack[][] recipeItems;
private ItemStack resultItem;
@NotNull
@Override
public Map<String, Object> serialize() {
Map<String, Object> map = new HashMap<>();
map.put("recipeItems", recipeItems);
map.put("resultItem", resultItem);
return map;
}
@SuppressWarnings("unchecked")
public static CookingRoomImpl deserialize(Map<String, Object> data) {
ItemStack[][] recipeItems = (ItemStack[][]) data.get("recipeItems");
ItemStack resultItem = (ItemStack) data.get("resultItem");
return new CookingRoomImpl(recipeItems, resultItem);
}
}
But the error said:
[20:34:57 ERROR]: [org.bukkit.configuration.serialization.ConfigurationSerialization] Could not call method 'public static kr.shibapark.shibacooking.cooking.CookingRoomImpl kr.shibapark.shibacooking.cooking.CookingRoomImpl.deserialize(java.util.Map)' of class kr.shibapark.shibacooking.cooking.CookingRoomImpl for deserialization
java.lang.ClassCastException: class java.util.ArrayList cannot be cast to class [[Lorg.bukkit.inventory.ItemStack; (java.util.ArrayList is in module java.base of loader 'bootstrap'; [[Lorg.bukkit.inventory.ItemStack; is in unnamed module of loader java.net.URLClassLoader @504bae78)
at kr.shibapark.shibacooking.cooking.CookingRoomImpl.deserialize(CookingRoomImpl.java:34) ~[ShibaCooking.jar:?]
I guess the Spigot API doesn't support to save two dimensional array
Is there any way to save two dimensional array?
Looks like when you get it it deseralizes as an ArrayList
2 dimensional array?
[][]
how does the yaml look like?
you'd probably have to load it as List<List<ItemStack>>
https://pastebin.com/b08ABv3g
https://pastebin.com/bASzpZb5
Anyone can help me? The hashMap look like never initialized
private static Map<String, Location> locazioni = new HashMap<>();
ComandoSetHome.getLocazioni();
Since the data in the Map is not stored permanently, create a Manager class to save it in the config
packets probably
as far as I know you can;t do it without Teams. Even packets will be sending teams data
does someone have auction house plugin for 1.20.1 bc spigot doesnt allow me to download that version
yeah but the advantage of packet teams is that they dont need a scoreboard
but the downside is that each client has their own representation of the teams
since you essentially create the teams per player on their client
It not only allows to send and create
But I also discovered a way by reading it's source code to optimize it greatly
(packet sending)
Hi, I'm writing my plugin and I'm having trouble configuring the dependencies correctly (maven shade plugin)
I wanted to create my database library (includes mysql-connector-j dependency) with methods e.g. executeQuery, executeUpdate, connect, etc....
I use this library in the actual plugin as a dependency and compile to the shaded-plugin .jar
The problem is that if I use my library as a dependency to the plugin, the final plugin file weighs 16mb (too much, definitely)
And if I use the mysql-connector dependency directly in the plugin and use scope provided, compile, the file weighs normally, a few kb. How do I make it so that the shaded-jar with my library's dependency weighs normally, not 16mb?
The point of shading is to include the entire source in your jar
You can have it as a dependency in the plugin yml instead which will reduce jar size, but that 16mb has to be somewhere in the runtime
The jar is only 2.4mb, what else are you shading?
When I put the mysql-connector dependency in the plugin, it weighs 4kb. But when I put a library dependency that has a mysql-connector dependency then the plugin weighs 16mb.
The library has nothing more than two methods.
If I do this dependency provided, of course it shows an error that the class was not found etc etc
<dependency>
<groupId>xxx</groupId>
<artifactId>DatabaseLib</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
Oh so youβre saying your wrapper lib is adding 16mb?
Sounds like you're not shading mysql connector in the first plugin
exactly
Yeah the regular mysql connector is alrwady 2.4mb
You can look into your jar by renaming the name.jar to name.zip to determine what uses the space
obv the unzip
good idea, lemme try
small correction; im using sqlite instead of mysql-connector atm
seems like sqlite is the reason
why are you shading a driver? Its included in Spigot
is sqlite already included in spigot?
yes
how do I rename a plugin im making in intelliJ?
you mean the jar name or the plugin name
plugin name in plugin.yml
plugin jar name in pom.xml
i just read plugin.xml
π
or use 7z where you can just open .jar as an archive 
file roller my beloved
I was thinking, if I made a website for my awesome menu plugin to configure menus online I would initially wanna use minecraft assets so peiple know what its gonna look like in game. But that isnt legal I think. But, if I just make a resourcepack and use that it's fine right?
a resource pack is fine. If you use Minecraft assets on yoru website, not so much
yeah alright
nice
then there is a way to make it real
thanks
its just gonna be a huge effort
to just make a resource pack with all items and menus xD
or borrow one online π€
If I use a Xeon E5 processor in server version 1.20.6, will it perform?
as always it depends
We'll play 5 people, it'll be stable.
I will use 4 GB of memory and Ubuntu 22.04 operating system.
and what else yoru server is doing, if its a shared server, what services, teh Internet connection and so much more
It has 1 GBit internet. How do I know if it's shared? The product type is VDS.
also the JVM flags you use (some flags can kill your server no matter your hardware)
Aikar Flags.
Is it your own box, or a server hosting?
Probably server hosting judging by teh description
Hosting company.
Is it a summerhost or?
then its pot luck how it will perform
What is Summerhost?
Teenagers creating companies whose only purpose is to make money by reselling overcrowded servers from OVH or similar - as it happens usually during the summer break, they are called summerhosts
I understand.
Hi, I am new to protocollib and packets, and I am trying to learn. I have a question about how I can send a toast to a player with packets. I looked at https://wiki.vg/Protocol, and I think I need to use the Update Advancements packet, but I can't find PacketType.Play.Server.UPDATE_ADVANCEMENTS.
Does anyone have optimization ideas for the physics of block movement and their control?
I think I need to use PacketType.Play.Server.ADVANCEMENTSbut I dont know how to send this it looks complicated.
all movements will occur through mobs
I make it possible to create massive moving objects
Just a bunch of block displays all on a single parent entity is best
Then you only need to move the parent
I need to optimize the traffic calculation
what will be the next blocks etc. to give the physics of the impact on the chipping etc. for the box.
I have 1 friend suggested to me to make a separate module that on a separate server with the same sid will calculate 5 blocks to the front
just a massive build would consist of shalkers and armorstands and it's going to consume a lot of resources
1.16.5 π¦
update
not can
Yeah
and shullkers for solid blocks
do you need that for a smooth rollout?
for animation
i mean shulker mob
he can move a diagonal i gess
bump
guys can i name an outgoing channel anything i want?
or do i have to write BungeeCord
if you want to use the Bungeecord channel you write Bungeecord
if you want to make your own channel you can name it something else
Just keep the name under 64 characters or some things might explode
And namespace it
myplugin:mychannel
because you're providing it in your jar?
Hey all, I've been struggling to understand Dependency Injection with Spigot. I read the documentation about it, but I don't how how it's happening. Essentially I have class A, which manages the stored data. I have class B, which uses the stored data, and I have MyPlugin class, which should keep the data.
public class ClassA{
private HashMap<UUID, ClassB> playerDataMap = new HashMap<>();
public ClassA(MyPlugin myPlugin){
}
//methods to add and remove data from the map
}
public final class MyPlugin extends JavaPlugin{
private ClassA classA;
public void onEnable(){
classA = new ClassA(this)
}
//getter
}
public class ClassB{
???
//methods to get data from ClassA
}
I want to know 3 things:
- How is the data kept? Does each instance of ClassA have access to the same data, or is it only the ClassA that was instantiated in MyPlugin at the start?
- How do I obtain the data using ClassB? Should I also use a Dependency Injection there?
- Should I instead create a HashMap in MyPlugin and store data like that? What is convention? ClassA is pretty much only responsible (as of now) for handling storing data.
Thanks for the help, it's greatly appreciated. I know this might not be the place to ask for Java help, but I want to make sure that my code follows the basic principles and I think that the 'Main' class with Spigot functions a little differently than the 'Main' class in normal programs.
Let's use some more insightful names to explain this
ClassA -> MyRegistry, ClassB -> MyData
The approach usually goes a little like this
the dependency reduced jar doesn't include shaded dependencies
im tryna do some config stuff and i have no clue how i managed this
[18:27:32] [Server thread/ERROR]: Error occurred while enabling HungerGames v1.0 (Is it up to date?)
java.lang.StackOverflowError: null
at org.bukkit.configuration.MemorySection.createPath(MemorySection.java:949) ~[spigot-api-1.20.4-R0.1-SNAPSHOT.jar:?]
at org.bukkit.configuration.MemorySection.createPath(MemorySection.java:927) ~[spigot-api-1.20.4-R0.1-SNAPSHOT.jar:?]
at org.bukkit.configuration.MemorySection.getDefault(MemorySection.java:863) ~[spigot-api-1.20.4-R0.1-SNAPSHOT.jar:?]
at org.bukkit.configuration.MemorySection.get(MemorySection.java:237) ~[spigot-api-1.20.4-R0.1-SNAPSHOT.jar:?]
at org.bukkit.configuration.MemorySection.getDefault(MemorySection.java:863) ~[spigot-api-1.20.4-R0.1-SNAPSHOT.jar:?]
at org.bukkit.configuration.MemorySection.get(MemorySection.java:237) ~[spigot-api-1.20.4-R0.1-SNAPSHOT.jar:?]
at org.bukkit.configuration.MemorySection.getDefault(MemorySection.java:863) ~[spigot-api-1.20.4-R0.1-SNAPSHOT.jar:?]
at org.bukkit.configuration.MemorySection.get(MemorySection.java:237) ~[spigot-api-1.20.4-R0.1-SNAPSHOT.jar:?]
at org.bukkit.configuration.MemorySection.getDefault(MemorySection.java:863) ~[spigot-api-1.20.4-R0.1-SNAPSHOT.j
its repeating this like 20 bajillion times
you created an infinite loop
List<Team> teams = new ArrayList<>();
Team team = new Team(List.of("PhoenixDev"), "phoenix", 0, 0, 0);
teams.add(team);
Configuration defaults = getConfig();
defaults.set("active", true);
for(Team t : teams) {
defaults.set("teams." + t.getName() + ".members", t.getMembers());
defaults.set("teams." + t.getName() + ".spawn_x", t.getSpawn_x());
defaults.set("teams." + t.getName() + ".spawn_y", t.getSpawn_y());
defaults.set("teams." + t.getName() + ".spawn_z", t.getSpawn_z());
}
getConfig().setDefaults(defaults);
saveConfig();
FileConfiguration config = getConfig();
boolean active = config.getBoolean("active");
List<Team> teams2 = new ArrayList<>();
for(String teamName : config.getConfigurationSection("teams").getKeys(false)) {
List<String> members = config.getStringList("teams." + teamName + ".members");
int spawn_x = config.getInt("teams." + teamName + ".spawn_x");
int spawn_y = config.getInt("teams." + teamName + ".spawn_y");
int spawn_z = config.getInt("teams." + teamName + ".spawn_z");
Team t = new Team(members, teamName, spawn_x, spawn_y, spawn_z);
teams2.add(t);
}
getLogger().info("Active: " + active);
getLogger().info("Teams: " + teams2);
not sure where
this is literally all the code in my programme
bump
your config
public class MyData {
private final MyPlugin plugin;
private final UUID playerId;
public MyData(MyPlugin plugin, UUID playerId) {
this.plugin = plugin;
this.playerId = playerId;
}
...
}
public class MyRegistry {
private final Map<UUID, MyData> registry = new HashMap<>();
private final MyPlugin plugin;
public MyRegistry(MyPlugin plugin) {
this.plugin = plugin;
}
public MyData getOrCreate(UUID playerId) {
MyData existing = this.registry.get(playerId);
if(existing == null) { // Replace with computeIfAbsent once you understand lambdas
existing = new MyData(this.plugin, playerId);
this.registry.put(playerId, existing);
}
return existing;
}
}
public final class MyPlugin extends JavaPlugin {
private MyRegistry registry;
@Override
public void onEnable() {
this.registry = new MyRegistry(this);
}
...
}
@grave vigil
MyPlugin passes itself when creating MyRegistry, MyRegistry holds the plugin's context and passes it to MyData
my config is also quite simple
and the fact this is there means the problem lies ```java
FileConfiguration config = getConfig();
boolean active = config.getBoolean("active");
List<Team> teams2 = new ArrayList<>();
for(String teamName : config.getConfigurationSection("teams").getKeys(false)) {
List<String> members = config.getStringList("teams." + teamName + ".members");
int spawn_x = config.getInt("teams." + teamName + ".spawn_x");
int spawn_y = config.getInt("teams." + teamName + ".spawn_y");
int spawn_z = config.getInt("teams." + teamName + ".spawn_z");
Team t = new Team(members, teamName, spawn_x, spawn_y, spawn_z);
teams2.add(t);
}
getLogger().info("Active: " + active);
getLogger().info("Teams: " + teams2);
somewhere here presumably
- There is only one
MyPlugininstance, every variable tracks a reference to the instance, MyDatahas the same reference asMyRegistry, and if you make some getters you can access the registry directly (Not advisable, see Single Responsibility Principle in my pinned message)- This is the correct approach, as the purpose of your "Main class" is to setup the plugin, not to actually store data. Each class should only be responsible for a single and specific thing
Class.forName("org.postgresql.Driver");
you have to add something like that or some shit
This makes a lot more sense now, thank you very much for the help π
Is there such a mob that you can stand on like a block?
shulker
and move in diogonal
idr
you are setting the defaults to the same config object itself
Configuration defaults = getConfig();
...
getConfig().setDefaults(defaults);
i think this owrks
boat? Not a mob, but entity
how am i meant to do it
create a new MemoryConfiguration for the defaults instead
something close to a block
also why do you make every message @silent lol
idk if the server allows it so wont say
gotta keep quiet about the secret sauce
do I smell a modded discord user
what are you talking about
but I want the why, not the how
i have no knowledge of this
lets me reply without having to worry about the annoying people who get pissed by pings
bump
you can also not ping when replying?
But some like to be pinged
Configuration defaults = new MemoryConfiguration();
defaults.set("active", true);
for(Team t : teams) {
defaults.set("teams." + t.getName() + ".members", t.getMembers());
defaults.set("teams." + t.getName() + ".spawn_x", t.getSpawn_x());
defaults.set("teams." + t.getName() + ".spawn_y", t.getSpawn_y());
defaults.set("teams." + t.getName() + ".spawn_z", t.getSpawn_z());
}
getConfig().setDefaults(defaults);
saveConfig();
Looks like yes
this doesnt work
idk
Lemme leave the channel and ping me in 5 secs
I prefer a ping IF I'm already in a conversation with the person.
moreeffort
spelling
@quaint mantle
yeah this just straight up doesnt save anything
the defaults are fallback values, those aren't saved
that might work, idk
why are you modifying the defaults that way
im tryna just save a template if they dont have anything saved
is my approach just wrong
just have a config.yml in your resources and use saveDefaultConfig
setDefaults does nothign unless you also copy
the defaults are simply fallbacks for when you do getThing("foo.bar") but the user does not have a foo.bar set in their config file
probably due to how plugins are loaded
Anyone know how I can send it?
?whereami
how would you store a list of chests in a config
I probably would not
^ if you mean chest + its contents thatβs probably not very good idea
just a list of chests
I mean
so that you can set like a list of locations of chests
in the config
idk how to set it and then deserialize it
I'd try to avoid storing locations of objects in game. you never know if your plugin was always runnign when the server was
too easy for your data and the servers to become unsync
I feel like this is for an envoy plugin?
hungergamess
Why do you want to store the chest locations?
why are you silenting every message
user to be able to set which chests are in which tier through the config
ah
I mean
would the tier not be better random?
nah so like you can set chests at the center to be tier 1
also means your config is not locked to a specific map
and then random irrelevant chests are like tier 3
then measure teh distance to center
vencord plugin
Iβm having a hard time understanding why you need to save locations to chests, I feel like itβd be easier to just let the operator place them in game and your system handle the specifics later
cuz the map is meant to be constant
why do i see it in my browser then
i meant they probably use a vencord plugin
you just start the game and it automatically teleports the players to a map
Wtf is silencing
no ping sound
oh like it's a discord feature but somehow accessible via vencord only?
no
That's lame asf lol wrf
@silent
i'm guessing they use a vencord plugin to silence every message
do you just prepend that to your messages
yea
a while
Then just store block x,y,z no world as its always the same world
wow uh
thats waht i want to do
Yeah that
i dont know how to store it in a way its deserializable easily
you could create a chest object and serializ it if you wanted
I think somethign like @SaveAs Chest
I want to create a file in the plugin's folder
String filename = ...;
File out = new File(plugin.getDataFolder(), filename);
out.mkdirs();
if (out.exists() || !out.canWrite()) {
sender.sendMessage("File " + filename + " already exists: " + out.exists() + ", canWrite: " + out.canWrite());
return;
}``` however this creates folders, filename is set to "blah.txt" and "test.txt", what should I change?
I saw [this](<https://www.spigotmc.org/wiki/how-to-make-a-file-in-a-folder/>) but it's just too complicated for what I want
you store it however you want
out.getParent().mkdirs()
all i want to know is how to store it in yml .-.
ty, will try
like how do you store a list of coordinates in yml
map?
I'm assuming getParentFile() because getParent() returns a String
that's not nio lmao
as a string?
i mean....
coords:
- '-185 74 214'
- '-17 68 77'``` why does this not work?
split it by space?
java io i meant
What doesnt work
?nocode moment
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.
chest:
x: -1
y: 0
z: 244```
i wanted to know if there was a preferred or better way to store it
isnt that a waste of space
I'm just trying to do the same thing, and i'm stuck at creating a file :p
but I'll store it with each block in it's own row
Idk what purposes you need it for though
yes, but you are talking about users editing it so it shoudl be easily human readable
No
what ever are you gonna do with the 6 extra bytes
alr cool
If you need space compact use sql not yml
mkdir is only folder creation
createFile or something like that creates your file
createNewFile?
My pc crashes without them π
Real ones use Java nio
real ones use kio
I'm trying....
but this is getting ugly as hell java File out = new File(getDataFolder(), filename); out.getParentFile().mkdirs(); try { out.createNewFile(); } catch (IOException e) { throw new RuntimeException(e); } if (!out.canWrite()) { sender.sendMessage("File " + filename + " canWrite: " + out.canWrite()); return; }
Its just ugly or not working?
ugly, working
why are you throwing a runtime exception
ide suggestion ig π
isnt it a IOException or something like that?
throw new RuntimeException(e);
I mean what createNewFile throws
yeah
dont worry it was intellij when i hovered over .createNewFile() and it says i have to add try catch or throws to the method signature
I'll unugly it asap
do you really have to
it was the first option, and the quickest to get me to working code
don't worry, I'm not going to ever leave something like that
If you catch a Exception dont throw a new one in your catch hahaha xd
this is how I'm doing it right now
Isn't that standard error handling?
cool
Hey guys, how to update a 1.20.1 plugin to 1.20.6? I got an "old" plugin which for some reason doesn't work on latest even tho it's not showing any errors at all
True i forgot
catch {
shutdownPC
}
UncheckedIOException is probably a bit more appropriate, but there really is nothing against rethrowing IOExceptions as RuntimeExceptions if there is no way to recover from the exception (which usually is the case)
That makes more sense but not a RunTimeException
At the end of the day there is no difference, both are unchecked
If you throw a error in that method, your method gets "throws XYZException" and you have to handle that as well or not?
No? Bukkit already does it for you in most of the cases
So you just saying, having a unhandled exception is normal
because you dont handle that-
throwing unchecked exceptions is normal yes
throwing checked exceptions in an unchecked manner (i.e. sneaky throws) is not normal
"in an unchecked manner" im confused with that wording. Wanna explain for more knowledge for me?
You might as well use AssertionError (although that one is fore more critical errors as it doesn't subclass Exception but rather Error) but the distinction between RuntimeExceptions is nearly non-existent since at the end of the day you'll catch them all.
Also if you run out of disk space or if the user broke file permissions then there rarely is anything a plugin can recover to in the first place. Recovery might even break more if a set of "sane" defaults is being used and overwrites the old untouched state (although I surmise that will rarely happen, but might happen with serde issues)
Okay, thats understandable now but im confused with one last sentence.
So just asking for my understandings:
Throwing a runtime there is fine you'll have a lot more issues if you encounter an io there
Bukkit.getServer().stop()
rm -r C:/
and the no preserve root
no need if you do the asterisk
Checked exceptions = All Exceptions that do not extend RuntimeExceptions.
Unchecked exceptions = All Throwables minus those of Exception and all RuntimeExceptions
Throwing exceptions in a checked manner = Either catch the thrown exception directly or guarantee that it is being caught using compile-time guarantees using the throws keyword
Throwing exceptions in an unchecked manner = Throw an exception, but don't handle it. Rethrowing using sneakyThrows can be considered as throwing an exception in an unchecked manner even though the exception is a checked exception and usually compile-time guarantees should exist to prevent one from not handling it (sneakyThrows will trick these guarantees though, which makes it so bad).
Idk if my sentence was wrong but
if i have a method like
public void whatEver() {
try {
} catch(XYZException ex) {
throws new ABCException();
}
}
but if you do something like that you method header have to declare "throws" or not?
like:
public void whatEver() throws ABCException {
And if you use that method in another method you have to handle it again with try catch or not?
Because IntelliJ wants that to declare throws when i use throw and implement a try catch when i use that method.
I love how there is now an entire discussion about handling exceptions
Im just curious if my english is bad as hell or im stupid. If im stupid, its good because im learning something new.
you can't always do that, for example in onCommand, which you have overridden, you cannot just add throws to it because then it becomes another method, so you just have to use try {} catch () {}
I didnt mean it on Bukkit, Spigot or whatever
Just plain Java
not if the exception you are throwing is an unchecked exception
only checked exceptions need to be explicitly a) handled or b) added in the throws declaration
You only have to declare the throws ABCException if your ABCException is not an instance of RuntimeException but is an instance of Exception.
Otherwise you can declare the throws, but you aren't obligated to do so
I thought unchecked exception is a sentence like you didnt used try catch while handling exceptions but thats not the case
AH
I get it, thanks. I was like "Yeah unchecked, so you have to check it".
Thanks for the information guys!
hi can someone help me ?
make sure to run the actual jar with that version too
or just try running the jar from the command line
can't find the jar file, only the .exe
and this is the only java i have on my pc
JAVA_HOME not set
env var ?
your java-version says you have Java SE version 21.0.3
so correct your JAVA_HOME variable
not set i think
How can I create a server on Bungeecord dynamically?
I'd require it to be no more than an empty limbo server
but I don't want to really bother with creating the login sequence handler (I've wasted 2 whole weeks of my life on that, never got the player to connect successfully)
so that I could send the player there before they go onto other servers
%JAVA_HOME%\bin\ worked for me
Or U can just delete it and re download that also worked
Also pretty sure U go into something in the environment feature and then U add JAVA_HOME and add a file directory to Ur jdk_
done 2 times
Where did U delete it from
config pannel
also need to be fixed in your path variable
or, you could just uninstall 21 and reinstall to let it update itself
I full path my execution of BT
U also need to delete a directory to java
Not the JAVA_HOME
nah, just the corect path/Home
Idk what it is but it's in system variables
Oh ri
Yeah, PATH and JAVA_HOME should suffice
yeah it working
Cause it fucks up the jdk thing for some reason
my bat to run BT```bat
@echo off
mkdir BuildTools
cd BuildTools
SET JAVA_21="C:\Program Files\Eclipse Adoptium\jdk-21.0.3.9-hotspot\bin\java.exe"
SET JAVA_19="C:\Program Files\Eclipse Adoptium\jdk-19.0.1.10-hotspot\bin\java.exe"
SET JAVA_17="C:\Program Files\Eclipse Adoptium\jdk-17.0.1.12-hotspot\bin\java.exe"
SET JAVA_8="C:\Program Files\AdoptOpenJDK\jdk-8.0.252.09-hotspot\bin\java.exe"
SET BUILDTOOLS_URL="https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar"
curl -z BuildTools.jar -o BuildTools.jar %BUILDTOOLS_URL%
SET /p Input=Enter the version: || set Input=latest
for /f "tokens=1,2,3 delims=." %%a in ("%input%") do set major=%%a& set minor=%%b& set revision=%%c
IF "%major%"=="latest" (
SET cmd=%JAVA_CURRENT%
GOTO execute
)
IF "%major%"=="1" (
IF %minor% LEQ 16 SET cmd=%JAVA_8%
IF %minor% GEQ 17 SET cmd=%JAVA_17%
IF %minor% GEQ 21 SET cmd=%JAVA_20%
)
:execute
%cmd% -jar BuildTools.jar --remapped --output-dir .. --rev %Input%
cd ..
pause```
It can downgrade Ur whole ahh version
Meanwhile in linux land I can switch the active JDK just by waving my hand
I just run ubuntu in windows when I can't bother setting shit up
like redis or mdb
In fact, about an hour ago I wanted to start creating a plugin. So I was looking for a tutorial and I came across a video for 1.19 that talked about the build tool. I installed it and... the wrong version of java, I was in jdk 20, so I uninstalled it because it didn't want to update and installed 22, still not the right version, I uninstalled and installed 21 and I ended up here.
archlinux-java my beloved
or fzf
What are U doing that requires Ubuntu?
LEGIT I can relate
why no docker π€
I was thinking machine learning π
screw off
dam
Anyone recommend any videos or channels to watch , because I hardly know much about plugins and I'm tryna make a custom enchant pluign
what if instead of a file system we just used a big sqlite database
and indexed stuff
based
String id = line.replace("GET /", "").replace("HTTP/1.1", "").trim();
Quality request parsing
hm
Guaranteed to work ig
"guaranteed"
I think the proper way is to split on space?
Does someone know the best way to quickly and cheaply generate a world or just a 250x250 area of a world without river/ocean/swamp biomes? I guess you could check over and over again try to generate one but that would be expensive.
Make a custom generator that excludes the biomes
is there a recource/example for that, I can not find any recent examples online
ChunkGenerator and BiomeProvider
Yeah, that does not help me figure out how to overide ChunkGenerator to not generate a biome. I am new, so just telling me two names of classes does not help at all.
The method Plugin.getDefaultBiomeProvider takes in a string worldName, what does this have to do with getting the default biome provider?
Create a biome provider that has all biomes except the ones you donβt want
And then override the method in ChunkGenerator to return that biome provider
Could I create a biome provider that uses Plugin.getDefaultBiomeProvider and if it is water then return plains? Could i then just pass that directly into WorldCreator?
Maybe? Iβve never tried a biome provider without a custom generator
Do you know why Plugin.getDefaultBiomeProvider takes in arguments?
It takes worldName and Id, but I have no clue why.
Heya,
I want to make a Task, that repeats itself, that checks a permission from out of a ConfigurationSection with keys.
Does someone have a example snippet for that?
?scheduling
Can BukkitRunnable repeat itself in a loop?
Are those tasks synchronized or asynchronized?
is any dependency injection tool included in spigot? e.g guice or sum?
can someone say which situations may lead the player to lose (drop or move to another place) his item? I can remember dropping and moving to another inventory, but idk if i am forgetting something
Death
anything more?
no, why not just use constructors I hear they are pretty great
interacting with an armorstand
I am using a lot of dependencies, also used to Spring DI
Paper has a method called WorldInfo.vanillaBiomeProvider, is there a way to use this on spigot?
dont really want my constructors to look like new class(new class(new class(new class))))
Sisu seems to be on the classpath
But realistically you can just use your own DI framework
what if I for example I want to use guice and want to shade the final project. It adds like 3mb to my final jar size. Should I set it to provided or..?
or It just has to be like that
You can use the libraries feature and set it to provided, yea
And well, guice /should/ be a transitive dependency of sisu, but as it is just a provided dependency it won't be on the classpath. Though I wonder why guice isn't set to optional like all other dependencies of sisu if it works without it - oh well
when i set it to provided, i am getting a NoClassDefFoundError tho
You need to make use of the "new" libraries feature - otherwise you'll get these issues
https://www.spigotmc.org/wiki/creating-external-libraries/ this maybe? I can't check though as I don't have 2FA enabled
https://docs.papermc.io/paper/dev/plugin-yml#libraries just in case it wasn't that - the paper docs are at least not 2FA-walled
its the latter
You donβt need 2fa for it?
im so confused rn
You need - the entirety of spigotmc is walled behind 2FA
heh
No it isnβt
I guess I could log out I suppose
Thereβs a gradle plugin to automatically add libraries to your plugin.yml
Idk if the same exists for maven
I know that guava is included, not sure Guava handles DI tho
still confused bout "new" libraries feature, dont know wym
Basically, using this list you can define dependencies that will be downloaded from maven central at runtime
Why are paper patches not included in spigot?
oh, so i just need to put in plugin.yml those libs I want to use?
The classes will be available at runtime because they will be added to the classpath at that point in time
(and dont want to shade entire lib to my final jar)
libraries adds the dependency to your classpath
just mark guice as compileOnly or whatever mavens equivalent is
So basically it's doing the same thing as shading - just that it happens at runtime and not while compiling
(that'd be provided)
kinda not really, but good enough
Because spigot isnβt paper?
well they probably wouldn't understand the differences either way
but why not just include some of the usefull patches?
?whyamihere
?justtosuffer
because its illegal
to do that
so just to be sure, I need to put
libraries:
- com.google.inject.guice:7.0.0
in my plugin.yml right?
That isn't a proper GAV
It'd need to be com.google.inject:guice:7.0.0 (notice the two colons)
Ask them to PR the patches upstream :)
can you just pr individual patches?
projectId:artifactId:version
basically the syntax is groupid:artifactid:version
you can not, only the paper core contributors have the rights to do this
don't you dare call groupids projectids!
but still need to set guice dependency to provided or simply get rid of it?
shush eclipse user
They can, we canβt
set it to provided
Well I mean it is called a GAV for a reason - have you ever seen people say PAV?
never heard either
hi bestie illusion
hello purple
OMG its purple'
(technically it's a GAVCE but not even the maven docs call it like that - outside of off-hand comment about them using GAV instead of GAVCE for brevity)
I wanna code but feel like throwing up every time I see lines of code
why
idk
I've been doing too much maven artifact resolution stuff then
mans got codaphobia
yesterday I couldn't program - but that is mostly caused by me being rather sick
I wanna finish my bedrock compatibility stuff and release it on spigot

but that takes time and effort
big market
works beautifully, spigot downloaded the lib, didnt even know such an option exist
@eternal night I'm back are you proud
yes 
A miles outside of their natural habitat is dangerous
imagine if paper learns of carbinetMC
or whatever
I wonder how many bedrock players are on bedrock servers vs bedrock players on java servers
a few featured servers are just geyser
That's my target audience
geyser users that don't get the full experience because.. geyser
CabernetMC* close
I'm proud of you getting close
lol
you can join and /icanhasbukkit and half of them throw the default error message
Shows that bedrock is clearly the better version
in TabCompleter or TabExecutor, how can I make the argument red as 'incorrect', like in the second image?
ah, wow
is overriding public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) enough, can I tuck brigadier somewhere inside, or I need to do something entirely different from TabCompleter?
you would have to use the brigadier library
Entirely different
carbeneretitMAC
Optic stole my download speed >:(
@young knoll why is my brain slow did you steal the brain cells
i need them back pls
What would be the best way to display a score letter in minecraft, like S, A, B, C, D, etc. I thought of killing the player with a retextured totem, titles, custom mapart, which would be better?
another question not related to the last one
is there any other way of registering commands instead of registering every single one command in the main class?
lets say i have like dozens of commands in one plugin lol
subcommands?
lets say if your plugin is called Nice Mines then you might want to have something like /nm help, /nm add, /nm delete etc?
no, lets say i have a lot of commands, eg. /kit, /help, /command1, /command2, /report, etc
normally u register them in onEnable with sth like this: this.getCommand("command").setExecutor(new CommandTest());
do i really have to register every single of them this way?
like this?
this.getCommand("cmd1").setExecutor(new Command1());
this.getCommand("cmd2").setExecutor(new Command2());
this.getCommand("cmd3").setExecutor(new Command3());
etc ... cmd50
cant i just do something that will register every single one of them from lets say package named "commands"
i know it may sound little stupid, but im just curious
reflection magic 
Map.of(
"cmd1", new Command1(),
"cmd2", new Command2(),
).forEach((cmd, exec) -> getCommand(cmd).setExecutor(exec));```
i love the part where it uses nms just to register commands
silly people
still waiting for that choco pr to get merged
Soonβ’οΈ
Which one? 
val map = ItemStack(Material.FILLED_MAP)
val mapMeta = map.itemMeta as MapMeta
val mapView = Bukkit.createMap(Bukkit.getWorlds().first())
mapView.renderers.clear()
mapView.scale = MapView.Scale.FARTHEST
mapView.addRenderer(BingoRenderer())
mapMeta.mapView = mapView
mapMeta.displayName(
Component.text("Bingo Card").color(NamedTextColor.GOLD).decoration(TextDecoration.ITALIC, false)
)
map.itemMeta = mapMeta
Anyone know why the scale of this map is still stuck at 128x128?
I'm a big fan of modularity and inheritance, and I made a custom enchant plugin which every class of enchant has its own listener, Is it a great idea to make different listeners, or make a big class which handles all of that?
maybe a class which has 1 listener is better?
for code organization and simplicity I have done that, I could migrate the code to a 1 listener class, and make methods which will be used in the method that has @EventHandler
lmk if there is any better solution
each enchant would need its own listener I'm not sure how they could work together unless all of your enchants work off 1 event
well basically they have a listener which is like PlayerMoveEvent to add potion effect, and some of them have spawn lighting or other unique stuff
at least 6/7 enchants will have effect and will use PlayerMoveEvent
so still my question is, better a big class with everything inside and use 1 method that is subscribed by the eventhandler or multiple ones?
personally I would delegate the enchant listeners to larger ones, but honestly it could work either way. 99% 100% sure spigot ends up caching your event methods when reflecting so the end performance isn't really a worry
so I can still continue to use different eventhandler methods for each enchant class?
my aim is to not make the server slow in performance or something like that
yeah you shouldn't notice a difference
128x128 pixels? They are always that size
The scale just changes how many blocks a single pixel represents
I thought so too but someone said I was wrong and if I'm not i have no clue how this was done
because that is not 128x128
Wonder if they did some magic with map markers
There aren't that many map markers
It doesn't appear to use the completely fucked color pallette
Perhaps core shaders + some pixel magic?
since when are they a feature
Idk a while
1.13
odd
Normally you name a banner, place it, and right click it with the map
I don't recall seeing that in nms
Hello everyone :)
I'm developing a plugin for 1.20.2, everything was normal until I suddenly got this error:
[23:44:13] [User Authenticator #0/ERROR]: Could not pass event AsyncPlayerPreLoginEvent to SolencysUHC v0.0.1
java.lang.IllegalArgumentException: UUID id cannot be null
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:143) ~[guava-32.1.2-jre.jar:?]
at org.bukkit.craftbukkit.v1_20_R2.CraftServer.getPlayer(CraftServer.java:716) ~[paper-1.20.2.jar:git-Paper-318]
at org.bukkit.Bukkit.getPlayer(Bukkit.java:722) ~[paper-api-1.20.2-R0.1-SNAPSHOT.jar:?]
at me.killer.uhc.player.UHCPlayer.getPlayer(UHCPlayer.java:42) ~[SolencysUHC-1.0-SNAPSHOT.jar:?]
at me.killer.uhc.player.UHCPlayer.<init>(UHCPlayer.java:21) ~[SolencysUHC-1.0-SNAPSHOT.jar:?]
at me.killer.uhc.listeners.PlayerListener.onPlayerPreJoin(PlayerListener.java:55) ~[SolencysUHC-1.0-SNAPSHOT.jar:?]
at com.destroystokyo.paper.event.executor.asm.generated.GeneratedEventExecutor5.execute(Unknown Source) ~[?:?]
at org.bukkit.plugin.EventExecutor$2.execute(EventExecutor.java:77) ~[paper-api-1.20.2-R0.1-SNAPSHOT.jar:?]
at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:77) ~[paper-api-1.20.2-R0.1-SNAPSHOT.jar:git-Paper-318]
at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70) ~[paper-api-1.20.2-R0.1-SNAPSHOT.jar:?]
at io.papermc.paper.plugin.manager.PaperEventManager.callEvent(PaperEventManager.java:54) ~[paper-1.20.2.jar:git-Paper-318]
at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.callEvent(PaperPluginManagerImpl.java:126) ~[paper-1.20.2.jar:git-Paper-318]
at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:615) ~[paper-api-1.20.2-R0.1-SNAPSHOT.jar:?]
at net.minecraft.server.network.ServerLoginPacketListenerImpl$LoginHandler.fireEvents(ServerLoginPacketListenerImpl.java:348) ~[?:?]
at net.minecraft.server.network.ServerLoginPacketListenerImpl$2.run(ServerLoginPacketListenerImpl.java:294) ~[?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) ~[?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) ~[?:?]
at java.lang.Thread.run(Thread.java:1583) ~[?:?]
[23:44:13] [User Authenticator #0/INFO]: UUID of player KillerCrazy25 is c1ea6d47-8467-4140-b119-e09a0bcfa81c
[23:44:16] [Server thread/INFO]: KillerCrazy25 joined the game
[23:44:16] [Server thread/INFO]: KillerCrazy25[/ip-adress:56924] logged in with entity id 154 at ([world]79.87668406827494, 144.0, 73.73803967458262
this is the part of the code that's causing it:
@EventHandler
public void onPlayerPreJoin(AsyncPlayerPreLoginEvent event) {
if (event.getLoginResult() == AsyncPlayerPreLoginEvent.Result.ALLOWED) {
if (!playerManager.getPlayersMap().containsKey(event.getUniqueId())) {
UHCPlayer UHCPlayer = new UHCPlayer(event.getUniqueId());
playerManager.getPlayersMap().put(event.getUniqueId(), UHCPlayer);
plugin.getLogger().info(event.getUniqueId() + " (" + Bukkit.getOfflinePlayer(event.getUniqueId()).getName() + ") has been added to players map.");
}
}
}
That seems odd. It's throwing because event.getUniqueId() is returning a null value, which Bukkit never does
Then again, you're using Paper, so maybe they change that behaviour
I'd say it was a bad plugin calling that event but it's coming from the server itself, so the server is invoking a deprecated constructor
Naughty server
any ideas why all of my items lost their name/lore in menus after updating to 1.20.6?
It is definitely different on paper
However according to their docs it isnt suppose to be null either but they have it declared deprecated for removal
So quite possible they removed the functionality of that method
Does this plugin work for persistentdatacontainers for blocks even if that block changes? e.g. if that is a wheat block and it grows from state 1 to 2, will that deleted the persistentdatacontainer?
wheat doesnt havent pdc but you can make your own system to add pdc to each block
its just a pain
afaik there isnt any libs for it
If I start a bungeecord server and one of the sub servers requires java 21, would that cause issues?
FINALLY got fixed
I'm writing a server impl with Minestom that requires minimum java 21
And I'm wondering whether most people will even be able to enable it
why would it? the server just runs on a different java binary
wdym enable it
you can't just require the client to have j21 you'd need to use 1.20.5+
Not client
It's server-side
I'm asking cuz on my pc
I couldn't start a java jar 21 ver
When having java 17
And when using java 21 I couldn't start any jar below 21
then just run the j21 server with j21 and bungee with j17?
Is that a Linux thing?
That you can specify which version you start it with
that should definitely be possible on windows by specifying the exact binary
I remember searching on the web
like uh C:\Program Files\Adoptium\bin\java.exe -jar ... or something
yeah bc you're using the exe
Ye
run the jar
Could you tell me for future how I could run higher java versions and lower ones without reinstalling the java ver?
just find the binary where it installed to and use that instead of java
And do most Bungeecords even use java 21?
like this
idk, never used bungee
Jre is bundled with jdk since java 11. There not separate anymore
Is that why I can't download jre past java 8
okay?
Correct
i don't see how that's related
You are saying it will run on a different binary and assumed you meant jre since ide usually uses jdk. So clarified they are not separate anymore
Unless i misunderstood what you meant
/usr/lib/jvm/jdk-17-adoptopenjdk/bin/java -jar bungee.jar
the path is probably wrong idk my adoptiun install by heart
Lol. Personally i use oracle
And i see now what you meant
Well at least raydan found the info informative
So there is that i guess
lol
If you are on windows you can create a symlink to the java version you want on the path in programdata directory in programfiles directory. If on linux you run the configure command for java and can select the java version or specify a path to one i think.
Java 8 and lower you need to use the environment variables to specify java home. Also note if you install maven standalone for some reason it still requires java home variable in environment variable even though java has moved away from doing it that way
Another way on is to create aliases, for example java17 points to C:/Program Files/Java/jdk17/bin/java.exe
Or save these paths to something accessible and run commands like this: "C:/Program Files/Java/jdk17/bin/java.exe" -jar server.jar nogui
path is written off the top of my head, please don't copy them from here
Yea thats what i do too ^^
I want to display particles using Protocollib
I wrote this code using Protocollib.
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
PacketContainer packet = new PacketContainer(PacketType.Play.Server.WORLD_PARTICLES);
packet.getParticles().write(0, EnumWrappers.Particle.HEART);
packet.getDoubles().write(0, 0.0);
packet.getDoubles().write(1, 100.0);
packet.getDoubles().write(2, 0.0);
packet.getIntegers().write(0,30);
protocolManager.sendServerPacket(player, packet);
It should actually display heart particles, but it does not. Does anyone know how to fix this problem?
Use PacketEvents
obligatory why are you using internals here
I am a beginner so can you elaborate?
why could you not use the api here
Is it common to use java 21 on bungee?
Or are usually people acquainted with how to start servers on incompatible java versions?
What API are you talking about?
Player#spawnParticle(...
bukkit?
I'm worried that if I write a server impl on java 21 people won't be able to use it because it won't start
Are my worries needless
people use j21 for 20.5 already
if you are not using any features of 21, build on 21 with a lower compat
Wdym?
I'm using Minestom, which is built with on java 21
So lower language level?
toSpawn.getWorld().spawnParticle(Particle.REDSTONE, toSpawn, 2, 0, 0, 0, 0, new Particle.DustOptions(color , 0.7f),true);
I want this particle to be visible to only one player, so I use Protocollib.
@digital cosmos
people really just be using packets and shit without even considering the fact that it may be possible within the api already
pro tip always ask before you spend hours doing it the hard way
I was able to solve the problem with spawnParticle. thanks
Hey guys, I'm creating a plugin and have some problems
I tried to save like below variables in a map, but I don't like this way
So What is the efficient way to make it as hierarchy?
public class UserCookingRoomTaskManager {
private static UserCookingRoomTaskManager instance;
// UUID: owner
// CookingPotType (ENUM): NORMAL, PREMIUM
// Integer: RoomIdentifier
// UserCookingRoomTask (BukkitRunnable)
private final Map<UUID, Map<CookingPotType, Map<Integer, UserCookingRoomTask>>> userCookingRoomTaskMap = new HashMap<>();
public static UserCookingRoomTaskManager getInstance() {
if (instance == null) {
instance = new UserCookingRoomTaskManager();
}
return instance;
}
}
Dont create one task per cookingpot. Use a single tasl which ticks all cooking pots.
And if you encounter nested collections, then its time to create new classes and put them in there.
I already make these classes
The classes are already implemented and in the UserCookingRoomTaskManager should be wrapping that classes as a map but I dunno how to make it
should I make it as hierarchy again? how do you think?
nested maps 
also why is it even grouped by task type
wtf
this could just be a map of uuid and list of cooking tasks
Nested maps? Ever seen a Map<String, BiMap<Mapping, Mapping>>
yes
Yeah
everything beyond a map, list, set is a skill issue
map.get(key) or map.invert().get(value)
BiMaps are legit useful
[ CookingRoomIdentifier.class ]
private int identifier;
private CookingRoom cookingRoom;
[ PotTypeCookingRoom.class ]
private final CookingPotType potType;
private final List<CookingRoomIdentifier> identifiers;
[ CookingRoom.class ]
private ItemStack[][] recipeItems;
private ItemStack resultItem;
[ UserCookingRoom.class ]
private final UUID owner;
private PotTypeCookingRoom defaultTypeCookingRoom;
private PotTypeCookingRoom premiumTypeCookingRoom;
According our plan: The task should be different by PotType, And index
since when can maps be bisexual
.
I would store the type in the cooking room
or create a cookingroomcollection class that has a pot type and a list of rooms
multiple constructor?
no
how?
I mean doesnt every room have a type?
why would you need multiple constructors
I guess we have to start at the beginning, what is a cookingroom?
Cooking room is just stored Items information (for example: minecraft chest)
what is it used for
you mean CookingRoom?
okay
alright, so now lets go back to you map of maps of maps of integer and cooking rooms and cooking types and uuids
first off I assume the uuid is for a player right?
yeah exactly
okay, so each player possibly has multiple cooking rooms
that was just for example
I know I wouldn't use in that way
yeah
It needed to require the PotType -> RoomIndex -> Task
SO for example again, it looks like Map<UUID, Map<CookingPotType, Map<Integer, UserCookingRoomTask>>>
And I don't wanna use nested map I wanna moved out to the other class but what is efficient way ?
well in this case its not a performance thing but just a usability thing
a MultiMap
as I suggested, you can perhaps could make something like a CookingRoom collection
JUST FOR EXAMPLEEEEEE ^^
that has a list of rooms and a type
so move the type into the room and still multimap
but that's gonna looks like better than for now
then its just MultiMap<UUID, room>
oh that is a multimap?
allows duplicate keys
it returns a collection (I think)
is it right from google?
guava I think
oh
than if I use that how it's gonna look like?
private static final Table<UUID, PotType, Map<Integer, CookingRoom>> table = HashBasedTable.create();
public static void main(String[] args) {
UUID uuid = UUID.randomUUID();
Map<Integer, CookingRoom> map = new HashMap<>();
map.put(3, new CookingRoom());
table.put(uuid, PotType.NORMAL, map);
System.out.println(table.get(uuid, PotType.NORMAL));
}
I used Table from google how do you think?
over complicated
Indeed is there any better way?
yes, redesign your classes π
hmm
a CookingRoom shoudl contain everythign to do with that room
including its type
what is the Integer key for your CookingRooms ?
public static class CookingRoomKey {
private UUID uuid;
private PotType potType;
private int roomIndex;
}
private static final Map<CookingRoomKey, List<CookingRoom>> map = new HashMap<>();
Then How do you think?
what is the room index used for?
it's used for rooms number 'cause room could be multiple with Pottype
So
RoomNumbers (for exmaple : 8 )
and pot type count (for example : 2)
the RoomTasks list will be 16 in the end.
So yeah
I don;t see why you need those numbers
so a room is a container for the 8 pots?
yeah
and
wait a sec
private static final Multimap<CookingRoomKey, CookingRoom> map = ArrayListMultimap.create();
public static void main(String[] args) {
UUID uuid = UUID.randomUUID();
CookingPotType potType = CookingPotType.NORMAL;
map.put(new CookingRoomKey(uuid, potType, 0), new CookingRoom());
map.put(new CookingRoomKey(uuid, potType, 1), new CookingRoom());
map.forEach((key, value) -> {
System.out.println(key + " : " + value);
});
}
public record CookingRoomKey(UUID uuid, CookingPotType potType, int roomIndex){
}
how do you think ? I redesign the code with Multimap it's just for test code (just for example)
It seems like works well
CookingRoomKey[uuid=4cea3e34-bfee-42c1-b2cd-8a1d0fae0479, potType=NORMAL, roomIndex=0] : io.github.daawn.CookingRoom@762efe5d
CookingRoomKey[uuid=4cea3e34-bfee-42c1-b2cd-8a1d0fae0479, potType=NORMAL, roomIndex=1] : io.github.daawn.CookingRoom@5d22bbb7
looks ok
is there any better way?
Not that I can see
got it thank youuuu
I think this is right 'cause room index couldn't be the same
private final Table<UUID, CookingPotType, Map<Integer, UserCookingRoomTask>> cookingPotMapTable = HashBasedTable.create();
but you said, the MultiMap is allowed duplicate keys
private final Multimap<CookingRoomTaskKey, UserCookingRoomTask> userCookingRoomTaskMap = ArrayListMultimap.create();
how do you think?
I mean Multimap allows multiple values for a single key
And a ListMultimap allows u to have duplicate values for a single key since the backing value of the map is of type List
This isnβt the case if youβd use a SetMultimap though
I don't think multiple map's key isn't a single key 'cause when I tested it like this:
public static void main(String[] args) {
Multimap<String,String> map = ArrayListMultimap.create();
map.put("uuid", "test");
map.put("uuid", "qwer");
map.keys().forEach(System.out::println);
}
the result was
uuid
uuid
and I think ListMultimap is same as MultipleMap
public static void main(String[] args) {
ListMultimap<String,String> map = ArrayListMultimap.create();
map.put("uuid", "test");
map.put("uuid", "qwer");
map.keys().forEach(System.out::println);
System.out.println(map.keys().size());
}
result:
uuid
uuid
2
well yeah it is
use a single string
String key = "uuid";
map.put(...
hmm then how can I use ListMultimap ?
the list part is just about the implementation thats different
idk
i dont know the difference
just use a normal multimap
map.put("UUID"
map.put("UUID"
two different keys
also a different approwch is just to create a cookingroom and add a cooking type and uuid in that class
and then just have a list of rooms
Hey guy can anyone help pls ? i am trying to make a plugin that makes item invisbible when held in hand using packets protocole lib but its not working i have no idea why
here is me code
https://mclo.gs/2I5YiJS
I may be wrong but wouldn't that be a client side thing and therefore not be able to be modified with packets?
Sorry for answering late, I'm not sure about that because I've never used bungeecord. But if it works on 17, I'd use 17
Hey, does someone when did the way on making custom enchantments change?
I found a resource from january this year but don't think it works for my version (using 1.20.1)
I'm looking on how to do it but don't know if I should check a 1.15 guide
custom enchantments in what sense?
if you add some nbt tags to a tool (pickaxe) and then listen to events (block break) in which you check if that tool is enchanted with whatever, and if so, then you do some crazy stuff, the version shouldn't matter
if you want to put enchantments into bukkit's registry, then it's a bigger deal
I can do it with nbt tags
Custom enchantments will probably change a bit with 1.21 (since enchantments are now data not code)
There may be a better way to do them then all the ways before.
It doesn't
use @Data if you want put @Getter and @Setter together
its possible check if player is with a worlddownloader mod?
if not send nothing on join server (worddownloader modified)
Do you mean https://github.com/mircokroon/minecraft-world-downloader ?
That is not a mod.
Proxy
maybe
on 1.8 have mod for this
mod for forge
iirc you can somehow query the mods
or they are sent when joining a server
what is irc
If I recall correctly
well ye
you have no guaranteed way of fully blocking ppl
how do you think hacked clients exist
you can maybe block the normal user
Does anybody here use WSL? (linux subsystem for windows)
?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!
everyone has a modified worlddownloader
that is the problem
Why
You sending the world to the player anyways
If somebody reallly wants to download ur world they could as well just write a script to intercept packets and recostrunct the chunks from that
That's what this thing does I believe
By the way, I was interested in 1 point. How do servers filter banned mods? Through anti-cheat?
Doubt anything can really prevent it, maybe if you filter out what you send to only be what the player can see, but that's too much effort and too inefficient for a price too low
but technically the anti-cheat allows you to do this without allowing the player to fly in survival mode, for example
Ah yes
But it doesn't intercept packets, it just communicates by itself I think
