#help-development
1 messages · Page 1708 of 1
They did say it's deprecated
oh speaking of that
theres this thing in the cod
that idk what it does
(i didnt write the code, someone said he was gonna fix it a bit so i didnt put the scheduler)
this
idk what it do cause it wasnt showing in game
hm
its not a static method of Team
oh
Get the team first
how?
Probably something like Team damage = player.getScoreboard().getTeam("damage");
in the scoreboard yes?
Then damage.addEntry(player.getName());
I haven't dealt with scoreboard yet so not entirely sure how it operates
You should learn Java first
change it to something else
Is there a way to like enable every shulker box type (blue, green, red, etc..) without having to multiply the recipes or smth like that?
ShapedRecipe recipe = new ShapedRecipe(NamespacedKey.minecraft("wand"), PokeballApi.getPokeball());
recipe.shape(
" E ",
"DSD",
" N ");
recipe.setIngredient('E', Material.ENDER_PEARL);
recipe.setIngredient('D', Material.DRAGON_BREATH);
recipe.setIngredient('S', Material.SHULKER_BOX);
recipe.setIngredient('N', Material.NAME_TAG);
pokeballMain.getServer().addRecipe(recipe);
hi guys, I apparently need org.bukkit.event.world.EntitiesLoadEvent, but my gradle build script can't seem to find it; I have compileOnly("org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT") as a resource and api-version 1.17 is declared in plugin.yml, what do I miss?
^
as i said, change one of the variables something else
anyone have an up to date resource for scoreboards?
Check if it has a tag, if not you can make a list of choices
At the InventoryClickEvent, the event is canceled, but when I press Shift on the items, they bug into my inventory
tag?
Inventory click event is supply buggy, it doesn’t get run half the time
Never had an issue with it
@solar sable you have defined "damage" twice
How would I approach making an drag and drop enchant book
oh um and how do i implement that tag never worked with it
i changed it
like Tag<Material.SHULKER_BOX>
did you refactor?
i changed it to Team player = player.getScoreboard().getTeam("damage")
Like you drag an book onto a pickaxe and it adds lore and an PersistentDataContainer entry
You already have a player defined
change it to something like damage2
oh um and how do i implement that tag never worked with it
is there a way to know the BlockFace which the Player is looking at ? nvm found it
if (Tag.SHULKER_BOX.isTagged(itemHere))
you refactored right?
oh however its spelt
SHULKER_BOX
They want it for a recipe
idk
what is the damage2 for
you told me to make it damage2
okie
what is the error now btw @solar sable
@neon nymph like this?
"hi i have issue, idk what's causing it so here's a screenshot. there's red lines but i choose to ignore them because idk what they are"
[00:11:54] [Server thread/INFO]: [CoolPluginTest] [STDOUT] damage Team was either deleted, or doesn't exist
[00:11:54] [Server thread/WARN]: java.lang.IllegalAccessException: Damage cannot be null
[00:11:54] [Server thread/WARN]: at testing-1.0.jar//me.amxyargaming.testing.PlayerScoreboard.updateDamage(PlayerScoreboard.java:48)
[00:11:54] [Server thread/WARN]: at testing-1.0.jar//me.amxyargaming.testing.PlayerScoreboard.lambda$showScoreboard$0(PlayerScoreboard.java:37)
[00:11:54] [Server thread/WARN]: at org.bukkit.craftbukkit.v1_17_R1.scheduler.CraftTask.run(CraftTask.java:101)
[00:11:54] [Server thread/WARN]: at org.bukkit.craftbukkit.v1_17_R1.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:483)
[00:11:54] [Server thread/WARN]: at net.minecraft.server.MinecraftServer.b(MinecraftServer.java:1559)
[00:11:54] [Server thread/WARN]: at net.minecraft.server.dedicated.DedicatedServer.b(DedicatedServer.java:479)
[00:11:54] [Server thread/WARN]: at net.minecraft.server.MinecraftServer.a(MinecraftServer.java:1475)
[00:11:54] [Server thread/WARN]: at net.minecraft.server.MinecraftServer.x(MinecraftServer.java:1274)
[00:11:54] [Server thread/WARN]: at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:319)
[00:11:54] [Server thread/WARN]: at java.base/java.lang.Thread.run(Thread.java:833)
lol?
wait @solar sable can you explain what you want to achieve today?
do damage.addEntry(player.getName()); afterwards.
And how do I implement the Tag into the MaterialChoice? RecipeChoice.MaterialChoice shulkerBoxes = new RecipeChoice.MaterialChoice();
an updating scoreboard?
yeah and what do you want it to show?
damage dealt?
Look at the constructors
is there any reason why this custom persistent data type wouldn't work? https://paste.md-5.net/bomobuqehu.cpp
well i want it to be working first, and then ill see if i can add more
so RecipeChoice.MaterialChoice shulkerBoxes = new RecipeChoice.MaterialChoice(new Tag<SHULKER_BOXES>);?
How would I set a location yaw and pitch to match a vectors direction?
Tag.SHULKER_BOXES.getValues().forEach(material -> recipe.setIngredient('S', material));
@quaint mantle
thanks
Idk if that works, but try
Ensure damage != null
Sigh
^ I know there isn't a lot of info, but there isn't a lot of info for me to give, no errors. It just doesn't work
okie dokie
if (damage != null) return; Or something like that
new RecipeChoice.MaterialChoice(Tag.SHULKER_BOXES)
better?
Yea sure
or this lol
Either you prefer
ill just use the if (damage != null)
or if (damage != null) return;
Thanks that works.
this one line of code works
And for debugging purposes, add a temporary else that prints out "damage is null sad"
learn what is a Enum
lol
crossing fingers hoping this will work rn
also whats the difference from POSTWORLD and STARTUP ?
nm solved building against a spigot derivative
Your plugin gets loaded before the world itself is loaded or after
aah
what about making it load first than the other plugins lol its a just a thing that is funny to learn
It's fine, but if your plugin depends on another plugin, that other plugin needs to be loaded first
aah
okeh ok
also can i just say that, using this --> ChatColor.translateAlternateColorCodes('&', "<put message here>")); is just wonderful
please 🙏
help
@eternal oxide
?paste your class
and it is still not updating 🙂 @neon nymph
theres no error in console either
its just not updating
my brain java if (CJ.hasProblem == true && ElgarL isOnline true || imaginedev isOnline true) { System.out.println("At one of them")} lol
whats not workign with it?
== true
lol
why is this one scoreboard project takes so long 😫
that i know
To start, save your new scoreboard somewhere
okeh
Then when a player joins, set their scoreboard to that

