#help-development
1 messages Ā· Page 2260 of 1
Postgres >
Yeah you only know sql right
==> <==
Well I havenāt messed w/ it for some time
How are you bussy?
Yeah Iām going to sleep now
lmao mi englis 10/10
But I might be available tomorrow
Soon ye
Ye
I will put an alarm to get up together
Youāll need that extra sleep tomorrow
3d fuck day with this
I cannot understand how doing the MongoCollection#UpdateOne
On a pojo class
Because i was casting the pojo into Bson
That is totally wrong
Sounds very erroneous
Btw
Why does that not work for you ?
I was reading the oficial docs to understand
But i will look that url
lmao i have atm opened 300 page son Opera > Chrome
txt > db
As the toaste paste said "colgate"
Txt is the wors thing you can do
not true^^
For some reason, player.getVelocity() is showing 0 for both X and Z even when I'm moving around, it only changes when I'm jump running, how do I get the actual velocity for X and Z?
Lmao i would use SQL rather txt
Makes sense
hEH?
Inded
what?
Is one the spigot api things i dont mostly like
If you want to get the distance the player move you can use that
I dont know what are you doing that why
well I want to get the velocity X and Z because I want to know if player is moving left, right, forward or backwards
is there another way to check that other than checking player velocity?
Oh Ilussion im not using Sring
tho i aprecciate your trying to help
I know what you want to do
I try that some months ago but for knowing which key was pressed either W, A, S, D
But i couldnt do it
u cant check the keys the pressed lol
It makes sense if ur walking
When ur jumping u got a velocity
But when walking, it's just like small teleportations ig
breh
What are u tryna do?
Not checking but you can trick it and calculate.
In which event?
That why
getVelocity itself should literally tell u the velocity
whats the point in the method then
To tell u ur velocity
I think I can use getFrom and getTo from playermoveevent
If u stop walking, ur character stops
no shit
If u had a velocity, character would keep moving
bru u dont get it
Pretty sure u don't
I'm literally moving the character and velocity stays 0
Walking around is small tps
What would be a good way to remove enchantments from enchantsToAdd list in EnchantItemEvent? I can't just remove the enchantment from the hashmap since that gives me concurrentmodificationexception
burh
How does that not make sense?
Why don't u listen to playermoveevent?
Have you tried using a ConcurrentHashMap<>()
Instead of HashMap
Because when you are looping over a collection you cannot do some operations and then you get a ConcurrentException
Send your code please on
?paste
so the first one?
Wait
Yeah
USe what fit you better
Oh lmao mongo docs are amazing
It doesnt explain how to updateOne the full Pojo document
Haha
Its so shity their docs
Anyone know why every time I apply even a minor amount of velocity I am insta kicked
that is the only error
I try doing that without new UpdateOPtions but told me the same that i need to cast it
its not a high amount of velocity either
@eternal night sorry for ping but look this
So should be fine
what im doing..
Maybe is an issue related to the driver
I will check all
pulse sorry for ping but have you seen the code i sent?
@ivory sleet
I dont know why in the example it doesnt cast it. But in my case it oblise me to cast it
He i asslep
ooh
im trying to figure out why i should use a di
I think one the mot important hthing is for code debugging
cause like im not sure how i add a di
im not entirely sure what it is
?di
Guide to dependency injection: https://www.spigotmc.org/wiki/using-dependency-injection/
You can start from there
Hi, i'm developing a chat moderator module for a plugin and i need to save regex strings to a config.yml file, but i keep getting compilation errors by gradle
i have enabled UTF-8 encoding
Maybe ?services
Send error in a paste
?paste
That's fine
Olivo what could be the probllem if a code im use as base from a example doesnt require cast but mines require it
Could you send your build.gradle
ur talking with me?
Me=
Yeah
Depends on the code
Its exactly the same
Verano, my only suggestion is to just keep researching. Sometimes you wonāt get a super good answer here yet so just research your issue.
Send it
A lot of my own issues have been solved by linking all sorts of solutions together
You have to go on your own
Allright 1 sec my pc is slow because 300 pages on explorer
Hm not sure
on what
On what the issue is
@paper viper hey, so i still don't understand di's the spigot page wasnt that helpful. um i need help ;-;
thank you so much
From what I've seen you've already used it correctly
Yeah you just need to remove the static singleton
That was what I was referring to btw
The JavaPlugin
if i remove that then how can i transfer the javaplugin?
Your plugin main class extends JavaPlugin
You can just use that
And also DI is how you would do it
and i dont understand di's ;-;
where?
Delete the static one
if you find the issue, send me DM. Thx for the help if you do
wdym
You donāt need that
And use https://github.com/JadeStudioss/Cloud/blob/Main/src/main/java/org/eternitystudios/plugins/cloud/utils/AddonManager.java#L19 instead
Uh well wrong line but that variable
but if i delete it, theres going to be errors
So fix the errors by replacing them with your plugin instance you passed into the constructor
Use the instance variable instead of Cloud.plugin
But why
i cant access stuff
@chrome beacon
My code its exactly the same as the one from mongo db github
In my case it oblise me to cast it whern in the example doesnt happen
public static void main(String[] args) {
// Mongo connection
MongoClient client = new MongoClient(new MongoClientURI(""));
CodecProvider provider = PojoCodecProvider.builder().automatic(true).register(Vector.class).build();
CodecRegistry codec = CodecRegistries.fromRegistries(MongoClient.getDefaultCodecRegistry(), CodecRegistries.fromProviders(provider));
// Mongo database
MongoDatabase database = client.getDatabase("test").withCodecRegistry(codec);
MongoCollection<User> collection = database.getCollection("testing", User.class);
// Mongo operations
User user = new User("Alex", "alexito@gmail.com");
user.setRole(User.Role.ADMIN);
collection.insertOne(user);
collection.updateOne(Filters.eq("name", user.getName()), (Bson) user); // Exception here
}
Notice how I use the plugin instance in āthis.pluginā
Instead of doing something like DeluxeMediaPluginBootstrap.getInstance()
Is User your class
Also could you send the mongodb wiki youre following
@paper viperim so confused
If you are confused, I recommend to at least learn about constructors and stuff
And some basic OOP
i know about constructers tho
No he is trying to implement it
idk what youre trying to tell me tho
Ugh this is hard to explain on phone
private DeluxeMediaPlugin plugin;
Object oriented programming
is this the thing?
We're telling you to use the variable you created
Aka what everyone hates
Well the one that you removed
OOP is the best
OOH!
Overcomplicating
sksksksk and i oop
but wait that one didn't work, i couldn't use anything on the addon. like get config or register command
There olivo
My photography Instagram: https://instagram.com/heitman.photography
every java programmer
Thi olivo
@chrome beacon but wait that one didn't work, i couldn't use anything on the addon. like get config or register command
You can giva PLuginMAanger
???
ExamplePlugin example = getServer().getPluginMnager().getPlugin("ExamplePlugin");
Maybe example is outdated not sure
that is how you access from a core to the addon plugin
My mongo driver version right?
I will check it
Please no
Donāt do this
ik
No we're trying to get them to use di
thats horrible
How would you get another plugin instance from one plugin? i listen...
Show us what you tried
?di
Guide to dependency injection: https://www.spigotmc.org/wiki/using-dependency-injection/
Thatās not what he is trying to do right now.
Also it's an addon
Oh ok
He is just doing it within the same plugin
they*
I thought he was trying to know how to access his addon plugin throw the Core one let say
they please
@chrome beacon so maybe the version is outdapted right, because the example repo was updated 7days ago
my pronouns are they/them
š¤
Veranos English is a bit limited it seems
i don't know how to explain this
Anyways yeah make sure everything is up to date
Dont tell me that lmao i have taken cambridge advanced international exam
I dont really know a s h**
Nah itās more like
I dont know how i pas it with 80%
Then how do you not know what pronouns are?
š
yikes
im not a boy or a girl
how about that
so since im not, you do not say he
or she. you say they/them
Oh sorry
its fine
LOL
Lol
im not a girl either (:
??
okay....
welcome to the complex world of not liking an oppisite gender lol
too much help for today
LOL
Oh you where meaning that
I dont understand you tho
Jade take the internet with a grain of salt
im going to die laughing
@paper viperback to the topic of this channel
he is on vacations
heh
Im interested on buying someone a custom tab api
dm me
.
is there a specific directory i should be writing plugin data to
Write to your plugin directory
You should use the plugin directory
yeah ur config folder
so ./plugins?
You can get it via: getDataFolder()
ah nice thanks
Your welcome
Also its recommend to learn tbe basics before start creating plugins
If not its really diff them
I say it cuz of personal experience
declaration: package: org.bukkit.plugin, interface: Plugin
i didnt bother looking in the docs since asking here is faster
and it might be better to write somewhere else than what i found in the docs
That's fine
@chrome beaconheres what i did public Cloud cloud; in main class right, then set it to this onEnable, use Cloud as a paremter in the addonmanager construcer then send over that instance to the addon
Sounds good
@chrome beaconbut then i cant access anything from the addon, like for example the config
Could you show how you try to access the config
@chrome beacon```java
package org.cloud.addon;
import org.eternitystudios.plugins.cloud.Cloud;
public class Addon {
Cloud instance;
public Addon(Cloud instance) {
this.instance = instance;
}
public void addonMain() {
instance.getConfig();
}
}
but getConfig doesnt work
The method isn't returning anything?
no, it doesnt exist
Ah I see the issue
?
Is that addon in another project
yes
is there a way to play the sound not through the players, but on the server itself? I'm just adapting the plugin for 1.7 and there is a problem that 1.8 and higher and 1.7 have different return values of players on the network
Are you using maven?
no
Gradle?
what error are you getting exactly
no, but i added the shaded jar as a libary to the project
declaration: package: org.bukkit, interface: World
So you're compiling directly with your IDE?
are you calling addonMain and its not giving you anything or something
dude
addonmain is working
the method doesnt exist
see
.
yeah into an artifact
Thanks
Alright compile the Cloud project and make sure you depend on an up to date jar
If that doesn't work try File > Invalidate Caches and restart
@chrome beaconits not that
the method just isnt there
and its up to date
is it because the instance is type Cloud?
Actually wait did you add Spigot to the project
Does it extend something that has getConfig?
JavaPlugin
WAIT
Let me handle this
should i change the type from Cloud to JavaPlugin in the addon constructer?
no
^
Is Spigot in your addon project?
Make sure that it is
And if you're on 1.18+
?bootstrap
Bootstrap Jar
The main spigot-1.18.jar is now a bootstrap jar which contains all libraries. You cannot directly depend on this jar. You should depend on Spigot/Spigot-API/target/spigot-api-1.18-R0.1-SNAPSHOT-shaded.jar, or the entire contents of the bundler directory from your server, or use a dependency manager such as Maven or Gradle to handle this automatically.
Please read the release notes for further information: https://www.spigotmc.org/threads/9-years-of-spigotmc-spigot-bungeecord-1-18-1-18-1-release.534760/#post-4305163
It's the same for 1.19
You will have to build it with buildtools then
that takes forever
So you got Spigot from an unofficial source?
can i just make another addon project with maven?
no
i used maven for the cloud project
well that's your solution
okay
Anyways your issue is that Spigot is not in your project so it can't find getConfig
oh
Olivo so the messge i sent using PluginManager was okay lmao
You and the other man where shiting me
It works yes
And what i sent was correct....
WHy
There is no other way of getting a plugin instance from another plugin if you are using DI
š
Didnt he told they diff projects
So they are diff plugins
š
Ohh ok
stupid
It's an addon system using reflection to pass the plugin instance to the constructor
/jk
Oh nice vocabulary
Reported
Hahaha
Also we are trying to help and you are shiting people from a non reason
So in fact you dont need help
Do it alone if you know everything...
Verano I think you should take a break and do something else for a bit
maybe im really stressed with mongo thing because im folloing the tutorial either more i copy-paste the example
And only rename the clas and modify something thingand doesnt ork :/
Take a break and come back to it later
š”
I would like but i cannot
My friends are dm all time
When you finis ht eplugin and everytime
Nomatter if i tell them to be pacient
Soryr man
I know that you dont want to be listening me
But idk
it was something i need to say it
and take out from me
Oh mnice food is in the door i eat calm don and come bac
Thanks for all and see you later
I'll get some sleep now since it's almost 1am
See ya
@buoyant viperhehe
https://github.com/JadeStudioss/Cloud so i made this plugin, and for the addons. I'm curious how i can make it so you can add commands via the addons? Any idea how i can do this?
Well you'll have to inject the commands into the command map
exactly how?
I'd just use a command framework already out there it saves you thr pain
you just take your commands and just SHOVE them in /j
E.g. I use lamp and I think acf Is a big onr
but its an addon, i have to register the actual command on the main plugin. but have the code on the addon
Then let the addons call a registerCkmmand method found in the plugin that registers the command into the commandmap
Exactly what frameworks do but the post above works if you wanna hack it together yourself
what frameworks?
Lamp, acf etc I'm pretty sure some others in here have there own too
I never use bukkits command api
Just have a register command in your core
a register command? or a register method?
If you want to learn the framework look at examples and ask questions in the discord he's very helpful
Register method
Register a command
but the codes on the addon? how would i do that
I'm not on my computer nor do I have access on it so I can only point you in directions no code
ik
You'd call core.register(Object clsss)
whats the object?
Some command node
Do you not know what an object is?
oh god
Java - Object and Classes, Java is an Object-Oriented Language. As a language that has the Object-Oriented feature, Java supports the following fundamental concepts ā
not completely
?learnjava
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.
oh its an instance lol
thats what i meant
so the object should be the instance of the command method?
wait im confusing myself
When u register the object, it looks for all methods with @Command or SubCommand
And registers those methods as commands
The args or the method are tje args of the command
Args of the method*
?
?
wdym
You don't have to extend a class to make a command class
You just annotate the method
And then register an instance of the class
can i have an example?
Lamp has official examples on there github
that adapt to this situation?
class CommandClass {
@Command("fly")
public void toggleFly(Player player) {
player.setFlying(!player.isFlying)
}
}
That's typed on phone
But like thay basically
When u do /fly it toggles fly for the executor
U register an instance of commandclass
as an object?
U can have multiple methods with different commands
Well yeah, all instances are objects
You can also annotate the top of the class with the command annotstion and use the default annotations for default with no args
Look at his examples on github
oh yeah
Hello, if i add config files tomy plugin events (player join)
dont work. Idk why. Does anyone know what to do with it?
https://pastebin.com/BZSfH37u - Main file
https://pastebin.com/fu95xpKz - Events file
@river oracleim gonna take a break, im so tired
you never registered your join event
oh my god the file formatting is horrible in those two files
Uch thx,
I had to delete it by mistake
its work thx so much
I have one more small problem. After overwriting the config and saving and restarting the server, the config is overwritten back and nothing is saved https://pastebin.com/sURPVEid
You are constantly overwriting sections in your #onEnable() method.
Essentially giving off the impression that nothing is saving.
and how to fix?
Don't overwrite the sections in the onEnable method. Just make changes when you need to.
@river oraclewhat should the method in the main plugin look like?
@humble tulip?
nvm
Is there a way to send a webhook request when a certain resource is updated?
is there a better way to get the net.minecraft chunk then using Chunk Chunk chunk = ((CraftChunk)event.getChunk()).getHandle();
NMS is not my strong point
Any tab api with heads that you can recommend?
Tab api?
more like horror of NMS but it is my only option. would you be able to point me to a tutorial or something to work around the crap with avoiding import org.bukkit.craftbukkit.v1_19_R1.CraftChunk; to try and make it compatible with as many versions as possible?
Tablist that allow adding in lines heads
Basically an api for tablist that allow to add player heads into the lines
You need to use abstraction with nms
Are you dealing with stuff the API canāt do?
Try to always use the API, as it will be the best compatability
Agree
Another dought do you recommend scoreboard api which uses NMS?
Structures, structurepieces, and boundingbox. can't find that anywhere in the api
Yeah seems like you need to use NMS
Hereās some tips
Make an interface with methods that you will call for NMS. Then make separate modules for each NMS version that has classes that implement the interface
And provide implementation
+1 to pulse recommendations
PlayerProfile profile = p.getPlayerProfile();
profile.setTextures(target.getPlayerProfile().getTextures());
profile.update();
p.setPlayerProfile(profile);```
Any idea why this is not updating the player's skin?
It is much appreciated and I understand this point. I have it coded for 1.19 but I am lacking this portion of knowledge for the implementation.
Wdym
is camelCase or dash-space convention in config.yml
i can coded it all individually, per version, but am lacking the java-foo to get the server version that will load the right nms class part.
String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];```
This is one way to do it. People criticize it because it may become unreliable in the future, but it works well for now.
It'll return values like
v1_17_R1
v1_18_R1
v1_18_R2
v1_19_R1
Can I store multiple things in an item's metadata? call it like "info" with a list of items inside it
Wdym by metadata?
like..
You can store all sorts of data with the PDC.
Yeah just do PDC
There is metadata you can use, but it won't be persistent.
so i need to find the right why to get .nms.impl.%s to load the proper class based off the version?
such as
List<MetadataValue> hiveMetaData = beehive.getMetadata("newHive");
Yeah, i get the version of Minecraft and put it as one of my package names. The %s is replaced with the proper Minecraft version
I then shade the separate NMS modules and stuff
For example, com.example.something.[version].NMSImplementation
And then example package class for implementation would be
com.example.something.v1_19_R1.NMSImplementation
Iām typing on phone so hopefully I didnāt mess up
sudo code works just fine for me. you got me down the right track.
fyi... i hate the chunk.{random letter}() changing with each version....
NMSImplementation looks like NM Simplementation to me 
NMS = No Minecraft Simplicity
Lol
Anyone know an easy way to stream an item's lore and get the value if part of the string equals something?
Hey, I'm having some stupid issue with scoreboards.
Basically, I copied a scoreboard example from a gist online, did some modification to allow it to write a StringList and all lines are coming out blank
You should not check for custom items using their name or lore.
Always go for the pdc of an ItemStack
?pdc
http
Yeah i know but the params
There is probably a different file transfer protocol as well
Im replicating a simple maven server
Why?
But our goal is to our own dashboard
You can write a dashboard over an artifactory
Prepare for at least 1.5 years of dedicated development then
No need to reinvent the entire wheel.when you only wanna change tires
You can disable that
Hmn but other can access so
š¤
I need to access only throw my dashoard auth
But dont allow others to use the maven dashboard
You mean a dashboard that magically for you doesn't habe auth ?
What even is a "maven dashboard"?
The maven dashboard is the one that have Nexu for example
Yeah i want to have 1 dashboard
Which contains maven things
I want to my dashboard be public but it must ask for authentification
And my dashboard should contains the maven one
Well thats just the default behavior of nexus. You usually have an admin account.
I kno but i want to connect neus dashboard to my dashboard
Im think im not explaning
You already have a dashboard but want to incorporate nexus into it ?
Yes!!
And i cannot use nexus one, because it ask for authentfication
And i just want to use 1 auth system
So once you login into the dahboard you can either use my dashboard or nexus one
Well you will always have to auth with nexus or another maven repo server. Your dashboard should be the one responsible for that.
Because writing your own maven server for this is synonymous with ending your project here unless you have a large developer team that can only work on that
Hello. When I run public static MultiverseCore core = (MultiverseCore) Bukkit.getServer().getPluginManager().getPlugin("Multiverse-Core");, I get an error in the console saying :
Caused by: java.lang.ClassCastException: class com.onarandombox.MultiverseCore.MultiverseCore cannot be cast to class com.onarandombox.MultiverseCore.MultiverseCore (com.onarandombox.MultiverseCore.MultiverseCore is in unnamed module of loader org.bukkit.plugin.java.PluginClassLoader @76eb238a; com.onarandombox.MultiverseCore.MultiverseCore is in unnamed module of loader org.bukkit.plugin.java.PluginClassLoader @7050f8cc)
Does anyone know what would be causing this?
Don't shade the multiverse API into your jar
I didn't think I was... I'll check again
That is usually the cause of these
Nice XD
I'm trying to do some stupid thing with nms, and it requires me to somehow call a superclass's method indirectly
for example if AbstractHorse extends Animal, Horse extends AbstractHorse, and SuperiorHorseEntity extends Horse
I want to be able to call Animal#aiStep() from SuperiorHorseEntity#aiStep()
and skip over Horse and AbstractHorse
is this possible?
How can i make an npc teleport randomly to any player (in a radius defined by me, that radius would be the map) and when he (the npc) is with the player there is a possibility that the npc will teleport to the front, back or to the sides of player and walk together with the person and after some time the np will teleport to another person and do the same? Help please
Maybe ?services
Basically you want something like doesnt hipixel wathdog
Those are a lot of questions. What is the first you want answered?
how would i find the first available number within a range
for example, i have numbers 1, 3, 4, 5, 6
i want to get the first available number which is 2
and not 7
and if i had a range like 250 - 400
and had numbers 250, 252, 253, 254 ... 399 i would get 251
nevermind
Nothing you can do other than counting up and checking if the number is available.
There is probably a smart way because the numbers are ordered but im too lazy to think about that rn
I am trying to write a command that allows a user to grab the config file and load that memory into the server. Meaning if a server admin edits the config in the file manager, they can run a command /configreload and it will update the plugin with its new memory from the config. Everywhere I read it says just use reload config, but no matter which option I try, I just can't get it to work. Any help would be appreciated!
public class ConfigReload implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
Player p = (Player) sender
Main.plugin.reloadConfig();
p.sendMessage(Main.plugin.getConfig().getString("Messages.Config"));
return true;
}
}```
How can i make an npc teleport randomly to any player? (in a radius defined by me, that radius would be the map i have)
This looks fine to me. Did you make sure to save the file before using the command?
yup. I know this because when I use plugin manager and reload the pluging that way, the data in the server updates. But when I run the configreload command, nothing happens.. it's kinda annoying lmfao. I thought it looked fine too.
A map is not a radius. Its a volume.
Do you have a collection of all players in this map?
if you want, I can add the entire plugin to a repo on git and you can take a loot at it, but really I thought that is all I needed.
Nothing happens in the sense that you get the old config entry sent?
I don't have a collection
Then how do you define which player is in a "map"?
I was going to make the collection
Then manage your game structure before you implement any new features.
For instance
First:
Original Blacklisted Words
- test
- anothertest
Second:
Plugin works fine and bans those words
Third:
I edit the config in the file manager to added
- test
- anothertest
- anotherexample
Fourth:
I run the /configreload command
Fifth:
I receive the message it reloaded.
Sixth:
That data in the server still only has the two original words, not the added ones.
But if I reload the server or reload the plugin, the data is added to the server memory
This looks like you are not copying the data out of the new config file after reloading
Sorry if that didn't make sense š
This is the chat filter code
public class ChatFilter implements Listener {
private static List<String> banned = Main.config.getStringList("Blacklisted");
@EventHandler
public void onMessageFilter(AsyncPlayerChatEvent e) {
Player p = e.getPlayer();
String msg = ChatColor.stripColor(e.getMessage());
// if(p.hasPermission("moderationplus.chat.bypass"))
// return;
for(String bWord : banned) {
if(msg.contains(bWord)) {
p.sendMessage(Main.plugin.getConfig().getString("Messages.FilterTrigger"));
e.setCancelled(true);
}
}
}
}
wait
...
Yes
is it because the list is static.,
I honestly dont even know why I made that static in the first place.
It doesnt matter if its static or not.
Its in memory and it wont change unless you edit it.
Doesnt matter if somewhere you edit your config. You need to load the
data from your config into your list again.
hmm.. and how would I go about doing that?
First of all: This list does not belong here.
Your listener should only have on concern: Listening to events
Holding data should be done in a manager class which should be a singleton as well. Let me write you an example.
okay thank you so much homie
Wisconsin š§
bump
xd
do the dang reflection
dude i really dont feel like writing 500 lines for private methods and fields
First of all your manager:
public class FilteredWordManager {
private final Set<String> bannedWords = new HashSet<>();
public boolean isBanned(String word) {
return this.bannedWords.contains(word);
}
public void reloadFromConfig() {
this.bannedWords.clear();
List<String> words = Main.config.getStringList("Blacklisted");
bannedWords.addAll(words);
}
}
Then the usage:
public final class SpigotSandbox extends JavaPlugin {
private final FilteredWordManager filteredWordManager = new FilteredWordManager();
@Override
public void onEnable() {
YourReloadCommand command = new YourReloadCommand(filteredWordManager);
YourListener listener = new YourListener(filteredWordManager);
// Register command an listener
}
}
This is a very important design principle.
Your manager classes have only one single instance. And this instance is used everywhere.
This means you need to pass this instance through the constructor of your other classes.
In this case we pass the same filteredWordManager to our listener and to our command.
This means if the command class changes the manager then the listener "sees" the same changes
because it uses the same instance.
So your listener uses filteredWordManager.isBanned() and your command uses filteredWordManager.reloadFromConfig()
How can a fix NullPointerException
But both access the same Set
Thank you so much! I will try it out and update you!
Make sure you dont do anything with null objects... dont call fields or methods because the object does not exist.
Java 101
So then I would need to make an instance of the FilteredWordManager class in my ConfigReload class and then run the .reloadFromConfig
Uh. New color indicators for chat in 1.19.1. Noice.
Nope. You only create an instance of a manager once and then never again.
This is usually done in your main class.
If you create two instances then each will have their own Set<String>
And updating the one in your command would be useless because your listener has a completely different instance.
is that what the private final FilteredWordManager filteredWordManager = new FilteredWordManager(); is used for in the main class?
sorry im trynna catch up on everything and make sure im getting this all
Yes. This is your "singleton". new creates an instance. And this exact instance needs to be used everywhere.
To achieve that you simply pass it through the constructor of your other classes.
would making a getter function in the main be a liable way to continue with it?
Like create a function that accepts a string and the returns a boolean
and then call that function in all the classes?
No this has no place in your JavaPlugin class. Your JavaPlugin class should only hold your managers.
What you could do is create a getter for your FilteredWordManager in there. Not as clean as the constructor injection but also viable.
Very dumb question... how can I make my config.yml have spaces? Like this: yml mines-message: "&d&lRaidTheMine Mines &e/mines reset <mine>&f: Resets the specified mine &e/mines tp&f: Teleports you to the mines "
In theory, I want each line to be their new line in game.
\n?
Either make a list or insert a newline character \n
a list?
\n worked, thanks!
But dont use * on the list. It might oneshot players.
okay im trying to add the constructor injection into my config reload command class but I guess im a little confused as to how I still use it to run the isBanned method.
im sorry if im overloading you with questions xd
Wouldn't I want the new instance in Main of the filteredmanager to be public so I can access it everywhere?
as in that instance
Something like this
public class YourListener implements Listener {
private final FilteredWordManager wordManager;
public YourListener(FilteredWordManager wordManager) {
this.wordManager = wordManager;
}
@EventHandler
public void onChat(AsyncPlayerChatEvent event) {
if(this.wordManager.isBanned(event.getMessage())) {
event.setCancelled(true);
}
}
}
if so, why are there class names that start with "Spigot" in it
or methods like "getBukkitEntity"
yes. nms = net.minecraft.server
@lost matrix?
Because Spigot applies patches and changes this code.
Thaths how scheduling, events, configs and eveything else is injected.
oh, so its more like mojang code but changed a little by spigot?
hmm still not updating when I run the reoload command
reload*
Show both classes
public class ChatFilter implements Listener {
private final FilteredWordManager wordManager;
public ChatFilter(FilteredWordManager wordManager) {
this.wordManager = wordManager;
}
@EventHandler
public void onMessageFilter(AsyncPlayerChatEvent e) {
Player p = e.getPlayer();
String msg = ChatColor.stripColor(e.getMessage());
if(this.wordManager.isBanned(msg)) {
p.sendMessage(Main.plugin.getConfig().getString("Messages.FilterTrigger"));
e.setCancelled(true);
}
}
}```
```java
public class ConfigReload implements CommandExecutor {
private final FilteredWordManager wordManager;
public ConfigReload(FilteredWordManager wordManager) {
this.wordManager = wordManager;
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
Player p = (Player) sender;
this.wordManager.reloadFromConfig();
p.sendMessage(Main.plugin.getConfig().getString("Messages.Config"));
return true;
}```
also im not trying to copy your code.. just wanting to learn how this works, and then I can tweak and change later on
You need to first reload the config file and then call "reloadFromConfig"
Currently you are loading from the same config again
wouldn't running the config reload command update the instance so that the chat filter will work with the new instance?
ohhh
reloadFromConfig gets the FileConfiguration from your main class and loads its content into the manager.
If you dont reload the FileConfiguration then you can call reloadFromConfig as much as you want but it will
always just get whatever is in this FileConfiguration.
So if you want to change the managers content you need to first let spigot update the FileConfiguration from disk
and afterwards you can call reloadFromConfig.
wait I think I get what your are saying
so I really just put Main.plugin.reloadConfig(); right before the reloadFromConfig file
yes
ahh
okay
you have taught me more than I thought I was going to learn
File Configuration has been troubling for me.
It also took me some time to really understand the differences of File FileConfiguration YamlConfiguration and when which
data is on disk and when it is in memory.
yeah supper confusing
annnnd it broke completely
the chat filter doesn't even work anymore lmfao
Hello, I have this as a tab completer: ```java
private static final String[] COMMANDS = {"reset", "tp"};
private Main main;
public Mines(Main main) {
this.main = main;
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
final List<String> completions = new ArrayList<>();
StringUtil.copyPartialMatches(args[0], Arrays.asList(COMMANDS), completions);
Collections.sort(completions);
return completions;
}``` How can I make a second one? Right now when I use `/mines` it shows `reset` or `tp`, but when I choose `reset` I want a few more tab completers to appear.
Do I just do this StringUtil.copyPartialMatches(args[1], Arrays.asList(COMMANDS2), completions);
If your set contains
- "pig"
- "wombat"
And someone types in
"You fking wombat"
Then you filter will not recognise it because you only check if the message is exactly one of ["pig", "wombat"]
So look at your isBanned(String) implementation
Add debug messages to check the state of your code.
You need to check if args[1] is either "reset" or "tp" and then send a different list of Strings accordingly
would I say that it has to equals true when checking
if(this.wordManager.isBanned(msg) == true) {
p.sendMessage(Main.plugin.getConfig().getString("Messages.FilterTrigger"));
e.setCancelled(true);
}
No this does exactly nothing
okay
A boolean expression is evaluated to either true or false
So
this.wordManager.isBanned(msg)
-> true
And
this.wordManager.isBanned(msg) == true
-> true == true
-> true
Its just one more step that does add no logic
Did you forget to register the listener?
nope
wait this might sound dumb
but when you debug your plugin, do you just have it shoot different debug messages out to you in game like a p.sendMessage("Debug 1")
You can use the logger or System.out
I would advise against messages to a player
okay let me try with logger real quick
Example:
public void reloadFromConfig() {
this.bannedWords.clear();
List<String> words = Main.config.getStringList("Blacklisted");
System.out.println("Loaded the following banned words:");
words.forEach(System.out::println);
bannedWords.addAll(words);
}
This will show the loaded messages in console
Where would I be putting a check?
public class ChatFilter implements Listener {
private final FilteredWordManager wordManager;
public ChatFilter(FilteredWordManager wordManager) {
this.wordManager = wordManager;
}
@EventHandler
public void onMessageFilter(AsyncPlayerChatEvent e) {
Player p = e.getPlayer();
String msg = ChatColor.stripColor(e.getMessage());
System.out.println("Debug 1 ");
if(this.wordManager.isBanned(msg)) {
System.out.println("Debug 2 ");
p.sendMessage(Main.plugin.getConfig().getString("Messages.FilterTrigger"));
System.out.println("Debug 3 ");
e.setCancelled(true);
System.out.println("Debug 4 ");
}
}
}
And only getting the Debug 1 message in console
in your method, lol
if(args[0].equalsIgnoreCase("reset")) {
StringUtil.copyPartialMatches(args[1], Arrays.asList(COMMANDS2), completions);
}``` Like this?
Then add messages to isBanned()
ok
Kind of. But this will throw exceptions left and right
What's a better way of doing this?
public boolean isBanned(String word) {
System.out.println("Debug 5 ");
return this.bannedWords.contains(word);
}```
with this I am getting the debug 5 message
Can someone help me and tell me the process i should go about cleaning up this code. I expect ill have to redo the complete insides, but im really struggling on figuring out where i should start. https://github.com/Silent-Program/BetterSpawners Its really old code that works but its all duct taped together. And i want to make it much more concise. Having a proper api would be nice, i just have no idea how to implement that (i have an api folder but its misleading)
Yes of course. I was talking more about something like this:
public boolean isBanned(String word) {
System.out.println("Checking: " + word);
System.out.println("Filtered words: " + Arrays.toString(bannedWords.toArray()));
System.out.println("Is filtered: " + bannedWords.contains(word));
return this.bannedWords.contains(word);
}
my apologizes
[05:18:21 INFO]: [ModerationPlus] [STDOUT] Checking: stupid
[05:18:21 INFO]: [ModerationPlus] [STDOUT] Filtered words: []
[05:18:21 INFO]: [ModerationPlus] [STDOUT] Is filtered: false
my yml
Blacklisted: # Add any words you wish to blacklist from your server. Make sure to add a TWO space indent and "-" before each word.
- stupid
- dumb
so its in there
This means your filtered list is empty
Add a debug when reloading:
public void reloadFromConfig() {
this.bannedWords.clear();
List<String> words = Main.config.getStringList("Blacklisted");
System.out.println("Loading the following words:");
words.forEach(System.out::println);
bannedWords.addAll(words);
}
Do you even call reloadFromConfig when the server starts?
yes
Show me how
public void onEnable() {
plugin = this;
config = getConfig();
// Plugin startup logic
System.out.println("[ModerationPlus] has been enabled!");
//register events
pluginManager = getServer().getPluginManager();
pluginManager.registerEvents(this, this);
pluginManager.registerEvents(new ChatFilter(filteredWordManager), this);
pluginManager.registerEvents(new SignFilter(), this);
//register commands
// getCommand("blacklist").setExecutor(new SetBannedWords());
getCommand("configreload").setExecutor(new ConfigReload(filteredWordManager));
plugin.getConfig().options().copyDefaults();
plugin.saveDefaultConfig();
plugin.saveConfig();
filteredWordManager.reloadFromConfig(); ```
Ok looks fine
Then lets see the debug result from the reloadFromConfig method
You could start with your naming conventions....
And not make a mutable field (gui) public
[05:22:35 INFO]: [ModerationPlus] [STDOUT] Loading the following words:
[05:22:35 INFO]: [STDOUT] [java.util.ArrayList] stupid
[05:22:35 INFO]: [STDOUT] [java.util.ArrayList] dumb
interesting
wait
it works now
what
lmfao
I must have had a typo in my reload config metho, and whenI just re-wrote it to add the debug, it fixed it? š¤·šæāāļø
lol
No comment.
Now lets make the isBanned method a bit more sophisticated
public boolean isBanned(String sentence) {
for(String bannedWord : this.bannedWords) {
if(sentence.contains(bannedWord)) {
return true;
}
}
return false;
}
This will filter out entire sentences.
You can see here how very important the naming of your variables/methods is.
Instead of having to deal with "p" "l" "i" or other nonsense, you can read this like a book
if(sentence.contains(bannedWord))
You dont even need to know how to program in order to understand this code
works perfectly, thank you!
are constants not supposed to be capitalized?
could you elaborate?
Those are not constants. Constants are known at compile time and are static.
a
question
what would the downside to making those namespaced keys static
(Im one of those guys that doesnt understand static very well)
You wont be able to use "this" then
i think i understand but im not sure
The gui shouldnt even be there in the first place.
But as it is: It should be private and have a getter.
Exposing mutable fields breaks their encapsulation.
And it shouldnt be there because that violates the separation of concerns principle.
This JavaPlugin class is just a mess of scrambled objects. There is no real defined purpose for your class.
Matter of fact the namespaces should also not be in there
Yea ik, thats why i said i need to redo the whole thing lmao
own class?
Yes
Alr
DataManager is well placed here.
Just missing a GuiManager so the gui doesnt randomly float in there.
Manage guis...
let me check what that class actually does
Are you using freaking tabs for spacing??
ctrl+shift+f
Yes those are tabs. Its just an opinion but i would def change this to 4 spaces.
Everything is package private in here. No reason for that.
So are 4 spaces
Just press tab and get 4 spaces
*If you IDE isnt total garbage
it is
Eclipse?
package private?
intellij, but ive fucked around with the settings once and messed everything up
If you dont add an access modifier to a field then it is package-private
only other classes in the same package can access them
effectively no. But it should be private for consistency sake.
Ok ye
should i also make them all final?
intellij suggested it and it looks correct
Also this is a tiny plugin. Ive looked throgh all classes and you can probably just rewrite it from scratch in 2-3 hours.
Yes
Ik, im just dreading it
Should i redo from scratch?
You should never use configs on runtime like that
for (String i : plugin.getConfig().getConfigurationSection("gui.groups.custom-groups").getKeys(false)) {
if (plr.hasPermission("betterspawners.group." + i)) {
group = "gui.groups.custom-groups." + i;
break;
}
}
or scoop out the bad stuff?
is that on runtime?
This explains how to work with data and define scopes for it:
https://www.spigotmc.org/threads/working-with-data.562421/
You should load this kind of data a single time into properly named variables when the server loads.
After that you dont use the config at all but rather your properly named variables.
Well

This data yes, but using the config is not terrible. Its just a Map backed data set.
Performantly its not bad. Design wise its terrible
But you are accessing it with an arbitrary String as key. This is quit error prone instead of calling a variable (which is compile time safe).
If you decide to change the path then you need to go through your whole code and change all the strings
true
Yes, all access should use enum constants
ok
@lost matrix Im gonna redo it
But im gonna need some help with naming conventions
And what to name and where to put my classes
This is a decent convention guide
https://google.github.io/styleguide/javaguide.html
Horrible
holy shit thank you
wtf is that lmao
Are you crazy
Yes
that's some weird formatting
This is compliant with the google code style.
Where are you contracts
Im gonna go work out now... maybe later
Rq
one thing
I changed the gui class to GuiManager
Cause thats what it is
What package should i put that in?
š¤·
k
In a properly named one
ok
imma stop asking questions
and just start
if (!itemStack.hasItemMeta() || (!itemStack.hasItemMeta())) return;
i just found this in my code lfmao
if (itemStack.getItemMeta() == null)
intellij hates hasItemMeta
i also hate asserting
Better safe than sorry š
Gotta double check
grtItemMeta clones the Item meta
If it is not null
Yes, but it is likely to Not be null