#development
1 messages · Page 77 of 1
you can just use squared distance
yeah, but its for displaying it to the players
you'll be fine
imo
it's just math, as long as you arent trying to do it hundreds of thousands of times a second youre probably safe
should still be fine honestly
hmm, i suppose will have to find out manually
Been told off from using Redis for crucial permanent network-wide data from the velocity devs
Better off accessing the database directly
Supposing each player does 20cps, you'll have 800 roots per second, which is nothing. It doesn't make sense to worry about performance here while a regular PC can crunch 100s of gigabytes per second
Okay maybe not hundreds but when not limited by a drive or ram lanes/connections, it's not little
Players can also only damage 2 times per second
So 40 players is only 80 max
Just saying :))
okay well then don't even think about it haha
my ancient Ti83 overclocked could do that
actually probably not even overclocked
considering it can play doom
it entirely depends on the type of data, permanent yes just use sql. if you need to "sync" constantly redis works the best
Damage is just minimized if its not a hit after cooldown. It still does damage.
sus
my ti84 ce can probably only take a few dozen square roots a second at most
at least using tiBasic, maybe its a different story using z80 asm
Does someone know how this is not an instance of the reference? (Using IntelliJ debugging tool)
The result is an instance of SQLiteDatabase and the reference is the SQLiteDatabase class
reference is type Class
i think you're asking if a Class object is an instance of itself which doesnt make sense
or am i wrong idrk
I don't think it's type Class. I used the parameter as SQLiteDatabase.class
type SQLiteDatabase? Not sure how else to setup the parameter
oop big link
Lol
But shouldn't it be an instance of both?
Instance of class and SQLiteDatabase?
It also implements an interface called Database which it should also be an instance of right?
this is the interesting bit
note that your reference argument in your getConfig method is type Class<T>
But this is a comment on that comment
yes
they are both correct
or i guess yeah the comment is more right
but the idea that Class represents classes is correct
But this can't be setup using an Object. I need some sort of Type
Not sure how else to do it
what exactly are you trying to do
This might explain it better https://paste.helpch.at/ebejejowud.typescript
public class SQLiteDatabase extends Database implements LocaleReference {
reference.isInstance(reference)
is there a reason you have to do this fancy Class stuff at all? it seems like you just want to provide different implementations to storing a config
you want to check if Object result is an instance of reference
other way around
wait both would work actually
result is an instance of the class represented by reference
reference.isInstance(result) and result instanceof reference would both work no?
This works how I want tho
public <T extends LocaleReference> T getConfig(Class<T> reference, String name) {
Object result = configs.get(name).get();
if(!reference.isInstance(result)) {
return null;
}
return (T) result;
}
Is there an easy way to make my SQL queries compatible with SQLite? I feel like I have to rewrite my entire connection code to support both 😢
mostly they should work
and almost every time if a statement don't exists in sqlite there is an alternative for it that works for both mysql and sqlite
Sweeeet I had only one situation where I had to handle some oddity. SQLite support implemented 👍
What's the correct SQLite query for checking if a table contains a specific value that is not marked as the primary key?
For example I want to check if items contains an item with given name
"CREATE TABLE IF NOT EXISTS items (" +
"uuid VARCHAR(36) PRIMARY KEY, " +
"name VARCHAR, " +
"price INTEGER" +
");"
just do a select query?
why would you do that in first place
like you can do it, but if you don't specify an index for the affected columns, you might run into performance issues
It's basically just to warn the user that an item with the selected name already exists, but it should definitely just be cached instead
Or idk, SQLite is pretty fast, is caching it in the jar worth it?
probably not, but the scaling factor of the db depends on the indexes you're using
SQLite can't magically search through n strings in O(1)
How does it handle it based on primary key then? There's some efficiency way of checking that right?
primary key means unique, combined with the data type it can create a unique index for that column
if you index the item name column it should be bearable
still depends on exactly how many items you plan on having stored though
you can do some benchmarking of your own to see how long it takes
Does spigot have an api for getting the base64 texture string of a skull? PlayerProfile only has methods for getting the URL 😦
I just used this when I needed it https://github.com/deanveloper/SkullCreator/blob/main/src/main/java/day/dean/skullcreator/SkullCreator.java
yeah well, I need to get it
Yeah true but it's just one class
Not the nicest code but it does its job D:
if (ServerVersion.HAS_PROFILE_API) {
val profile = (meta as SkullMeta).ownerProfile ?: return null
val textureUrl = profile.textures.skin ?: return null
val json = "{\"textures\":{\"SKIN\":{\"url\":\"$textureUrl\"}}}"
return Base64.getEncoder().encodeToString(json.encodeToByteArray())
}```
Me and a friend of mine are doing a coding project that includes frontend/backend and I just made the endpoint diagramm containing stuff like /api/laps or /api/teachers or /api/classes etc. Now he's telling me that we decided on a REST API and thus everything should have one endpoint and the resource you want to access is put into the body of the request. I have never seen such an API, nor ever thought about REST APIs in that way. Can somebody tell me that his thoughts aren't exactly right?
yeah that sounds like a GraphQL API lol
REST is all about having different resources mapped to different urls, using like GET POST PUT PATCH etc. to confer different meanings about those resources
curl -X GET me.com/api/v1/bitches
Imo doing that with HTTP requests is worse than sending the status code as a field in the response body and with an HTTP status code of 200
I mean there's pros and cons to both
but having a single endpoint and doing routing behind that is a big part of GraphQL, which is maybe what they're confusing it with?
I don't think so
inb4 response is 200 but body is a nicely done 404 html
They sent me a redhat link called "what is a rest api" and said "where is it written that you have multiple endpoints"
send him this
The server identifies each resource with unique resource identifiers. For REST services, the server typically performs resource identification by using a Uniform Resource Locator (URL). The URL specifies the path to the resource. A URL is similar to the website address that you enter into your browser to visit any webpage. The URL is also called the request endpoint and clearly specifies to the server what the client requires.
that part is the most useful lol
Okay they meant RPC
ah
is that like controlled RCE?
isn't RCE remote-code-execution 🥲
ye
I mean it's just different ways of framing APIs lol
RPC is better for stuff that doesn't fit the resource model of REST well, like doing complex actions and stuff
but like meh, tons of web tooling is centered around what is basically REST, so it's not super worth it imo to do something like that
especially if other people are going to be consuming it or anything
But like simple resources and get/put/patch/delete requests are more REST than RPC I'd say
I mean by definition they are yea lol
Is this as efficient as using a combined future?
for (Quest quest : registry.getAll()) {
this.update("INSERT OR REPLACE INTO quests(identifier, type, icon) VALUES(?, ?, ?)",
statement -> {
statement.setString(1, quest.getIdentifier());
statement.setString(2, quest.getType().toString());
statement.setString(3, quest.getIcon().toString());
});
}
consider using batches
updateBatch("insert blah blah", statement -> {
for (quest ...) {
statement.setString(...);
statement.addBatch();
}
});
updateBatch would be basically the same as update, but instead of calling statement.execute() it'd call statement.executeBatch()
Ohhh, never heard of batches for cf before
Will look into it, thanks!
I changed it to this, which does basically the same tho I think
public CompletableFuture<Void> save() {
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(
registry.getAll().stream().map(quest -> this.update(
"INSERT OR REPLACE INTO quests(identifier, type, icon) VALUES(?, ?, ?)",
statement -> {
statement.setString(1, quest.getIdentifier());
statement.setString(2, quest.getType().toString());
statement.setString(3, quest.getIcon().toString());
})).toArray(CompletableFuture[]::new)
);
combinedFuture.join();
return combinedFuture;
}
Oh lol
batching like this will use a single connection once, as if it was a single operation
the query itself is "compiled" once in the server and then the params are sent following it
doing this you're just doing the same thing over and over again, + depending on what thread pool you're using under update you might thread-starve or take an absurdly long time which is no bueno
Does executeBatch work for updates as well as queries? As in executeQuery() and executeUpdate()
Ahhhh I see
yes
Why is there a difference between executeQuery() and executeUpdate() then?
they are more so "helper functions" around execute()
Ohhh wait I can't use executeBatch for queries tho, only updates
As I need the resultset
you can
you need to get the result set separately
Just
statement.executeBatch();
ResultSet resultSet = statement.getResultSet();
?
but, insert doesn't return a resultset afaik? not sure why you'd need that?
uh
you don't need batching when doing regular select queries
batching is for update/insert basically
Oh okay, so I can remove the executeBatch rly
Alright, perfect, thank you :))
It made the code a lot cleaner as well yeah
public CompletableFuture<Void> save() {
return updateBatch("INSERT OR REPLACE INTO quests(identifier, type, icon) VALUES(?, ?, ?)",
statement -> {
for (Quest quest : registry.getAll()) {
statement.setString(1, quest.getIdentifier());
statement.setString(2, quest.getType().toString());
statement.setString(3, quest.getIcon().toString());
}});
}
oops
forgot the addbatch
make sure whatever registry.getAll() returns is thread-safe, as it's gonna run on a separate thread, or copy it beforehand, the same goes for Quest
It's just this, so I'd assume so
public Collection<Quest> getAll() {
return quests.values();
}
quests is a HashMap
Oh HashMaps are not thread safe
Ahhh ConcurrentHashMap
Will this be thread-safe then?
looping is nearly never thread safe
you can copy a concurrent hashmap
then loop over it though
I only need the values from the map tho
you can copy the values before calling updateBatch, then use that copy inside it
List<Quest> quests = List.copyOf(registry.getAll());
updateBatch(.... {
for (... : quests)
});
So List is thread-safe?
But Collection isn't right?
Not sure what determines whether or not it's thread safe sry
no that's not how it works
the map can be modified anytime from the main thread since you're running on another thread
if you copy the values, the copy won't be modified
But with this, the map should still be concurrent right?
no
since you are copying the collection before using it in another thread
using getAll directly in another thread runs the risk of the main thread modifying the map (removing/adding a quest) and the query can blow up
by copying the list, you basically take a snapshot of the collection, so subsequent additions/removals are not going to alter the copy
Ahhhhh yeah now I understand what you mean
That makes sense
If an event is called asynchronously, does an error or warning show up?
I have been troubleshooting one of my plugins for ages, and I found out I am calling an event async accidentally, and that was what broke most things though there was no error or warning in the console
Not always. Some events will respond with an error others won't.
Mine is a custom event
How would I implement an error or warning for that?
If it is possible?
When calling an event, should I do Bukkit.getPluginManager().callEvent(event) or event.callEvent()?
Got it, they're the same 🥲
Use Thread.currentThread() I guess
Not entirely sure but that would do the job I think
callEvent(event) already does the check, if an event is set as async it can only be called async, if the event is set as sync it can only be called sync .. on paper at least
But if you really need to check, Bukkit.getServer().isPrimaryThread()
⚠️ noob question incoming ⚠️
@Override
public void spawnCrystals(Player player, int amount) {
SpawnCrystalsEvent event = new SpawnCrystalsEvent(amount, player);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
amount = event.getAmount();
player = event.getPlayer();``` to make sure my custom event can be cancelled and also allows to change the values of `amount` and `player`, is this appropriate?
I haven't really messed around with custom events much in all my years of plugin development lol
I would avoid overriding the method's parameters, but yeah, that's how you usually do it
Okay thank you
can i make a config.yml file and have that used as the default config?
yes. Default of what though?
my default plugin config
instead of config.addDefault()
can i just create a yml file that created by default with the plugin?
Yes, call JavaPlugin#saveDefaultConfig() somewhere
Yeap. Add it to your project and use JavaPlugin.getConfig().options().copyDefaults(true); true will force write paths.
Or what gaby posted.
where do i put the config.yml though?
In your project. Usually in resources.
ok
is it possible to get custom heads without using a name or GameProfile?
i dont see any of those
org.bukkit.profile was added in 1.19
Well, what other options are there??
what about 1.12 because i dont have a GameProfile in my autofill menu
name or texture afaik
How can i set the the itemMeta for a player_head so i can set the Skull Owner ? or change the texture of it ?
Lot of player head questions today
Happens
((SkullMeta) ItemStack.getItemMeta())
https://paste.helpch.at/idomuvutef.java
Am i able to add this to that code ?
Yeap.
I'm not on PC but I'll send some skull generation code later.
Okay thanks
Yes, mojang auth lib
yeah i got it
can you add data to an itemstack that can't be seen my the player?
like custom key, values?
nbt is what you are looking for
specifically, PDC
1.12 
Cursed
the joys of working with old versions
btw technically, I think NBT/PDC can still be seen by clients if they have like a mod, so don't put something that absolutely shouldn't be shared
haven't confirmed it tho
yeah they can
but not with vanilla client
it should be fine in many cases but just be sure you don't hide any passcode or smth
encrypt it 
Hmm question
If an item spawns in a world through a glitch which duplicates it, will that be caught in an ItemSpawnEvent?
I imagine the answer is 🤷♂️
@mild stirrup, @abstract gate
ItemStack skull = new ItemStack(Material.PLAYER_HEAD);
SkullMeta skullMeta = (SkullMeta) skull.getItemMeta();
if(ServerVersion > 17) {
PlayerProfile profile = Bukkit.createPlayerProfile(UUID.randomUUID(), "<Name>");
PlayerTextures profileTextures = profile.getTextures();
profileTextures.setSkin(<TextureURL>);
skullMeta.setOwnerProfile(profile.update().getNow(profile));
}else {
GameProfile profile = new GameProfile(UUID.randomUUID(), "<Name>");
byte[] encodedData = <Base64>.getBytes();
profile.getProperties().put("textures", new Property("textures", new String(encodedData)));
if(field_profile == null)
field_profile = new ReflectField(skullMeta.getClass(), "profile");
field_profile.setValue(skullMeta, profile);
}
```This should be ran async. Also make sure to adjust accordingly. This can't just be copied and pasted.
ok thx
when setting the food value, does the game automatically make it not go above 20?
or can it go higher?
🤦 uuid != null ? uuid.toString() : data
Caused by: java.lang.NullPointerException: Cannot invoke "java.util.UUID.toString()" because "uuid" is null
Yeah I doubt that’s the code you’re running there
i think its a bug in the jdk yapperyapps
yapperyapps probably uses the Eclipse compiler
Can anyone recommend a good, quality, top-notch command builder framework? My plugin is getting messy around commands and I really need to clean it up xD
cloud https://github.com/Incendo/cloud or https://github.com/TriumphTeam/triumph-cmds perchance
Ooh triumph is niceeee
yapp uses the Eclipse compiler* you meant to say
I've been using LAMP for all my projects, really noce
Full code at the time was ConsolOutput.instance.debug("Generation (" + (uuid != null ? uuid.toString() : data) + "), Skull: " + skull.toString());
I do use eclipse.
Well you either found a bug in the eclipse compiler then or the exception occurred somewhere else
That's the line the stack trace posted lol
That's why I was confused since it cleary checks null.
Why would the compiler be the issue? The code is fine.
🤷 Java
Idk it was only debug code that didn't even help with the problem I was debugging.
Just thought it was weird for occurring.
bruh what is "Java" in your opinion
java, also known as...
borrrrrnana
javascript
i resist the urge to shitpost in development
Does anyone have a GSON adapter for ItemStack? Just using GSONs reflective stuff doesn't work sadly
you can serialize using base spigot method but that doesnt give json afaik
Is there an updated post on this for later versions since they changed to using mojang mappings.
As a lot of the methods in here uses spigot mappings and some methods no longer even exists anymore.
just use paperweight and don't care much about mappings
or use an API to do the work
Just look up the new mappings or using spigot/papers maven plugin to convert mappings.
The issue is uh half the methods don't exist as far as I can see, e.g. Chunk(the nms on)#a which returns a ChunkSecion(spigot mappings) I could not even find a method that returned a ChunkSection (or LevelChunkSecion)
Because they are named differently per version. Which is what most people use the maven plugin for.
Doesn't paperweight use some sort of mappings as well? (I've never used paper weight before)
it uses mojang mappings
Yes, but Ive gone to https://nms.screamingsandals.org/1.20.4/net/minecraft/world/level/chunk/LevelChunk.html and checked for return values and no return gave the thing I needed.
Then I'd have to convert them into mojang mappings still.
😭
Did not find that but thanks i guess.
yeah the mappings viewer doesn't show inherited methods
That's why I see so likely checking decompiled is better.
no, just writing code is better
auto completion basically already does everything you want
Yeah I guess, but sometimes the params can get annoying especially when theres no javadoc.
Ah yeah true, it's just for database so doesn't really matter
For
Does anyone know for arg2, what should I pass in if I don't want the block to apply physics.
im trying to use nbt editior in my plugin but im getting NoClassDefFoundError
i assume the dependency is not getting added to the plugin?
Most likely not, a very common mistake I see that causes that is people using a build tool like maven but not building with maven and building with IJ instead
Or not using the correct task to build
well im using gradle, and just using the default build when creating a spigot project with the mc dev plugin
With gradle you need to use the shadow plugin and the task shadowJar
i dont have a task
Did you add the shadow plugin?
is that this?
https://github.com/johnrengelman/shadow
Yeah
No I’m not, but even if I am, no clue what’s the flag int for noPhysics
Anyone ever used Hibernate ORM to manage DB connections? I'm getting an "Entity Class not found" error which is incredibly generic.
For added context, here's my attempt at creating the session factory for my HSeason.class file. https://paste.helpch.at/vojujoxeja.java
You need to register your entity classes for Hibernate ORM to recognize them:
Configuration configuration = new Configuration();
configuration.addAnnotatedClass(YourEntity.class);
anyone knows how to develop a server
DM, I can help you out.
If retry4j has everything, use that
It hasn't been updated in 4 or 5 years. I'd have to write a 30 page PowerPoint explaining why it isn't bad to use it 😭
Someone know how to fix this?
I want to have the icon and "Users" to be in the middle/center so it looks like 1 line..
I use tailwind css.
<div className="d-flex align-items-center text-center">
<UsersFour size={32} />
<h1 className="text-gray-700 text-center mb-6 dark:text-gray-200 ml-2">Users</h1>
</div>
idk if you have vertical-align: middle already
Am I missing something here? What exactly is class d-flex. Is this a class made by you? If you're using TailwindCSS, why are you creating custom classes?
Also, I think you want to use content-center not align-items-center.
d-flex is bootstrap iirc
maybe add some padding?
Oh. First time I see someone mixing tailwindcss with bootstrap.
Mind clarifying what you mean by fallsafe's Retry policy not allowing custom entry logic like entry4j did?
Yes sorry, didn't know i had that installed.
I used jetstream and it was automatically in it xD
But it was fixed
The h1 had a margin-bottom
Just set it to mb-0
Yeah. My bad. Before I do that though, I just want to clarify that I've just ended up writing my own little retry service.
Retry4j has a method called retryOnCustomExceptionLogic which takes a Function<Exception, Boolean> which lets you decide if you want to retry or not.
From what I've seen, failsafe specifically states that only specific exceptions can be handled. So you have to give it the exception types you want it to retry on.
Yeh it turns out the reason I was getting the problem was because I had my dependency listed as “provided” and included it in plugin.yml under “libraries”. Which removing that and violating it works. However now I have an issue that my plugin is 11MB. Any idea how to reduce that size down, but still have access to the hibernate dependency?
Ah, gotcha. Yeah, you're right. Thanks for the clarification
By default, policies handle any Exception that is thrown. But policies can also be configured to handle more specific exceptions or conditions
https://failsafe.dev/policies/#failure-handling sounds like you don't have to specify any particular exception, but that you can handle specific exceptions in a specific way
Oh. You are right. I somehow missed that completely. Well, it is a bit late for this but thank you!
Does anyone have a gson Type Adapter example I can see? I found the official one but it doesn't seem too good
uh, a type adapter for what exactly?
Anyone able to help me figure out how to reduce the size of my plugin? I'm currently 17MB, which is obviously too large. I tried using minimizeJAR true but that only dropped it to 16MB
what are your dependencies
I mean the answer is "use less stuff" but if your core dependency is big, then it's big, you could use proguard I guess to further get rid of stuff but you need to set it up and idk how
if you're using 1.17+ then spigot has a libraries feature
you can load libraries on runtime if it's on maven central
So I tried running the libraries and changing it to provided here, but the moment I do that, the dependencies stop working.
This basically
And yes, lombok is bad ik, pls just ignore it lol
This is what I currently have https://paste.helpch.at/arafuxiqih.java
Just trying to figure out the next step
Is this bad?
writer.beginObject();
writer.name("quest");
JsonObject object = new JsonObject();
object.add("identifier", JsonParser.parseString(quest.getIdentifier()));
writer.name(object.getAsString());
writer.endObject();
For writing the string
Is there some magic I need to perform to get my project to point at the libraries?
uh yes
you'd want to do something like
writer.beginObject();
writer.name("identifier");
writer.value(quest.getIdentifier());
writer.endObject();
although that won't store any other info besides the identifier, usually you'd do something like
writer.beginObject();
writer.name("identifier");
writer.value(quest.getIdentifier());
writer.name("thing");
writer.value(quest.getThing());
writer.name("other thing");
writer.value(quest.otherThing());
writer.endObject();
etc
or just use records, gson handles them naturally
idk if gson has a way to automatically work with hierarchies when deserializing
The issue is inheritance. I have a KillQuest class for example that extends Quest, therefore it didn't really work
Also shouldn't I have something to actually identify if the reader actually found data for quest. Some sort of identifier for that?
what
When gson goes through the data it has to recognize that it's a Quest somehow right? How do I identify if it actually is a quest?
gson.fromJson(fileReader, Quest.class)
Oh yeah.... I'm dumb lol
it doesn't have to be a FileReader, but any other source gson can take
Thank you! Will try to make this work
hmm, doesn't seem like it
jackson does 
I’m sorry Ms. Jackson 😔
Kinda proud of this lol https://paste.helpch.at/ucecijobaz.java
I did get a lot of help, but I think it looks good
The null checks might not be optimal but yeah
Anyone recommend a dependency management solution/library that works great?
what is a "dependency management solution"? lol
like gradle? or like dependency injection?
My plugin is 20MB right now due to dependencies and Maven/Gradle ain't about it. I need a way to remotely fetch them. The "Libraries" feature in plugin.yml somehow breaks the dependencies, I guess they aren't loading properly or it can't be found for some unknown reason.
oh I mean yeah that's basically as good as it gets
I found a fork of Libby which may be perfect
or just stop using 20MB of dependencies maybe? lol
I'm trying to use Hibernate to model my DB. It's a worthy cause
there's no way Hibernate is 20MB
Hibernate + Hibernate HikariCP is somehow
rather hibernate-core + hibernate-hikari
oh my god hibernate core is 10MB
what the actual fuck lol
just do raw SQL at that point lmao
Lol I currently use RAW SQL with a DAO setup, but it's still too messy for my liking
is it 20MB messy? lol
surely not
No not that bad, but maintenance is a pain in my butt. Especially maintaining SQL and SQLite it's very "Ewww"
Seems like I don't really have a choice however, I can't even get a dependency solution of any kind to work. Even Libby isn't cutting the cheese properly. Surely theres a reason that the libraries feature isn't working as expected to load the libraries. Do I have to point them at something somehow for them to work, or just include them in the list?
what do you have right now?
in build.gradle/pom.xml and plugin.yml
pom.xml: https://paste.helpch.at/ibuwacoguz.xml
plugin.yml: https://paste.helpch.at/civebijore.yaml
Heres the error I get as well : https://paste.helpch.at/woduyuzubu.md
The class definitely exists at that package location. The moment I direcly use the dependency without libraries suddenly the error disappears.
oh hmm
maybe it seems like spigot made it so that the libraries can not access the plugin's classes?? 🤔
- org.hibernate:hibernate-hikaricp:6.4.4.Final
```this one should hopefully work without issues though
idk how big that dependency is
oh nvm its very small
if you're using latest paper, then I think paper-plugins could have something
but I don't really know much about it since I haven't used it myself
Is it possible that I need to add the dependencies, for the dependencies to the libraries list? Like manually enter them all.
no
So just a hot tip, abandoning HibernateORM wasn't a bad idea. Switching to ORMLite was a good idea. Much much much easier to work with and it works great with the libraries feature in plugin.yml. 😄 No more shading/relocating required and my plugin is ultra-lightweight at a very nice 152kb 😄
Dude you gotta share some code or something. That question is abysmally generic and very difficult to answer 🤣
I'm guessing, you could parse the placeholder, before giving it to papi, and implement your own functionality for it whenever the placeholder matches a pattern.
Did you compile this? @lyric gyro
or did tanguygab do that for you as well?
If you compiled it, then it makes sense to ask for help changing it.
If not, then asking how to edit the code to accept arguments won't do you much good tbh.
And iirc you don't have any experience with java development, so it would make a lot more sense to either: learn at least the basics of java development first OR ask somebody else to do it (maybe tanguygab)
This is the same reason I was really confused about your initial question as well
?learn-java
Online Courses:
Online courses are also great for learning java. Some websites that offer them are:
- Coursera - Free unless you want a certificate
- PluralSight - Great courses from what I've seen. Mostly Paid
- Udemy - Never used them myself but they seem to all or at least most be paid.
My first ever course was one from Coursera. - I can say it was pretty good at introducing me to the programming world as a whole not just java.
Oracle Docs:
Oracle docs can help a lot at learning and understanding java:
- Start with this,
- Breeze through this (skipping stuff that doesn't seem relevant like bitwise operators),
- Hit this.
They're the first three from this larger thing which you should definitely go through overall. But those three should be enough for slightly better understanding of what is happening here without feeling like a huge time sink.
That one is a small part of this larger site wherein "Essential Java Classes" and "Collections" also have good useful stuff
Other services:
Some other cool services that will help you learn java are:
As you can see there are plenty of good ways to learn as long as you're willing to invest the time. Have fun learning!
yeah, i like it
you are going to need an IDE to start actually coding, but really have to learn how the language functions first before going into a project
vs is fine, but i would go with intellij if your ram allows it
Imho it is better to get a proper IDE
vs is a proper ide, he is not talking about vs code i believe
with plugins it can be, i personally would just go with jetbrains stuff though
anything above 8 and you should be fine with small code bases
i feel with latest versions this is not really true anymore, intellij performance has been getting worse i feel
or rather all jetbrains ides feel slower
Is it common for updated resouces on Spigot to actually not update? Seems my recent update isn't actually appearing despite uploading it. Sus
never had that happen nor did I hear anyone else encounter this issue
if (!tipus.isEmpty()) {
if (!player.hasPermission("antiswear.bypass")) {
event.setCancelled(true);
String serverName = player.getServer().getInfo().getName();
String playerName = player.getName();
String customMessage = "§8(" + serverName + ") §8[§4§l" + tipus + "§8] §c" + playerName + " §8» §f" + message;
getProxy().getPlayers().stream()
.filter(p -> p.hasPermission("antiswear.see"))
.forEach(p -> p.sendMessage(customMessage));
player.sendMessage(new TextComponent("§4§l! §8| §fAz üzeneted nem felel meg a szabályzatnak, ezért nem lett elküldve."));
}
}
Can someone help me make the customMessage variable a clickable text, when sent, and after a staff clicks on the text, it would run a command "gmute playerName" ?
#general-plugins @hearty igloo
ignore @spring crescent's message, it is recommended to not use that spigots bloatware. It is better to use https://docs.advntr.dev/text.html
stop recommending bad stuff to people lol
What is peoples’ aversion to dependencies and third party libraries? I understand sometimes they can be bad but also discovering that can be an amazing learning opportunity. Case in point, I discovered Hibernate is great, but not for plugins. As a result I went and learned ORMLite. Or I discovered IF is better than TriumphGUI, or that ACF is phenomenal. All these things I’ve picked up by trial and error, because I did research and tried different things.
I mean yeah I think its almost always worth trying something before fully judging it
If anything for the sole purpose of reminding you that you aren't a 10x dev, and no one is, and that you should just quit now xD
I'm a 10eggs developer. I'm a farmer xD
Hibernate is really nice .. if you're using Spring
+1
You pretty much hit the nail on the head, it’s like buying a new game that you’re looking forward to playing and running into people who have thousands of hours in the game. They inform you of the statistical best meta and if you’re not playing by that meta you might as well uninstall.
This has plagued MC development spaces since I’ve been in them and I think are the culmination of a couple factors
I think another big part of that on the flip side though is that a ton of people try to do MC plugin stuff without Java experience/as a first time learning to program and they can make some really bad code lol
i know i've seen my fair share at least here
Maybe I'm just built different. I thoroughly enjoy helping people, and because of that I always have a preconceived notion that everyone else would feel the same. Particalarly in a setting like HelpChat, where the idea is to help xD
jokes on you, I have been coding in java for quite some time and my code still sucks
😎
^^^^ Refer to the above note about 10x dev xD
good, just don't recommend them shitty stuff like spigot's text chat components and we gud
How am I to know it's shitty, without first experiencing it. I made no such recommendation, merely posted a link.
I appreciate being called out on it, but there is this thing called "Tact"
the correct answer is not posting it at all
😎
anything spigot related = bad
take note
paper 🔛 🔝
You’re unhinged
facts xD
you speak like I know what that means 
It means, you're deliberately trying to get either #1 an ego boost, or #2 trying to get a rise out of people
Then perhaps the correct answer is to not post anything at all 🙂
💀
more like, 3rd, making sure people don't go down the sh@ hole that spigot is
trying to save ya bud
For example, a good response to a perceived shitty post might be to say something like
"I appreciate you're trying to recommend X thing, but X thing is bad, and here's why."
Simply making a blanket statement "Don't recommend shitty stuff" makes others perceive your comment as abrasive, and off putting, degrading any potential for self-growth, for both you and the receiving party.
sadly, 80% of people that fall in that hole are unable to be saved, they become spigotolics and their opinions of the holy spigot can't be changed
fair point
See, growth ❤️
man, i love the fact that you have the energy to explain after the response
ngl I would not have it
but also, anything spigot-chat related is quite bad
We're all on a different journey my guy. I don't know it all, and I know I don't xD I can see why he posted that response, and I respect it. Namely because I'm making myself look at it from his perspective. Guaranteed @worn jasper is thinking "Oh god, not another one of these."
The amount of people in the community that are just plain arrogant is what makes help channels feel shit, specially for newbies
I mean look at stackoverflow as an example
hell yeah
thanks?
I can’t add reaction but fax 📠
Why are you assuming I'm talking about you? lol
Revert to statement #1 ego xD
cause I myself agree that I was a bit arrogant
Yes but that is like a tiny bit of arrogance compared to what you see from others
duplicate of another question thats not even the same, question closed
I was this close 👌 to posting a lmgtfy.com link xD
"Have you even searched?"
"See the docs"
"*downvotes for no reason, refuses to reply and explain why, mark as duplicate*"
SO is incredibly toxic. The only time a post doesn't get downvoted/closed is when it's so darned complicated no one can figure it out, then it will go unanswered with a 200+ bounty for months.
By that time, a different solution has been found xD
the downvote part especially is annoying to see
especially when I have the same question as the poster 🥲
no comments or anything, just -2 or something
Ah and let's not mention that they'll immediately block your account for getting just a few downvotes
My first SO account was straight up banned
👀
I am a proud owner of 31 reputation 😤
They even sent me an email after I created a new one "Previously banned users, never generally improve, we may ban your new account"
Now I have 2.5k reputation, somehow xD
-2 jerma core 😌
maven {
name 'papi-repo'
url 'https://repo.extendedclip.com/content/repositories/placeholderapi/'
}
implementation group: 'me.clip', name: 'placeholderapi', version: '2.11.5'
Even though I did everything right it doesn't detect the api, does anyone know why?
Wdym?
Like what's the error?
If it's just red, reload maven (common issue; intellij should fix it)
Otherwise, please send the error or a screenshot
there is no error. I can't use the API
Oh, so it seems to load OK but doesn't work in the code?
yep
Hmm
Can you send the full pom.xml?
i'm using gradle
Oh lol oops
Can you send the full build gradle?
Not really sure what could be the issue
Also you reloaded gradle right?
I think it's like ctrl shift O or the little gradle icon
fix it
Oh also use compileOnly, not implementation
fixed*
Oh nice
Or else it'll include the placeholder api jar inside your plugin, which might cause problems
you are answering your own question there
send the packet to only one player by either handling the entity yourself
or cancelling other packets being sent
to other players
either works
use packetevents
or protocollib
whichever you find easier to deal with
do any of you know (even if its through paper api) if you can modify the experience drops from blocks being mined specifically
couldnt you just cancel and break yourself worst case?
declaration: package: org.bukkit.event.block, class: BlockExpEvent
found this
oh thats helpful
oh
wait no, you can just ... setdropexp
on the actual break event
Hello, can you help me, my placeholders dont work. why?
package org.dewery.dewerystatistics;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.inventory.FurnaceSmeltEvent;
import org.bukkit.plugin.java.JavaPlugin;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.OfflinePlayer;
public final class DeweryStatistics extends JavaPlugin implements Listener {
private int cookedItemsCount = 0;
private int brokenBlocksCount = 0;
@Override
public void onEnable() {
getServer().getConsoleSender().sendMessage("Плагин запущен");
getServer().getPluginManager().registerEvents(this, this);
// Регистрация расширения PlaceholderAPI
new StatisticsExpansion(this).register();
}
@Override
public void onDisable() {
getServer().getConsoleSender().sendMessage("Плагин выключен");
}
@EventHandler
public void onFurnaceSmelt(FurnaceSmeltEvent event) {
if (event.getSource().getType() != Material.AIR) { // Проверяем, что предмет не воздух
cookedItemsCount++;
}
}
@EventHandler
public void onBlockBreak(BlockBreakEvent event) {
brokenBlocksCount++;
}
public int getCookedItemsCount() {
return cookedItemsCount;
}
public int getBrokenBlocksCount() {
return brokenBlocksCount;
}
}
class StatisticsExpansion extends PlaceholderExpansion {
private DeweryStatistics plugin;
public StatisticsExpansion(DeweryStatistics plugin) {
this.plugin = plugin;
}
@Override
public boolean persist() {
return true;
}
@Override
public boolean canRegister() {
return true;
}
@Override
public String getIdentifier() {
return "dewerystatistics";
}
@Override
public String getAuthor() {
return plugin.getDescription().getAuthors().toString();
}
@Override
public String getVersion() {
return plugin.getDescription().getVersion();
}
@Override
public String onRequest(OfflinePlayer player, String identifier) {
if (identifier.equals("cooked_items_count")) {
return String.valueOf(plugin.getCookedItemsCount());
} else if (identifier.equals("broken_blocks_count")) {
return String.valueOf(plugin.getBrokenBlocksCount());
}
return null;
}
}
What are you using to test?
What command?
Try using /papi parse me %dewerystatistics_cooked_items_count% for example
i just installed my plugin, and try to use my custom placeholders but they dont work
this command simply outputs my placeholder in the format: %placeholder%
tell us what you're doing and what you're getting as a response exactly
does anyone know possible causes of getting a "NoSuchMethodError" error even when I have the required classes and methods in the plugin?
you probably did not shade it correctly
check your maven - gradle
this specific project isnt maven, im using a local library and all other methods work fine other than this one method which doesnt make any sense
It’s most likely not on the classpath at runtime
my plugin depends on two other plugins, I added them to depend, but how do I compile? I imported the jars to library so I can import and all that but it won't compile
what
when i try to compile it says it cannot find the symbol from the dependency, I added the jars to library
although I don't want to compile with them since they are already plugins in the server
actually it specifically says error: package infinitycity.botanischergarten does not exist
how?
like what are you using to add the jars to the library?
I'm guessing that you're trying to use 2 different build tools at once (which won't work)
intellij and maven or gradle
does anyone here know how to convert an Inventory to an ItemStack[] i have a function to serialize an inventory to base64 and then one to deserialize it to an Inventory but the setContents() requires an ItemStack[] and i cant seem to find any sources using my wording on how to do this
There is a bunch of information online
This thing has been discussed like a thousand times
the keywords ive used must not be the right ones i coudlnt find any
Cant you just get the contents of the inv?
the contents of the players inv are gotten and serialized to a string then saved as a pdc im trying to now reverse that and set the players inv contents to the contents gotten back from the pdcstring
getContents() returns ItemStack[]
if(cmd.getName().equalsIgnoreCase("deserialize") && sender instanceof Player) {
Player player = (Player) sender;
String inventory = getpdc(player, "inventory");
Inventory inv;
try {
inv = deserializeInventory(inventory);
} catch (IOException e) {
throw new RuntimeException(e);
}
//here is where i want to set the players inventory to the contents gotten from inv
}
instead of serializing the inventory to base64, serialize the contents
or if you want to stay with saving inventory, ^^ does the trick
im not really sure how to do this im new to the whole inventory stuff right now im using the methods from this gist
https://gist.github.com/graywolf336/8153678
how new are you to it?
essentially my main goal here is save the inventory to the string that is then saved to the players pdc then when i run a command it takes the string back deserializes it then sets their inventory back to the contents gotten from the deserialization
i just started learning it a few hours ago
inventories or bukkit itself?
inventories ive been developing with bukkit for a couple months now this is my fourth plugin
well I just told you, you can't simply override the inventory object of a player (I think), just set the contents of it, and save the contents instead of the inventory.
-setpdc(player,"inventory",serializeInventory(player.getInventory().getContents()));
-requires Inventory
-given ItemStack[]
requires an Inventory but getContents() gives an ItemStack[]
basically this requires an inventory not an itemstack
public static String serializeInventory(Inventory inventory) throws IllegalStateException {
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream);
// Write the size of the inventory
dataOutput.writeInt(inventory.getSize());
// Save every element in the list
for (int i = 0; i < inventory.getSize(); i++) {
dataOutput.writeObject(inventory.getItem(i));
}
// Serialize that array
dataOutput.close();
return Base64Coder.encodeLines(outputStream.toByteArray());
} catch (Exception e) {
throw new IllegalStateException("Unable to save item stacks.", e);
}
}
ok, and?
just use getInventory()?
so setContents() cannot be used i have no choice but to use Inventory my issue still is that i cant update the players inv or set contents of the inv without a way of using the Inventory type to do this somehow
you can use it
just use getContents() from the inventory you saved
quite confused on what's so hard?
omg i didnt even think of that let me try that
Best way is to just save the contents instead of the whole inventory as said before
be easy on me i just taught myself java like two months ago lol
that sounds scary but gl on that
I would also def. only use things you understand, helped me to learn
aka only use the above method if you actually understand how it works
so i did that using this line player.getInventory().setContents(inv.getContents()); but got an error and the error log it too big to post here but something clearly went wrong
but it returns im pretty sure a nul pointer exception
?paste
Paste Services
When asking for help with a config/menu/code issue please use our paste bin:
(we prefer it over pastebin.com)
• HelpChat Paste - How To Use
this is the relevent line to the error
Caused by: java.lang.IllegalArgumentException: Size for custom inventory must be a multiple of 9 between 9 and 54 slots (got 41)
im assuming the issue is that this includes armor slots in the serialization of the inventory but im not too sure how id work around that
but where the return is less than the expected 54 slots that doesnt seem the issue if im thinkign this right so im unsure of this issue or whats causing it
by learning how serialization works and creating your own method
a little assistance in getting further in this would be more helpful than dismissing it, after all how can one learn without the learning part
no it's just the library is not added to the build.gradle while the IDE can see the library because I added it
you can't use intellij artifacts and gradle at the same time
assuming that's what you mean - my question wasn't a yes/no question
you just sent an "assistance" yourself, and google is free for everyone.
.
is there a method to make a player drop all slots of their inventory? or do i have to make some crazy for loop to cycle through each slot and drop the item somehow
- option
hmmm ok
craAAAazy for loop 🤪🥴
can someone elighten me on a method that can be used to drop an item from an inventory slot
World#dropItem
You hit the nail on the head already, for loop over the players inv and armor contents, clone and drop them at the players location and then delete them from the inv
ohhhh thats very helpful i didnt think i had to use the clone part this may make this much easier
You might not have to, you might be able to just drop the itemstack themselves and then delete the inv contents, test both ways if you wish
so this may be all wrong but im hoping im on the right track here ```java
public void dropInv(Player player) {
int invsize = player.getInventory().getSize();
ItemStack[] itms = player.getInventory().getContents();
for(int i = 0; i < invsize; i++) {
itms[i].clone();
}
}
for(ItemStack is : player.getInventory.getContents())
so this?
public void dropInv(Player player) {
for(ItemStack is : player.getInventory().getContents()) {
is.clone();
}
}
assuming no since this gives an error when attempting
Check that the is isn’t null, if(is != null) {
Otherwise you’re cloning air as well lol
probably a dumb question but when doing this null check can i use```java
if(is = null) { continue; }
or should i just use a ```java
if(is != null) { the stuff }
If you use continue the for loop will instantly move onto the next iteration in the loop, just use the 2nd one
ahh ok i have only use a contiue once so i wasnt 100% on what it did
ok that passed no errors buttt nothing dropped
did i miss a step
Continue moves onto next iteration and break will break the loop and move onto other code in the method
Send the code
public void dropInv(Player player) {
for(ItemStack is : player.getInventory().getContents()) {
if (is != null) {
is.clone();
}
}
}
oop ok so another probably dumb question but whats the method to drop the item and or put that item in the world (not allowing it to get picked up immediately)
or is that world#dropitem
its probably in that jdoc but is there a way to prevent instantanious pickup
You’ll have to pass a location in as well as the itemstack itself
id want that to be directly infront of the player but im not sure if this is right but i can take the location and setX/Y/Z to +2 right?
Providing you know which way (x or z) to increase you can just player.getLocation().add(2, 0, 0) in the case of increasing the x cord
ik theres a method for facing direction ive used with vectors but figuring that out seems overly complicated
If you want the drop to be exactly in front of the player I’m sure people smarter than me have answered that on the spigot forums or I’m sure somebody here can help you with that, I’ve never attempted to drop based on vectors so don’t wanna lead you astray lol
haha thats ok your help was the most help ive actually recieved here so far haha the final void ive come up with is this ```java
public void dropInv(Player player) {
String world = player.getWorld().getName();
Location ploc = player.getLocation().add(2, 0, 0);
for(ItemStack is : player.getInventory().getContents()) {
if (is != null) {
is.clone();
Bukkit.getServer().getWorld(world).dropItem(ploc, is);
player.playEffect(ploc, Effect.TRIAL_SPAWNER_DETECT_PLAYER, 10);
}
}
}
ik some of my methods are kinda strewn in their efficiency but it works for me and helps me understand it haha
Some things I’d change
- You don’t need to get a string of the world, you can just get the world itself with player.getWorld()
- You don’t have to clone the itemstack with this method so you can get rid of that
- If you have the world you don’t have to use Bukkit.getServer().getWorld because we already have it so you can just do world.dropItem
- If you want to add the pickup delay you can use Item item = world.dropItem(pLoc, is) to create an item object and use .setPickupDelay() to set the delay as shown here https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/Item.html
Other than that gj
so how do i add the dependency?
can anyone tell me what would cause this to run as many times as there are players online i cant seem to figure it out
public void onInteract(PlayerInteractEvent event) {
Player player = (Player) event.getPlayer();
if(Objects.equals(getpdc(player,"zoomable"),"true")) {
if (player.getInventory().getItemInHand().getType() == Material.BLAZE_ROD && player.getItemInHand().getItemMeta().getDisplayName().equals("Zoom")) {
if (event.getAction() == Action.RIGHT_CLICK_AIR) {
//player.sendMessage(ChatColor.BOLD + "DE TEST WERKT!");
zoom(player);
}
if (player.getInventory().getItemInOffHand().getType() == Material.BLAZE_ROD && player.getItemInHand().getItemMeta().getDisplayName().equals("Zoom")) {
if (event.getAction() == Action.RIGHT_CLICK_AIR) {
//player.sendMessage(ChatColor.BOLD + "DE TEST WERKT!");
zoom(player);
}
}
}
if(Objects.equals(getpdc(player,"launching"),"true")) {
event.setCancelled(true);
}
}
if(Objects.equals(getpdc(player, "jailed"), "true")) {
event.setCancelled(true);
} else {
event.setCancelled(false);
}
}
for example the zoom function runs once to the player who is holding the Zoom blaze rod and right clicks air (as its meant to) but if a second player joins every time i click with the zoom stick it then 'zooms' me twice and so on for every additional number of players that join, i may have missed some discrepancy in the code event but i cant seem to see it
You’re not checking per hand https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/event/player/PlayerInteractEvent.html#getHand()
It’ll fire twice (once per hand)
Hello everyone! Could you help me resolve a question?
Is it possible to have a plugin do "Session Validation" to verify if a player is connecting from their premium account with a valid session and is not an "usurpation" using a premium username in a non-premium launcher
Just set online-mode to true (they're turned on by default), and this will automatically be handled for you
The idea is to keep online mode = false
API Status (Removed)
L
im dumb here https://wiki.vg/Microsoft_Authentication_Scheme @proven trail
slight pain
is it possible to remove the recipe book entirely from the player inventory?
I suppose it's a client-side thing
so modifying the server jar won't do much
it is clientside afaik so you cant
stupid question but would i replace itemInHand with gethand? or does this need a whole now loop?
No you don’t have to replace it just surround the code with the hand check, basically anytime a player interacts they technically do it twice (one for each hand) if you don’t want this to happen just check if the interaction hand is the main hand
it looks like there is a hand check to me
ah, but the if statements aren't correct
the check for the offhand is INSIDE the check for the main hand
ahhhh even more
the "offhand" check, checks the meta for the mainhand item
player.getInventory().getItemInOffHand().getType() == Material.BLAZE_ROD && player.getItemInHand().getItemMeta().getDisplayName().equals("Zoom")
@fleet shale
i still have no idea about the weird phenomenon you're getting with the once per player thing, but that's what I've noticed in the method so far
and since I'm giving input, I would check if the action is right click air first, then check the mainhand, else check offhand
then you don't have 2 if statements for the action, you just have 1
optimizes a bit
i removed the offhand check so no worries about that
Player player = (Player) event.getPlayer();
if(Objects.equals(getpdc(player,"zoomable"),"true")) {
if (player.getInventory().getItemInHand().getType() == Material.BLAZE_ROD && player.getItemInHand().getItemMeta().getDisplayName().equals("Zoom")) {
if (event.getAction() == Action.RIGHT_CLICK_AIR) {
zoom(player);
}
}
if(Objects.equals(getpdc(player,"launching"),"true")) {
event.setCancelled(true);
}
}
this is all it has right now but still gets the per player zoom
Paste Services
When asking for help with a config/menu/code issue please use our paste bin:
(we prefer it over pastebin.com)
• HelpChat Paste - How To Use
i'll be back later
https://paste.helpch.at/xedocorazo.java
heres the whole 'class' or rather the event calling the void and the void being called
yes
register the command in plugin.yml
Anyone knows if it's possible to disable generation of cave-spider spawners or spawner dungeons? No matter the way, modifying server jar, datapack or whatever, plugin
well nvm I think I found it
to add onto this, SHOW COLUMNS FROM table doesnt return anything
but no errors when running that
the error i get is when using MERGE INTO and its complaining about the table not existing, even tho SHOW TABLES lists the table and SHOW COLUMNS FROM table doesnt result in an error
ping if reply
still looking for some assistance in solving this (issue: causes "zoom" to happen once per player online, this is not theintended effect) ping on reply
How create a minecraft plugin with java
And can i make a minecraft plugin witg python?
And
Velocity is better or waterfall?
theres a couple guides online for making an empty plugin with java,
yes you can makenit with python but its not recommended and itll just convert to java afaik
tbh not sure which is better but from the people ive spoke to velocity seems to be the way nowadays
velocity is better, waterfall has more plugins available
ANyone here able to help me with skript?
im making one, and I haev the correct indentations. But I don't know why it says that it expects them all on the exact same line when using a ton of if statements
this is for development, not english writing, #general-plugins
recommend skunity for better skript support
or even better recommendation, stop using it
you can develop skript scripts 👍
but yeah #development isn't for scripting help
and I assume there's a discord server for skript support (skunity?)
hmhm
java is a scripting language
bless you
Ignore my spelling
false
true
https://www.ivansthings.work/
for the definitive answer on what is and is not a scripting language
Ivan Volkov's portfolio website
(real)
sure let me just not click that and disagree instead
thats not allowed
Gigachad
banned for racism
god yes
Nowhere in the channel it says it is not for scripting help
So are we banning gradle help? That's kotlin script, or groovy script
Are we banning Lua?
No, all that is totally fine to be asked here
Ofc doesn't mean people will help, I don't think there is anyone that is active here that uses Skript
And as for you, you do not need to be rude to people just because you don't like what they use, if you don't want to help then don't reply
Oh true
Okaaaay
Sorry I just forgot since I feel like that's what's been said every time someone tries asking for skript help here
And since the word "development" is ambiguous, I just assumed it wasn't for skripting
Mb
If I were to be rude I would straight away say skript sucks and not provide anything else. Instead, I provided a better place to ask (Skunity, since here is very rare to get skript help like you said) and then proceeded to provide my own personal recommendation, which is stopping to use it.
If you were to be ruder*, doesn't mean you message wasn't rude
On a side note, Skript scripting do be just english writing at this point lol
Scripting is not configuration either
So is SQL, what is your point?
debatable to be fair. But point is that saying using skript is "coding" only sends the wrong message, which in turn is what creates skript kiddies that ruin the community even more because their holy mighty skript is the best and proceed to put in their CV they can "code" lol.
What is and isn't a programming language is very debatable nowadays, for instance, the whole HTML and CSS being programming languages or not.
Same thing, some think so, others don't.
The real question is, at the end of the day, does putting that down on your CV help in any shape or form? In html/css's case, yes, in skript? Hell no.
So, excuse me if I don't say "OH skript, skript is sooo good, think skunity is better for support than here, I totally recommend using skript though!"
I have never mentioned it being "coding", this channel isn't just "coding"
How is CV even being brought up? You are acting like this channel is some sort of professional coding help lol
Skript is totally fine to be helped here, if anyone is whiling to help
You do not need to recommend, you can just ignore
Anyways, end of argument, this argument is more out of topic in this channel than the subject of the argument
But at one point, you get tired of the skript guys thinking that their whole "programming language" is the holy god of the gods and better than java and whatever nonsense those people say, if I have the chance to "save" (my words for it) someone from skript, I sure as hell will try to do so.
(Also, CV was just a random example that came to my mind)
just a few people asking for help with skript every now and again does not mean they think it's "the holy god of the gods and better than java"
it's people that just need help with something to get it done, if you don't wanna help then don't
My man shadow boxing with Skript users again 😭
All good until you see someone's bio with Skript Developer
Anyone have any thoughts on a "Structure" or "Totem" that is configured in a config, and how can I reasonably track said totem, and do X thing upon completion. For example I might want to have a structure that is in the shape of a "t" 4 blocks tall, three wide, made of specific blocks. Is there a reliable and performant way of tracking that structure to see if it has been constructed and triggering an action based on it?
I was thinking of using pre-determined "X, Y, Z" for each of the blocks' positions using an object to "map" the structure of that object, but still not entirely certain it would work all that well.
Is anone here good at Python? I want some help making a system
Basically, I want to make a system for a furniture shop, and want the features to search, check quantity and input Quantity. Can someone teach me, or send me a code so i can refer to it?
doubt anyone will spoon feed you the whole thing, post what you already did and what you got stuck on
Not spoonfeed, I just want a template
hi, is there any method from placeholder api to update a placeholder like every 10-20 seconds, i tried getRefresh that doesnt seems to exist my code: https://paste.helpch.at/ohuhufoqud.java
just return the newest value on request
and for it refreshing on another plugin, thats on them to call not on the expansion
for something that relies on time what do you do?
a feature someone wants is if you haven't slept for an hour there is a chance to get sick
how would i do that?
schedule a runnable to run an hour+?? minutes after a player first logs on that makes them sick, but restart it whenever they sleep
declaration: package: org.bukkit.scheduler, interface: BukkitScheduler
how do i modifiy them
afaik you have to remove them and make a new one to update the delay
you get the id when you first schedule a task so store that for if you need to delete it
According to the dev:
This bug happens if you have more than 1 player head of the same player in front of you.
Any way to fix this guy? (I mean, in my own plugin)
(Apart from giving a random name to each head)
so i can just create a map of these and add and remove them as needed?
you can create a map of task ids, and call a method to delete and then re-schedule a task as needed yes
how can i get output of a another placeholder?
please anyone 😩
ive searched everywhere to try and fix
omg i fixed it
when i created the table i also made the primary key, which by default H2 makes uppercase
then i pre-made the columns, which i accidentally made a duplicate of the primary key except lowercase
so when i tried setting/adding row, it couldnt bc it didnt set primary target column 🙃
adding backticks around primary key name and removing duplicate column creation fixed it
oh jk looks like its just cause everything is uppercase now which i dont want
alright fixed lowercase issue, added IGNORECASE=TRUE to my connection URL and made sure everything was enclosed with double quotes (")
oh didnt need to have IGNORECASE=TRUE, guess i wont be keeping that lol
does anybody have an idea why this doesn't work?
public class YamlManager {
protected Main main = Main.getInstance();
protected File file;
protected FileConfiguration config;
public YamlManager(Main main, String fileName) {
this.file = new File(main.getDataFolder(),fileName);
if(!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
this.config = YamlConfiguration.loadConfiguration(file);
}
public void set(String key,String value) {
config.set(key,value);
save();
}
public Object get(String key) {
return config.get(key);
}
public void save() {
try{
config.save(file);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Which part?
idk it doesn't let me save
Try config = config.save(file);
i also have its child
public class Warps extends YamlManager {
public Warps(Main main) {
super(main,"Warps.yml");
}
public void newWarp(String name, Player owner) {
System.out.println("works!");
}
}
Also if you initialize main already whats the point in passing it?
protected Main main = Main.getInstance();
YamlManager(Main main, String fileName) {
could you explain what super() is?
super basically grabs from the parent class... "super" class.
so if i call super()
in a class that extends YamlManager it will run
public YamlManager(Main main, String fileName) {
this.file = new File(main.getDataFolder(),fileName);
if(!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
this.config = YamlConfiguration.loadConfiguration(file);
}
this right?
Based on your code above, Passing main to that constructor isn't needed.
i know
Sorry didn't read the first line. Yes a class that extends that class should call that constructor when super is used.
so its like doing this:
manager = YamlManager(stuff)
new YamlManager() yes
np. Let me know if you got it to work.
?
Hello there, I was wondering how I could update the victim's scoreboard inside the if (killer != null) in my onPlayerDeath script. I tried importing the code below into it but it won't work.
UUID victimId = victim.getUniqueId();
int victimKillStreak = killStreaks.getOrDefault(victimId, 0);
int limitedVictimKillStreak = Math.min(victimKillStreak, 5);
ChatColor victimKillStreakColor = getColorForKillStreak(limitedVictimKillStreak);
String coloredVictimKillStreak = victimKillStreakColor + String.valueOf(limitedVictimKillStreak);
victim.setPlayerListName(victim.getName() + " " + victimKillStreakColor + "[" + coloredVictimKillStreak + "]" + ChatColor.RESET);
updatePlayerScoreboard(victim);
Full onPlayerDeath script: https://pastebin.com/ZCfYshw8
Is it possible to exclude the root jar from projects with subprojects?
I don't need the top one
i think u can do ```gradle
tasks.jar {
enabled = false
}
or something like that
Will this also exclude it from the publishing?
That worked ty, not sure about publishing tho
wdym?
are you publishing that to a maven repository?
I'm publishing the project to a maven repository yeah, but I don't want to publish the empty root ofc
been a while since I've set it up, but I think as long as you don't create the publishing configuration for the root it should be fine
Hmmm it needs this for some reason
can u show build.gradle(.kts)?
Yeah, this is the publishing function or whatever I use for my projects without subprojects, just not really sure how to change it
To exclude root
try putting that in the subprojects as well (excluding common)
Could not PUT 'https://maven.summitrealms.com/private/com/summitrealms/summitlibs/common/1.0.0-SNAPSHOT/common-1.0.0-20240323.225241-2-all.jar'. Received status code 413 from server: Payload Too Large
It's like 1.5mb and shouldn't be too large
I think it's adding more than it should
Trying to run scan
How?
Ah yeah ofc
That does seem to work
It might just be the repo settings then
1.5mb limit just seems so low
interesting
idk what the cause is but if it works, that's all that matters :)))
I'm assuming bukkit & velocity would be shading common tho, meaning both would be bigger than common
Do you know if it's possible to publish in a queue sort of? So it's not all in one request
wdym?
currently, it should be doing that
bukkit -> velocity (ig gradle likes to go alphabetical)
So the "Payload" isnt too large is what I mean
Or well to make it smaller at least
Right now it's one big payload I assume
Under 1 payload tho right?
i think 2
because the tasks are registered under each submodule
so it runs the tasks in both submodules separately
Would make sense yeah
What's the general structure for usage, should the bukkit module implement the common module as a dependency?
Or should whoever uses the library implement both
tbh I'm not sure here
usually, libraries/apis shouldn't be shading though
didn't say anything earlier since I don't have much knowledge about this
Ah alright, thanks for all the help tho :))
I'll look into some open sourced projects to check this
Oh they use this thing
dependencies {
api("")
}
Never seen it before
api or the api("")?
ah that's like shading but not
it shades when ppl use your library
but your library jar doesn't actually shade it
Why are you publishing a shaded build
I'm not sure if I should shade it or how it should be setup
I just have a sub project called "bukkit" that needs functionality from "common"
What's the difference then? the core can't be used inside the project?
the difference is that it allows the project using your library to manage it
ex they can exclude it if needed
however, you can't api the common module because it's not published
so either
a) shade it
b) publish common
which is better? probably b, but I don't have any examples to prove
¯_(ツ)_/¯
I'm pretty sure publishing shaded builds is bad practice though as Sparky implied
Would that also include publishing builds using api dependencies? As it shades but doesnt or whatever lol
Just using this as example https://github.com/SpongePowered/Configurate/blob/master/format/yaml/build.gradle
no, because for api, the project is aware of that and can control it
for shading, it's as if everything is in 1 (bc it is), preventing any control
there's probably other reasons besides that
What happens if someone using the library implements both bukkit and common then?
It would have 2 copies of common right?
Or well graddle would handle that in some way, but probably not optimal?
hmm, not sure how gradle would handle it
but using api prevents that conflict because gradle can just choose the higher version or smth (idk what gradle does)
or the user can exclude one version
Found this
If you are a library mantainer you should use api for every dependency which is needed for the public API of your library, while use implementation for test dependencies or dependencies which must not be used by the final users.
Basically what u said yeah
also note that you don't need shadow to use implementation
I'm pretty sure
in the library
because as long as the project using your library has shadow, it'll work
although if you want to relocate something, ig you'll need shadow (as the configurate example above has)
Honestly not even sure when to use shadow, I never really understood it, I just always add it lol
Okay so the api thing makes kinda sense, but why would you give the library user the option to not use the common module? As it's required to run the program
api is the same as implementation but your consumers get access to the dependency too
its unrelated to publishing
just publish your core or whatever and dont shade
shading causes conflicts
How do I avoid shading though?
by removing shadow?
oh lol
I should probably look into how shading exactly works
But I never understand why it's used
It's used to copy + paste the compiled code of libraries into your .jar file
basically building ur project just compiles ur own code, not dependencies
If you don't have access to them another way, you basically need to shade them to get access
so when u shade it compiles it and includes the dependencies
^
Otherwise you can use like the Spigot library loader, or like Spigot could maybe include it and expose it to you directly
Ohhh so shadow just adds all implemented dependencies to the jar?
yes
yes
Ah makes sense
but what's the difference between implementation and compileOnly if implementation doesn't add the dependencies to the jar?
I thought that was what its for
compileOnly means dependencies that you only need for compile time, implementation is dependencies you need always
shadow is just a way of obtaining those implemented dependencies
also - while Star and Sparky are here, would this mean that it's better to publish the common module as well?
otherwise, shading would be needed
But what's the functionality difference if it's not added to runtime anyway?
defeinitely
Without shadow ofc
alr
I don't know if there is really a functional difference lol, I just know that's how it's setup
I think gradle and maven just provide ways to declare where dependencies should be available but don't actually technically do anything about it
Ah gotcha
maven is kind of the opposite way, where you have to add <scope>provided</scope> to have it not shade stuff iirc
but similar vibes, declarative dependency managers, etc.
Then the difference between implementation and api doesn't make any sense to me, if I'm not using shadowjar
Well I think the idea is that there are other ways to provide dependencies
if ur just building regularly it doesnt do anything differently, but (i think) if u run it with like the like the application plugin, in tests, or use shadow theyll provide the dependencies (whether they add them to the runtime classpath or include them in the jar)
Like not just shadowjar
implementation = hidden
api = not hidden
in code
when editing in build.gradle.kts, everything is shown & editable
except when shading
Yeah, but does making it not hidden change any functionality for the consumer of the library? Other than the fact they can see it?
the change is functionality is the fact that they can or can't see it
it'll always be in the final jar, but api will be accessible in code while implementation won't
basically
project :a
dependencies {
implementation("paper here")
}
project :dependant
// build gradle
dependencies {
implementation(project(":a"))
}
// java file
import org.bukkit.inventory.ItemStack; // error, cannot access
but if we change
implementation("paper here")
to
api("paper here")
then it will automatically get added to :dependant when they depend on :a and there wont be an error
Why not just make everything not hidden then? Too much unusable information?
see above :))
(and just ignore that you're not supposed to be shading paper)
Same reason you don't publish every method and class in a Java project
hide implementation details, so you can change them
Ohhhhh
That makes good sense yeah
for instance, if a library that depends on you also depends on your version of like, say, HikariCP, and then you upgrade, it'll break their code
ohhh also i misread ur message
oops
i thought you said why not make everything hidden
but I think it's basically what Star said - the same (or similar) reason why visibility modifiers exist in java
Ahhhhh gotcha, and still keep backwards compatiblity right?
Exactly
yea its a terrible example
no its good
That actually makes a lot of sense
no like in terms or real world ness
So api is basically "public" in java and implementation is "private"
yeah
That's very oversimplified ofc but the concept ig
still there, just hidden
Project with path 'common' could not be found in project ':bukkit'.
Should it maybe be in root subProjects instead?
try :common
I forgot I can just use rootProject().project("whaever")
Is it possible to exclude specific dependencies from shadowJar?
yeah mark them as compileOnly
This just seems wrong setup
They're so big because they have the common as api dependency
Common:
api("org.spongepowered:configurate-core:4.2.0-SNAPSHOT")
api("org.spongepowered:configurate-yaml:4.2.0-SNAPSHOT")
api("org.spongepowered:configurate-gson:4.2.0-SNAPSHOT")
sub projects:
dependencies {
if(project.name != "common") {
api(rootProject.project("common"))
}
}
Does this seem right?
The size of common womt change the size of velo and bukkit unless ur shading
Using api will shade it tho right?
Anything on the runtime classpath will be dhaded by shadow
so I'm confused, surely you want to be shading Configurate since it's not provided by anything?
But u shouldnt use shadow if u dont wanna shade
Usually u want ur consumers to be shading
or if this is a multimodule project, the Bukkit and Velocity ones should use compileOnly instead of api, since they're just consuming it from your other plugin
Usually the opposite lol
You want providers to be shading and providing it to other stuff, and the consumers just link to it in the classpath at runtime
Yeah, it’s a custom fork for Configurate, so can’t use the version in papermc jar
Ah okay yeah
I need shadow for other dependencies tho
So, you intend for people to have the Common jar plus either Bukkit or Velocity depending on which platform?
like on a Paper server, for instance, they should have the Common jar and the Bukkit jar?
That’s what I’m not sure about, what’s best practice?
Best practice is just to have one jar per platform
and just basically include all the common in it
This is a library tho? Not a plugin
Yeah, so common should probably not even be published then, and just internal
Unless im misunderstanding
Looks like both lol
A common "library" and two plugins, one for Bukkit and one for Velocity