or reuse this one
I highly suggest you learn java first, plugin development assumes you already know the basics
It might not actually be that class, but what I'm doing with it, here is my sethome and home command class
sethome: https://paste.md-5.net/vevepugero.java
home: https://paste.md-5.net/wubebeture.java
?learnjava yee
Here are some links to get you started on learning Java:
- https://www.codecademy.com/learn/learn-java
- https://www.sololearn.com/learning/1068
- https://www.learnjavaonline.org/
- https://programmingbydoing.com/
- https://docs.oracle.com/javase/tutorial/java/index.html
The last one is the only official one, however some of those concepts assume that you already know a bit about programming.
I did some some now me intermediate yay
Ye same lol
sorry for asking a lot, can anyone help me with this ?
you are using different keys
You know default runs regardless ?
oooh
Home is using a
lol
I believe it even bypasses break @quaint mantle
what is wrong there
The default
i removed it
It will run on all cases
(:
I just copied it to IntelliJ and it says "cannot resolve symbol lombok" How can I fix that?
@ivory sleet https://paste.md-5.net/umudusocut.java
to the new scoreboard?
default does not run regarless
im going to eat dinner
@eternal oxide Still not working
Remove the imports and just write a constructor by Hand.
Then pmz check if hologramManager still is null, if it is then prompt the console with the abnormal version message
Does it not? Thought it always did
Well haven’t used switches in ages so that’s probably why
What is failing?
A constructor for what?
when I do /home, it just says "You do not yet have a home set! Set one with /sethome"
I assume you did already set one?
yes
I think
idk if it actually set one
I did /sethome
it could be a problem with either one
put a sysout in the sethome to tell you when you set it
and make sure line 23 in Home uses "home"
Oh I think I got it!
now there's only this one left. Can I just do Main.getPlugin() ?
i'll try
any tipps? anything? the minecraft version is called limbo
Yes
so i create a new scoreboard and then set the onPlayerJoin to that scoreboard, got it
Can i somehow serialize or save all the values about a Entity class (Zombie, etc...) to yaml config?
After creating a new scoreboard create a new team in it as well
Get it’s tag compound probably Pavlyi
Using nms
An easy way to do it but not flexible
eehh and how do i get the tag compound ?
oh okaay
@eternal oxide I got it working!
if i dont have the CraftEntity class i need the spigot and not ther spigot-api right?
wdym
you mean should i check if
hologrammanager == null ?
Yeah
Ya
?paste
There's no getTag() function
Yeah probably named something else
@eternal oxide I thought it was working, for some reason it works for me, but I got one of my friends to get on and they tried it and nothing happened
do your commands need permissions to use?
nope
the commands work
I think
wait
lemme ask him something
I asked him, and it didn't say "You do not yet have a home set! Set one with /sethome" to him
if you added permissions to the plugin.yml
like I said, I didn't
didn;t you set it to ops?
this is my plugin.yml https://paste.md-5.net/uhudowitob.makefile
ok, only heal is op
ye
no clue then. There is nothing in your code that I've seen which would make it work for one person and not another.
I'm using the player name as the key
players can change names
then they would be left with junk data in their player file and would lose their homes
ok, I will. But I'm guessing that wouldn't fix the big problem
Is there a way to find out whenever Player is feeding Animal and prevent that?
@EventHandler(priority = EventPriority.HIGHEST)
public void onAnimal1(PlayerInteractEvent e){
e.setCancelled(true);
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onAnimal2(EntityInteractEvent e){
e.setCancelled(true);
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onAnimal3(PlayerInteractAtEntityEvent e)
e.setCancelled(true);
}```
Tried cancelling those events with both HIGHEST and also LOWEST priority and it seems to just be ignoring it.
Any clues?
i guess playerinteractatentity event
I'm cancelling all at the same time
And it still bypasses them
And feeds and consumes the items
did you register the listeners?
Yes
Anything else in the Sever it's cancelled due to events also cancelled
Literally i can't do anything
But feed Animals
Somehow?
Tried searching in Google,Bukkit,Spigot any other forum i could find
No clues
What's the javadoc to give an user an item when he joins?
Cancelled Tame and Breed event
Still bypassing
public void createScoreboard(Player player) {
ScoreboardManager manager = Bukkit.getScoreboardManager();
Scoreboard scoreboard = manager.getNewScoreboard();
Objective objective = scoreboard.registerNewObjective("title", "dummy", ChatColor.translateAlternateColorCodes('&', "&b&lCYBERCADE &7["+Bukkit.getOnlinePlayers().size()+"&7]"));
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
// I left out the lines
player.setScoreboard(scoreboard);
when a player disconnects from the server, does the server automatically add the scoreboard to the garbage collector? i've seen other people delete thier scoreboards from helpers when the players disconnect. should i do this too?
Like cancelling all 5 events at the same time. It just ignores
Hey, I am currently trying to import another plugins source code to make my own (private) version.
It is made with gradle and I have got everything imported in. My only problem now is that there is a .kt (kotlin?) file for the "volatile code" (I guess for making it work on multiple versions) and my problem is, that it somehow cant find the craftbukkit & the net.minecraft packages even though I have manually imported them.
does your private plugin allow kotlin files in it?
if not, intellij has a kotlin>java converter
I have a question about IntelliJ
Can I compile just certain files into a jar file? and if yes, how?
I know that there is a plugin for MC developement,a nd I also have it, but I am following a book I was gifted about making MC plugins, so I'm trying to do what it says, and it wants me to use eclipse, but I prefer IntelliJ's look (bcz I'm used to PyCharm lol)
but idk how to compile my files into a jar file..
I have a plugin.yml and a pluginname.java file so far, and ig the IDE can make a .jar file out of those somehow... i just don't know how...
Hello,
I have a little problem with Spring, I am not sure if there is someone good with it. But i am
using spring boot (https://github.com/Alan-Gomes/mcspring-boot), And sometimes i have a trouble, it throw
me a up an exception (NoClassDefFoundException). But i dont know why. I looked up something about it, but i couldnt
solve the problem out.
Code on Enable:
Thread.currentThread().setContextClassLoader(getClassLoader());
ResourceLoader loader = new DefaultResourceLoader(getClassLoader());
SpringApplication application = new SpringApplication(loader, Application.class) {
@Override
public void setListeners(Collection<? extends ApplicationListener<?>> listeners) {
super.setListeners(listeners
.stream()
.filter((listener) -> !(listener instanceof org.springframework.boot.context.logging.LoggingApplicationListener))
.collect(Collectors.toList()));
}
};
application.addInitializers(new SpringSpigotInitializer(this));
Properties properties = new Properties();
try {
properties.load(getClassLoader().getResourceAsStream("application.properties"));
} catch (IOException ex) {
ex.printStackTrace();
}
setupDatabase(properties);
application.setDefaultProperties(properties);
this.context = application.run();```
there's a book for making minecraft plugins? sounds like a waste of money lol
seemingly there is
but hey it teaches me the basics of java and plugin dev so why not
- it's rude to just tell my big bro "f off with that waste u bought" lol
I appreciate it ^^
yes you can compile only certain files
however you would have to modularise your structure
unlike python
java has to compile
so it would be a big problem if you could handfully select a few classes contained in a source set
oh dw, I've only palyed around with python code, not really compiling anything or sth like that
it's fun tho
Yeah I enjoy python for small stuff
but it becomes quite messy when trying to scale projects from my experience
what does this mean tho? ':D
modularise?...
at least if you take an object oriented approach that is
Any clues on that?
I didn't even get to classes... so... does python have classes? xD
yes
nice
it is multiparadigm after all x)
yo what does that mean? xD
style of programming - paradigm
multiparadigm means it contains the features which provides the developer to use different styles
there's mainly functional, object oriented and procedural iirc
well logical
also
I think it's kinda obvious that I'm a true noob to programming haha
I barely have any experience, and only know C++ basics, and just a lil bit of python
yeah
well anyway...
would you mind explaining to me how I can compile these two files I have intoa jar file? ':D
anyways by modularize I mean that you can have multiple source sets and then select which sourcesets to include into your jar
hmmm
well I think I only have a single source file, and that is my pluginname.java
you said earlier that you used intellij?
and tbh I have no clue what I could / should do with the .idea folder
The home of Spigot a high performance, no lag customized CraftBukkit Minecraft server API, and BungeeCord, the cloud server proxy.
mhm, but I have basically no idea how to use it
(tbh I have no idea how to use any IDE, VS, Eclipse, PyCharm, IntelliJ, damn I'm stupid xD)
I recommend reading that guide
I'd recommend IntelliJ
but the importance is that you give every ide a try before deciding which one to use
yeah it was recommended to me too
I tried eclipse before it
my eyes die when I look at the design
Sublime text 😁
I agree, because IMO if you know how to use your IDE, then it doesn't matter which one you are using
Noone helps to me ?
that's not an IDE it's a code editor hehe
pretty much
Try Inteliij 😄
you probably want to shade in spring
if you havent done that
and thats a huge lib
thx for this tho, I'll read it and come back if I have questions, the peeps here are nice :)
I have dont that, its work sometimes, but sometimes It throw up this exception
?paste the entire stacktrace
I have that(Spring-Boot) in lib folder, and plugin is separated
Spring is a good framework. Setup some basic REST api and a simple frontend and backend in less than 30min
its thick tho lol
I just have spring-boot 😄 not other thinks
20mb ish
I'm not making a plugin so that's perfectly fine for me
Kotlin :kekw:
😏
If someone seriously try to help me, I already created a post on spigot forum.
https://www.spigotmc.org/threads/spring-noclassdeffound.527399/
(Sorry, if there is a issue with link)
well
I am still going to ask for the stacktrace
just the NCDFE doesnt say much else than that some class couldnt be loaded during runtime due to absence
I looked up for it, but didnt find anything
just a quick question, why does the server memorize the attribute max_health, but not the attribute movement_speed (entity is a player) after reconnecting
ping when you respond ty :)
usually errors yield something like
that at blah
at blah.blah
is the stack trace
might be a plugin which resets it?
let me check
no i dont think so, since only other plugins are health display plugins
Hmmm
i even cleared all the other plugins, and so its not a cause for sure
} else if (e.getCurrentItem().getType() == Material.RED_BED) {
String name = ChatColor.stripColor(e.getClickedInventory().getItem(4).getItemMeta().getDisplayName());
Player playerwhoisban = Bukkit.getPlayer(name);
Location bedloc = playerwhoisban.getBedLocation();
p.teleport(bedloc);
playerwhoisban.playEffect(playerwhoisban.getBedLocation(), Effect.DRAGON_BREATH, 0);
p.sendMessage(ChatColor.GREEN + "TP'd to" + name + "'s Bed!'");
System.out.println(ChatColor.WHITE + "[" + ChatColor.RED + "BAN EM" + ChatColor.WHITE + "]" + " " + ChatColor.RED + "Just Gone TO " + " " + name + "'s Bed!");
p.playNote(p.getEyeLocation(), Instrument.PIANO, Note.flat(1, Note.Tone.A));```
anyone know why this aint working ?
nvm
works
yea
repo ?
slovakia instead of montenegro smh 😄
😄
This is my forked repository and modified for 1.17 version
Just upgraded spring boot version to newest and changed compile version to java 16
where is the sk.westland.world code?
oh u look after for my code its private 😄
but what do u need from this code ? just command ?
well I dont need the code
but the build structure
because it says one of your classes is missing (not contained in ur jar presumably)
(the exception and the stacktrace)
This might sound dumb but how can I want for an event to get called inside a CompletableFuture?
Or some action to happen
Just call PluginManager#callEvent inside the future?
I know what do u mean, but it throws me sometimes not always
inside the future?
Idk I mean the callEvent method will call the event on the thread which invoked the function
My idea is like
so naturally it will be blocking on that thread which the future runs on
you don't wait for an event in a Future, you start the Future when the event fires
wait for event to get called
return some event value on the future
oh yeah then locking might be need
probably want to go with a fifo reentrant lock here
Could you give an example?
@ivory sleet
I think, I uploaded there everythink what do u need ? 🤔
https://www.spigotmc.org/threads/spring-noclassdeffound.527399/
List is null ?
seems to me that the lock would require a while loop 🤔
show to us a main.bossBar
that might tank performance
Does someone has an idea about that?
If I understood correctly
Lock lock = new ReentrantLock(true);
Condition condition = lock.newCondition();
AtomicReference<V> ref = new AtomicReference<>();
CompletableFuture<?> future = CompletableFuture.supplyAsync(() -> {
condition.await(); //try and catch ofc
Value value = ref.get();
});
void on(E e) {
lock.lock()
try {
ref.set(e.getValue());
condition.signal();
} finally {
lock.unlock();
}
}```
Might want something like this but with a reusable condition
also yeah
the locking might not even be needed
and if thats the case
maybe a CyclicBarrier would be better here
assuming you wanna await some value
welp time to make my own system based on this
Basically my code looks a bit like this
oh
Packet system is proprietary
btw
check that out
idk if a reentrant lock is totally necessary here
and (condition)
The packet is sent through some handler and another packet is sent back with the response
oo yeah
public class Main extends JavaPlugin {
BossBar bossBar;
private static Main main;
@Override
public void onEnable() {
main = this;
Bukkit.getPluginManager().registerEvents(new JoinListener(this), this);
BossBar bossBar = Bukkit.createBossBar(
ChatColor.BLUE + "Welcome To LaserTag Have Fun",
BarColor.BLUE,
BarStyle.SOLID);
}
public static Main getInstance(){
return main;
}
public BossBar getBossBar(){
return bossBar;
}
}```
--- JoinListener:
```Main.getInstance().getBossBar().addPlayer(...);```
do something like this
why
why are you doing singleton + dependency injection
naming your class Main and not making your bossBar private
while having no indentation
oh god
monka
how tf does this lock stuff work
I kinda gotta double lock
Like
I block the thread until another method gets called 🤔
Senor, the main does not have error, if you bothered to hover over it you'd see your IDE is warning you to make the field final.
and if you're passing through your main instance, use it. Don't use the static accessor you've created
You have an instance there 😛
God even my codestyle as someone learning Java was better than whatever the fuck is going on here.
Everyone learns differently
ok so back to the attribute movement speed, ive tried it on all levels do i report it as a bug?
On what entity? Not all entities support that attribute
player
i mean that after logging back on the attribute resets
everything works fine just that one thing, i mean its easy to go around it and save the number, and then after relogging setting his speed again, but its annoying
Oh, of course it does. afaik player attributes aren't persistent
max health is persistent
Well, that depends. How are you setting it? With a modifier? Or just setting the base value?
setting the base value
whats exactly a modifier, like a link or smth ;)
oh ok thanks
new AttributeModifier(UUID.fromString("a-constant-uuid-here"), "some unique name here", 2.0, Operation.ADD_NUMBER)
That will add 2.0 to the base value
I'd make that UUID.fromString() a constant somewhere so you can easily refer to it. If you just use UUID.randomUUID(), it will make a new one each time and re-apply it. Not ideal
hmm okay
Can someone help me? I'm making a plugin and the code doesn't give me any error but when I put in on the Minecraft server, the console shows this:
java.lang.IllegalArgumentException: Plugin already initialized!
at org.bukkit.plugin.java.PluginClassLoader.initialize(PluginClassLoader.java:224) ~[patched_1.17.1.jar:git-Paper-278]
at org.bukkit.plugin.java.JavaPlugin.<init>(JavaPlugin.java:53) ~[patched_1.17.1.jar:git-Paper-278]
at me.mrstreeet.logintitle.LoginTitle.<init>(LoginTitle.java:21) ~[LoginTitle-1.0-SNAPSHOT.jar:?]
at me.mrstreeet.logintitle.LoginTitle.onEnable(LoginTitle.java:28) ~[LoginTitle-1.0-SNAPSHOT.jar:?]
at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:264) ~[patched_1.17.1.jar:git-Paper-278]
at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:370) ~[patched_1.17.1.jar:git-Paper-278]
at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:500) ~[patched_1.17.1.jar:git-Paper-278]
at org.bukkit.craftbukkit.v1_17_R1.CraftServer.enablePlugin(CraftServer.java:535) ~[patched_1.17.1.jar:git-Paper-278]
at org.bukkit.craftbukkit.v1_17_R1.CraftServer.enablePlugins(CraftServer.java:449) ~[patched_1.17.1.jar:git-Paper-278]
at net.minecraft.server.MinecraftServer.loadWorld(MinecraftServer.java:725) ~[patched_1.17.1.jar:git-Paper-278]
at net.minecraft.server.dedicated.DedicatedServer.init(DedicatedServer.java:306) ~[patched_1.17.1.jar:git-Paper-278]
at net.minecraft.server.MinecraftServer.x(MinecraftServer.java:1212) ~[patched_1.17.1.jar:git-Paper-278]
at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:319) ~[patched_1.17.1.jar:git-Paper-278]
at java.lang.Thread.run(Thread.java:831) [?:?]
Caused by: java.lang.IllegalStateException: Initial initialization
at org.bukkit.plugin.java.PluginClassLoader.initialize(PluginClassLoader.java:227) ~[patched_1.17.1.jar:git-Paper-278]
at org.bukkit.plugin.java.JavaPlugin.<init>(JavaPlugin.java:53) ~[patched_1.17.1.jar:git-Paper-278]
at me.mrstreeet.logintitle.LoginTitle.<init>(LoginTitle.java:21) ~[LoginTitle-1.0-SNAPSHOT.jar:?]
at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:?]
at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:78) ~[?:?]
at jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:?]
at java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) ~[?:?]
at java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:128) ~[?:?]
at jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:350) ~[?:?]
at java.lang.Class.newInstance(Class.java:642) ~[?:?]
at org.bukkit.plugin.java.PluginClassLoader.<init>(PluginClassLoader.java:83) ~[patched_1.17.1.jar:git-Paper-278]
at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:153) ~[patched_1.17.1.jar:git-Paper-278]
at org.bukkit.plugin.SimplePluginManager.loadPlugin(SimplePluginManager.java:414) ~[patched_1.17.1.jar:git-Paper-278]
at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager.java:322) ~[patched_1.17.1.jar:git-Paper-278]
at org.bukkit.craftbukkit.v1_17_R1.CraftServer.loadPlugins(CraftServer.java:410) ~[patched_1.17.1.jar:git-Paper-278]
at net.minecraft.server.dedicated.DedicatedServer.init(DedicatedServer.java:276) ~[patched_1.17.1.jar:git-Paper-278]
... 3 more```
Yeah you are probably doing something you are not supposed to do in your constructor or fields of your JavaPlugin class.
Show some code pls.
That or you have two of the same plugin in the plugins folder
No, I don't
Then yeah, strange constructor business
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
getServer().getPluginManager().registerEvents(new LoginTitle(), this);
You can't create new instances of your plugin
You are not allowed to create instance of JavaPlugin classes.
👍
did you instantiate your main class
Do you call new LoginTitle() anywhere in your code?
nope
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Sound;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.io.IOException;
public final class LoginTitle extends JavaPlugin implements Listener {
public static LoginTitle instance;
@Override
public void onEnable() {
getServer().getPluginManager().registerEvents(this, this);
getServer().getConsoleSender().sendMessage(ChatColor.GREEN + "[LoginTitle] Plugin it's working in the version 1.0 BETA.");
getCommand("reload").setExecutor(new Reload());
createFiles();
instance=this;
}
@Override
public void onDisable() {
getServer().getConsoleSender().sendMessage(ChatColor.RED + "[LoginTitle] Plugin has stopped.");
}
@EventHandler
public void onLogin(PlayerJoinEvent event) {
Player p = event.getPlayer();
Bukkit.getScheduler().runTaskLater(this, () -> { p.playSound(p.getLocation(), Sound.valueOf(getConfig().getString("sound")), 1, 1); }, 20L);
Bukkit.getScheduler().runTaskLater(this, () -> { p.sendTitle(getConfig().getString("title"), getConfig().getString("subtitle"), -1, -1, -1); }, 20L);
}
private File configf;
private FileConfiguration config;
private void createFiles() {
configf = new File(getDataFolder(), "config.yml");
if (!configf.exists()) {
configf.getParentFile().mkdirs();
saveResource("config.yml", false);
}
config = new YamlConfiguration();
try {
config.load(configf);
} catch (IOException | InvalidConfigurationException e) {
e.printStackTrace();
}
}
}
Maybe this?
Constructor of Reload does
Yeah, you're extending JavaPlugin
what I need to do then?
If you need an instance of your JavaPlugin class you're going to have to pass an instance through its constructor
private final LoginTitle plugin;
public Reload(LoginTitle plugin) {
this.plugin = plugin;
}```
Then you can refer to plugin.reloadConfig()
When constructing the reload class, pass in this
I need to put this in the Reload.java?
Instance = this
Yes
oke
yes
public, not plugin ;p
When constructing the reload class, pass in this
java is hard 🤔
wdym "pass in this" (sorry not english speaker)
this
ikr, im learning and it's so confusing :c
?di
Guide to dependency injection: https://www.spigotmc.org/wiki/using-dependency-injection/
Alredy did all the things you did
you gotta access the config from your main class using the plugin variable you made
Then you can refer to plugin.reloadConfig()
Whats the main benefit for dependency injection over singleton? Singleton IMO seems so much cleaner
Tight coupling
If you can pass through instances, you're better to do so
DI forces you to really think about your design.
There are times however where doing so is either impossible or extremely awkward to do
Bukkit's schedulers sometimes makes that clear
In which case singleton access is fine 
My general rule of thumb for plugins is that if you can pass through an instance, do it. If you absolutely can't without breaking plugin flow, singleton. It's a last resort
:P
Commands and event listeners are by far among the most simple instances to pass plugin instances. You're only ever creating single instances of these objects and it's generally in the plugin class anyways. Using this does not hurt
😔 putting your listeners in the main class
?di
Guide to dependency injection: https://www.spigotmc.org/wiki/using-dependency-injection/
Sorry please im learning D:
Now I have a question, the command runs perfectly, but it works with this
private Block block;
@Override
public void onEnable() {
Bukkit.getPluginManager().registerEvents(new Listener() {
@EventHandler
public void onSneak(final PlayerToggleSneakEvent event) {
if (event.isSneaking()) {
return;
}
SpigotSandbox.this.block = event.getPlayer().getLocation().getBlock();
}
}, this);
}
😄
How I can make it like this?
ill cry
have y’all seen the recent pr to spigot - not merged but from the looks of it a lot of the enums are getting changed
as in the names
Your commands alias currently is 'reload'
You need to rename it to 'logintitle' and create a sub-command using the arguments.
?
You mean in plugin.yml?
Yes. You also need to change the value in your onEnable
I guess I still don't really understand the DI benefit over Singleton. The link provided by Conclure has 3 reasonings ¯_(ツ)_/¯
wheres
the rest of it

Guess I'll retype it ffs
First of all it will be difficult to unit test an instance of that class, since we will inherently test the static singleton also. - I know literally nothing about unit testing, so this benefit doesn't really do anything for me specifically. Maybe I should start, but I don't even know what it is!
Second, we will not be able to reuse the class for another MyPluginDataManager instance. - This makes sense when working with other classes, but for the main plugin class, we only ever need 1 instance anyways.
Third by using a static singleton you have complexified your code architecture. - I don't understand how Singletons make it more complicated.
For example, if you're instantiating a class within another class, that's instantiated within another class, etc etc, you'd have to pass y our plugin instance across every single one of the classes, JUST so you can use it in the one you're trying to get to, regardless of whether the first 2 classes actually use the plugin instance or not. It seems like that would be far more complicated than just "oh, I need my plugin instance for this class. Main.getInstance() done."
Any idea how i can prevent Animals from being Right clicked and fed by Food?
Interact Events doesn't work.
PlayerInteractAtEntityEvent
Doesn't work
Tried already
On every priority
Literally tried
@EventHandler(priority = EventPriority.HIGHEST)
public void onInteract(PlayerInteractAtEntityEvent e){
e.setCancelled(true);
}
And it ignores it
Tried also HIGH, NORMAL, LOW and LOWEST
None of them seems to work at all
Are you registering the event
Yes
Anything else it's entirely disabled
But Feeding animals with food is not
Could that be Client sided ?
And there is no event for that?
You can infinite feed Animals with Food
Did you try just the PlayerInteractEntityEvent
Just tested it. Works:
@EventHandler
public void onInteract(final PlayerInteractEntityEvent event) {
event.setCancelled(true);
}
Right click a Baby Cow
With a wheat
it continuosly consumes it
What server version?
1.16.5
Yes
You implemented listener too right?
Yes
I've tried to System.Out the Event
debug
It does fire the event
But even tho cancelled. It doesn't matter to the Baby cow
Very interesting. It blocks the interaction with adult animals but not with babies...
Exactly
You can feed Babies
FOREVER
And no event handles that
Therefore i thought it might be Client sided?
Ehm, well, the server would still have to consume the item
Oh the event is still cancelled. THe client just shows some particles.
I've read you can player.UpdateInventory
As it's "visual"
Apparently that's not the case
It right away consumes the item
Did you delay the updateInventory()?
Because if you're doing it in the event, it won't work
Tried 1 tick

man inventories make me cry
I thought my code was broken because the display on my inventory wasn't working, but it was just an issue with viaversion/the server being on 1.12
That's the literal cancel event?
I get the ghost item as well ^ I guess it just likes 7smile more 
Delaying updateInventory() works though
Let me try once again then
Then i guess either one of those Plugins
It's just doing it wrong
AS they continue consuming for me
While my plugin LCCommands being as Highest priority and cancelling the event
@EventHandler(priority = EventPriority.HIGHEST)
public void onInteract(PlayerInteractAtEntityEvent e){
e.setCancelled(true);
plugin.getServer().getScheduler().runTaskLater(plugin, () -> e.getPlayer().updateInventory(),1L);
}
Either i'm doing it wrong or i don't know
I don't know what i am doing wrong tho
@EventHandler(priority = EventPriority.HIGHEST)
public void onInteract(PlayerInteractAtEntityEvent e){
System.out.println("Event Fired");
e.setCancelled(true);
plugin.getServer().getScheduler().runTaskLater(plugin, () -> e.getPlayer().updateInventory(),1L);
}```
But it literally fires the event and it spoon feeds the Cow
You are using a different event
"PlayerInteractEntityEvent"
"PlayerInteractAtEntityEvent"
🤔 not confusing at all /s
How would I make a spigot plugin with maven, I can't find anything to help me and I would like to start using maven. (I'm using Eclipse IDE)
wut
dont use the slash commands they don't work
PortalCreateEvent
Hello! I have a problem, I'm doing subcommands in my plugin and when i want to put private final LoginTitle plugin; public ReloadCommand(LoginTitle plugin){ this.plugin = plugin; }
appears a problem
this one
You defined a constructor that demands one instance of LoginTitle but you dont provide it with one.
What I need to do?
Pass an instance of LoginTitle.
How? (I'm new coding)
Jumping into spigot development without learning the very basics of Java is a recipe for failure.
- Get an instance of your LoginTitle class
- Pass it via the constructor as an argument
There are several ways of obtaining an instance of your JavaPlugin class.
?di
Guide to dependency injection: https://www.spigotmc.org/wiki/using-dependency-injection/
u mean this?
Jeah for example
thats what I did
Yes this defines a constructor.
Now when you call this constructor you need to pass all arguments like you would with a normal method.
im lost
LoginTitle title = ...;
ReloadCommand command = new ReloadCommand(title);
I need to do that in the main class then?
You need to do this when you create an instance of ReloadCommand. Aka calling the constructor of ReloadCommand.
smh
is there a way to check for every glass type
ik there is Tag.Leaves etc but I can't find one for glass
private boolean isGlass(Material mat) {
return mat.name().endsWith("_GLASS") || mat.name().endsWith("_GLASS_PANE");
}
thats the only way?
unless you wanna make a set of the materials, idk why you would
This is probably the best performing way:
private static final Set<Material> GLASSES = EnumSet.copyOf(Arrays.stream(Material.values())
.map(Enum::name)
.filter(mat -> mat.endsWith("_GLASS"))
.map(Material::matchMaterial)
.collect(Collectors.toSet()));
Material material = ...
if (GLASSES.contains(material)) {
}
Enum::name?
hmmm I did something similar with mob eggs before but I'm just surprised there isn't a easy way checking with the Tag class
because it works for wool
Yeah name() is usually the better way as toString might be overwritten for readability. In this case it makes no dif
guys the scoreboard updates now, but when i leave the game, it immediately floods my console with error message
Are you doing some reflection fkery?
so i have https://pastebin.com/12zjawgR, its sort of working i guess, when i do /moneygive 39 for the first time it gives me 39$, but if i do it a 2nd time for example /moneygive 21 it stays at 39
Stop tinkering with yaml files on runtime.
When the server starts -> load your data into classes
When the server stops -> save your data back into files
Man, idk but i always do this
Main class
this doesnt help... i just need a way to fix what i have rn since i sort of need to do it this way and its sort of workign so i dont see why i need to do that
well wdym by reflection fu*kery?
something something;
@Override
public void onEnable() {
something= new something(this);```
Main
Main plugin;
public something(something plugin) {
this.plugin = plugin;
}```
Because i can assure you that if you keep doing this then you will have lots and lots of problems in the future.
You will waste 10x more time than if you just properly re-wrote it now.
ive used this type of system before and it all works fine so idk :/ i just need to know how to fix it
FileConfiguration fc = new YamlConfiguration();
if (fc.getConfigurationSection("economy") == null) {
fc will never contain "economy"
So it will always return a null section
how does that work though? if im getting the same file after "economy" has been created?
Yeah but you never load the content of this File.
You just create an empty new YamlConfiguration without any content.
Yeah but the else will never be executed because your FileConfiguration will always be empty.
im still a bit confused, would i just need to add a load or something before the if part?
Lets go through this line by line ok?
What does this do?
File f = new File(plugin.getDataFolder() + "/economy/" + p.getUniqueId() + ".yml");
creates a file thats named the player's uuid
Almost right. It defines a File. It is not created and not loaded. It just defines a File.
2)
What does this line do?
FileConfiguration fc = new YamlConfiguration();
gets the configuration for the file so you can do stuff like getting strings and default config stuff
Nope this creates a new, clean, blank YamlConfiguration.
It has nothing in it and is completely empty.
The code doesnt know that you want to load the data from your File into this YamlConfiguration because you never told it to.
So fc is always empty no matter what you did before.
What is the implication for this line then:
if (fc.getConfigurationSection("economy") == null) {
wdym? like what will it do or what do i have it there for?
What will it do if fc is always empty.
always return null so the else part wont get activated
Correct
Seems dangerous
So to fix this you need to load the content from your File into your YamlConfiguration.
You can just flush your data async every 15 minutes or so. Its def 100x better than just manually using FileConfigurations.
so that would be try { fc.load(f); } catch (IOException | InvalidConfigurationException e) { e.printStackTrace(); } correct?
You can also just do this:
File file = new File(plugin.getDataFolder() + "/economy/" + p.getUniqueId() + ".yml");
FileConfiguration config = YamlConfiguration.loadConfiguration(file);
if (config.getConfigurationSection("economy") == null) {
i dont get any errors or anything, but im back to square one having the same issue as i orgininally was
What’s the original problem?
here
Looks to me like your only saving the file if it doesn’t exist.
im saving it in both?
https://cdn.discordapp.com/attachments/798282294670000161/891862992747110400/unknown.png this wouldnt be saving it in both?
Scrap this approach.
Just create an EconomyPlayer class and load your data when the player joins or the server starts.
Its much, much cleaner, and performs way better.
Remove the ! In the second one
oh dang it works thanks for the help 😄
how do i allow remote connections to my msql server
How do I get server plugins to work with Minehut?
is there an event for radius?
if (onPlayerTillBlock.getLocation().distance(player.getLocation())) > 5){ I'm really fucking stupid what is wrong with this
Show more code pls
Usually you should be able to connect to your sql server as long as you have a username and a password. Maybe you need to also open the port.
This is my first time trying to code so dont judge me please
`public class TillBlock implements Listener {
@EventHandler
public void onPlayerTillBlock(BlockBreakEvent event) {
Block blockBroken = event.getBlock();
if (blockBroken.getType() == Material.DIRT) {
event.setCancelled(true);
(blockBroken.setType(Material.LEGACY_SOIL);
Block onPlayerTillBlock;
Player player;
if (onPlayerTillBlock.getLocation().distance(player.getLocation())) > 5){
}
}
}
}`
(blockBroken.setType(Material.LEGACY_SOIL); you put a ( at the start by accident
both variables will be null
and you have too many ) on the second if statement too
How is your IDE not bullying you
why are they null though
you are declaring a variable, but assinging no value to it
how is the plugin supposed to know what "Player" means when you have no context for it
good point
Because you never initialised them.
Block block; <- This creates a Block variable named block without content.
Block block = event.getBlock(); <- This creates a Block variable named which and stores the value returned from the getBlock() method inside.
its like telling the server: "Give me block" - What block do you mean? What position, etc etc
I defined block but having trouble on how I would define the player
event.getPlayer() for BlockBreakEvent i think
you guys are legends I spend like 3 hours trying to solve that small issue
You mean like how many ticks the server ran since last restart?
yeah
not that easy
What is your goal. You can keep track of that on your own but it might be off by maybe 5 ticks.
to get the exact tick at which specific events are happening to an object of mine
making this inaccurate defeats the whole purpose of this system
Depends. If you need relative time then it suffices.
sure it depends, and based on my needs it makes it useless, hence why I said it
this is specifically so I can measure delays both in real time and in ticks between different parts of the code running
and it's important that I check if the code is trying to run within the same tick
Then you only need delta ticks and having a total offset is no problem.
how do you imagine this working without me querying what tick it is to the server?
public class TickTask implements Runnable {
@Getter
private static int currentTick = 0;
private static boolean started = false;
public static void start(final JavaPlugin plugin) {
Preconditions.checkState(!started);
Bukkit.getScheduler().runTaskTimer(plugin, new TickTask(), 0, 1);
started = true;
}
@Override
public void run() {
TickTask.currentTick++;
}
}
how do you make it colorful my boy
3 "`" and java infront
```java
```
idk how to do it without formatting lol
ty
Sadly mobile doesn’t support the colouring
If you are fine with using NMS then you can just use
MinecraftServer.currentTick;
I’m surprised that’s not exposed
really surprised spigot hasn't implemented this
Then again I say that a lot
Like with this
// TODO NMS
if (!((CraftBlockData) material.createBlockData()).getState().canPlace(((CraftWorld) target.getWorld()).getHandle(), new BlockPosition(target.getX(), target.getY(), target.getZ())))
return;
I wanted to avoid having to do something like this but I guess there's no way around it if I'm only using spigot
seems like a really core methdo that should have been implemented already
yeah hence why I asked here, was surprised that it didn't exist already
I mean we only got player.breakBlock recently
Or ill write a quick PR, expose it in the CraftBukkit class and hope mr boss
merges it in the next 2 Months
I actually found a feature suggestion for this where
got into it with some rando
You should do mine too because lazy
Link plz
Hey I remember that one
I get that it's an "abstract concept" but the scheduler is built on top of this concept, which makes it way less abstract than it sounds
Well...
tick really doesn't seem abstract considering we use schedulers
then again that was 5 years ago, so maybe his thoughts have changed
off I go necroposting
it says unresolved so I guess I won't open a different ticket for this
MySQL Statement Executed Event?
Is there a way to set a radius on an event
what do you mean by that
What do you mean by that
in other words multiply the event by whatever the radius is
could you give us an example?
Sure
I want a compass to point a player but if the player moves its location changes. How do I make the compass point a variable location?
An event is not a number. You cant do any arithmetic with it...
Scheduling
Tell that to python
if someone wanted to make a pickaxe break a 5 block radius every swing
would that be possible
Sure
yeah definitely
on block break you can get the location then get neighbouring blocks
no but its some pretty easy maths
Block.getRelative
oh nvm there is lol
Or in this case a loop would probably be better
- Get the broken block
- create 3 nested loops over x, y, z
- Get the relative blocks within this loop
- Break them
alr bet thank you
Can you recommend me some library that will help me write nice-looking easy-to-follow Minecraft command plugins? There are many many libraries that gives you simple functions to create CLI commands. Has anyone created such a library for Minecraft? So we don't have to carry about splitting and writing same boilerplate over and over again?
I like Commodore and Brigadier
ACF is pretty pog
open-source Minecraft when
never
😭
Event is not working 😦
?paste
I'm surprised you managed to keep that under the character limit lol
make sure you provide fewer details
I even tried to sysout the event but it doesn't give the sysout
Missing Event handler annotation
that is one
OH
are you listening to the event ?
Annotation missing
And interact event is not right click @formal prawn
You sure about that one chief ?
Check if event.getAction is right click air or right click block
I want the method to run no matter the player right clicks air or block
Use ||
if(e.getAction().equals(Action.RIGHT_CLICK_AIR) || e.getAction().equals(Action.RIGHT_CLICK_BLOCK))
Yes
i did that only
Im blind then 😂
kek
Better to put at the top
does it matter?
yep
i guess more optimized
ah ok
always exit early
It checks any interact before the if
nice ping
And dont put a lot of if and else
Better to do it with return
ono
alright now for my next magic trick, I will find a way to output my code execution log to the admins
And i have a question
The Bukkit.broadcast()
Requires a perm node
So the players with this perm will recive the message ?
There are two methods. Bukkit.broadcast(String, String) and Bukkit.broadcastMessage(String)
The latter does not require a permission.
Ill just quote the javadocs:
"Broadcasts the specified message to every user with the given permission name."
Oh thanks
The latter does require a permission however I believe its defaulted
ok i got a dumb question for anyone that cares to answer.
I made my own hologram plugin with a gui and stuff but I wanna turn it into a dependency/api for 2 other plugins that im making. Think I should move the interaction/gui stuff into each of the dependent plugins so they can do different things, and just leave the dependency holograms as a way to display the info
if that makes sense
yeah? ok sick
gradle makes me want to leave technology behind and go live as a hermit off in the mountains
whether or not it will work is based on star alignment and the feng shui of the room you're in
Didnt you read the setup for perfect zen in your room on gradles homepage?
yeah but my house has a north-northwest exposure to the dragon's veins and mars is out of alignment this month so it refused to work until I pressed the refresh button for the 15th time and restarted intellij for the 3rd time
at which point it worked without me altering any of the code that was making it not work previously
might be because I put down the 2nd cup of coffee in a different place from the 1st one which altered the feng shui of the room
brb debugging my coffee cups
lmao
I need somone who can do the plugins and skripts and setup them both I need help bad who can join my server to help plss ping me
Wrong channel #help-server
Hi, I have a problem. When I try to use the getConfig method from a class of my own configuration file, this method returns null. I can't find what could be causing it.
First: This can be replaced by
YamlConfiguration.loadConfiguration(file);
Do you make sure to call the load method before you call getConfig?
okay, done.
yes
Then you are probably using more than one instance of that class
hmm
that was the problem. fixed, thanks
Would anyone here be willing to baby me through an issue i'm having w/ the plugin i'm trying to code lmao
java.lang.NullPointerException: Cannot invoke "com.n0grief.WatchBlock.SQL.FriendsHandler.createPlayer(org.bukkit.entity.Player)" because "this.friendshandler" is null
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import com.n0grief.WatchBlock.SQL.FriendsHandler;
public class Join implements Listener {
public FriendsHandler friendshandler;
@EventHandler
public void onJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
friendshandler.createPlayer(player);
}
}
You didn't initialize friendsHandler
Make it private and final and pass it through the constructor
I hope it's alright to ask more of a general question about MC programming. It's not exactly related to spigot.
I've been creating a backend over redis for more servers. I've created a simple wrapper for a User class, that simply has fields queried from redis on access. But, I have added a cache for the value. To synchronize properly I added TTL (after for ex. 500ms, cached value is queried from redis again) and a messaging broker (RabbitMQ) to call invalidate on other servers (aka sends a message to other caches on different servers, so they query the value from redis again when edited).
My question is whether this isn't just overly complicated for no reason and I could go without caching. I know that caching the value brings me some extra access time savings (from 0.1ms, depending on connection, on redis to like +-10ns for in-mem) and reduces the load on redis, which might be used widely. I just can't decide whether it's relevant or not. Or whether I should go only with TTL and ditch invalidation.
What is this backend for?
It's intended for all user data. Will have a standalone java app to save into database, then a public Rest API for the web.
Yes but like what’s the system for?
What type of web app is it going to be?
An online shop? A forum? Etc
well, mc servers? 🤔
@idle grotto any chance you might be willing to show me an example of passing it through to the constructor, im literally a -2iq programmer when it comes to this stuff im legit learning as i go stumbling through lmao
Alright
That was, too ironic of a response, sorry. It's for minecraft servers, yh.
What sort of data are we talking about? Because in most cases redis is over the top
and what magnitude/player count are you projecting
I'm not doing it for a target production, it's mostly for fun of building it. The intention was to move as much load from the server. Hence moving db work to a standalone
Mark the field as final and your IDE will show you what to do
either way you a querying a databse, whether it is directly to redis or to the db wont make a difference
I wouldn't consider the player count that relevant, the more the better. Mostly asking for another opinion.
If it saves 0.1ms then it sounds like a very negligible optimization
i really only use redis for pubSub and there are very few cases where i use it for data persistence
@idle grotto this is what my ide spits out ```package com.n0grief.WatchBlock.EventHandler;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import com.n0grief.WatchBlock.SQL.FriendsHandler;
public class Join implements Listener {
private final FriendsHandler friendshandler = null;
@EventHandler
public void onJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
friendshandler.createPlayer(player);
}
}
minecraft doesn't really need it
Sure caching will reduce the load on redis but afaik redis is very scalable given the right resources of course
Redis is mainly for caching data fast
I implemented the caching to have immediate results when working with the values in code
RabbitMQ is a better message broker than redis
Personally there has never been a usecase where i have benefitted caching data through redis rather than directly to a db
Though wertik I believe for testing purposes locally caching the values might be a great idea
Yup, it's built for that.
and that is with netweorks with 1000+ concurrent players
But really redis is good at handling caching
I assume you are reading/writing directly to redis?
rather than keeping a local cache on mem
public Join(FriendsHandler friendsHander) {
this.friendsHandler = friendsHandler;
}
Btw, if you're using Intellij you can use Ctrl+Enter and choose initalize in constructor (not sure about Eclipse)
Doing both right now
Changes the value locally in cache, then writes to redis & calls invalidate over Rabbit.
@analog ore anyways for scalability I’d recommend actually locally caching the values from redis in a short period of time actually
I'm doing that right now. The code base is a bit messy, but I could make the implementation public if you wanted to see.
sure id like to see
yeah but Conclure is right, far more efficient to locally cache then keep querying redis
but it really depends on what type of data you are holding
Yeah when it comes to architecture ideally you wanna separate the memory model with the database handling ofc but I’m sure you’re aware of that
if its shared data that is constantly changing, 100% use redis
but for player data that will only be accessed from one thing at a time its not entirely necessary
The data would be used & be able to change on multiple servers at a time, so redis seemed better than doing SQL/Mongo operations & queries on the server.
Yeah definitely
whats the whole fieldContainer thing
btw. if you have any comments on my programming, feel free to tell me. My inheritance practices are meh
That's a cache for each field.
Although should be said redis shouldn’t be used for persistent storage
I'm not using it for persistent-persistent, all will be saved into database & loaded on request.
Alr good
may be a bit more inefficient but why not use reflection?
// Since I'm using SQL & redis, which are key-value I thought it would be better to work with fields directly instead of caching the whole user btw.
yeah fair enough
Reflection for adding fields to the User model for ex.?
Wait what
because on each load of the user, I'd have to query all the fields instead of querying only the fields I'm working with
you could have an exclusion system
Well you most likely will have the entire user in your redis cache regardless?
that seems more messy than what I have right now
that's true 🤔
I mean
hm.
maybe its just me but i think an annotation based approach would be far easier
it feels more "optimized" to work only with fields