#development
1 messages ยท Page 75 of 1
there is legit no way to update an uuid of an account
it's the unique for each account.
updating on other tables has nothing to do with data type
How much will the performance be impacted realistically lol
the single case where that could be used, is if you want to transfer everything from x to y, but at that point just copy it, create a new user and delete the old....
you mark uuid as foreign or primary key and its no different
0
basically
uber big scales you will see a difference
on a minecraft plugin basically none
I am speaking in the context we are now.
regardless there no point doing premature optimization
^^
I always fall for the premature optimization trap
literally, we are not speaking about a company with millions of rows in an sql database
To make "things more future-proof"
and using uuid or id as primary key, will probably be one of the "less" factors when it comes to optimization in sql
comment by grzegorz
since most of the time, it's a query issue
take hangar sql queries as an example, they quite need to be optimized, tbf they have already been a bit but not perfect yet
and tbh, "norms" can be taken in several ways
take hangar again as an example, if you scheck their database structure
god...
they are not respecting several normal forms
lol
but to be fair, it wouldn't make sense for them to respect them in their case.
normal forms are good to know in general and a good base, but there are cases where they are not good.
main difference would be on index size and you cant get out of querying for the uuid varchar at least once
going by id is possible sure, but you would have to do at least one query to get that id with the uuid.
hi
ya, i can see it making a "difference" if you query a lot for the uuid
can somebody maybe help me with the connect feature of deluxemenus?
then it might be (probably not) worth it to query for it to get id once then use the id on a id-indexed table
in theory, you could get the id once on join, cache it and voila, do all the next queries with that id
ya exactly
will it make a huge difference? maybe in hypixel, but not in 99.99999% of the cases
even in hypixel its probably not a huge difference
yeah
but indexing file size wise it will since varchar index is quite size intensive
afaik
so the question is, do you want to "over" optimize it at the cost of a tiny bit of ram or not lmao
true.
TLDR; it does make a tiny difference. Is it that noticeable? Very probably not.
Then it also depends on how your systems works, for instance, if you request all the data from the database on join and cache it all, then going with uuid probably won't make a difference.
Also, hi, focused on the conversation, mb. What do ya need?
if you have a lot of tables, it might be worth it to query for id then use the id for everything else maybe, but i would only do it AFTER it runs into a performance issue and not before
^^
Also, if you care about performance, don't make the mistake some do cause it looks easier of using FROM several tables and then having a WHERE with their conditions, use (inner) joins, they are more performant.
And this, funnily enough, can have a huge impact in performance depending on your database from tests I did at school.
oh np. i tried to use deluxemenus to connect from world to world in my server with multiverse core but i dont understand how i need to connect it
read the channel topic, not the place for that. #general-plugins
oh sorry
mb
that just overcomplicating a database schema IMO
like now, to insert something for a new player you need to requests its generated id
from the database
TriumphGui doesn't have a pane system right? To have sub-guis essentially
I'm trying to set up pages for a selection system basically. But not sure what the best option would be
@pulsar ferry Sorry for the @ just saw you were online so I hope its fine
It doesn't, best option would probably be to extend the BaseGui and implement your own way of handling that
Or use a library that supports this kind of stuff a bit better, like incendo/Interfaces
Ah alright, havn't heard of incendo before, I'm just working on a plugin someone else made who uses IF (by stefvanschie) but I can't figure out how to update an item like gui.updateItem(slot, ItemStack) so now I use triumph gui lmao
Will probably be hard to replicate the same thing, good luck :')
I'll use TriumphGui and try to setup a system for the pages, it's just not very easy to handle properly imo
TriumphGui already has most of the functionality required actually. The filler basically works like a pane, just configured a bit. It already handles the area functionality
Wait Paginated GUI exists? lol
Didn't know that
lol
0 I would assume
actually
maybe 1?
idk
try and see I suppose?
I have it somewhere but too lazy to open intellij
just go to the method's code
and check it
True
on shoot:
if projectile is an arrow:
send "You Have Thrown A Pass!" to shooter
on projectile hit:
victim is a player
send "you have completed a pass" to shooter
okay so i have this but i want it to then wait until the victim is hit and then track the north and south amount from the shot to the hit and display that and im super confused on how to do that
im trying to transfer this from skript to a plugin how i do
listen to entity damage by entity event
then check for damager type, cast to arrow if arrow
then get shooter of the arrow for the second part
for first part you need this one
This is not a place for skript ๐คข
it's skript xD
no im asking how i would go about making it into a java plugin
oh kinda saw skript and skipped the next sentences you said lol
but yeah bitpex explained it
what would be the best way to send objects to another server? i am thinking of just using sockets and object streams but feeling like it might be a bit overkill
serialize and send through redis / something third party i guess? (please ping anyone responds)
If they're on the same proxy, you could use Plugin Messaging if you want something internal
Otherwise yeah, serialize and Redis would be your best bet
Could go even harder and have a separate http backend and send messages through that
i was thinking i could just do sockets since netty is included by default
yeah but that doesn't really get you any of the resiliency
is plugin messaging still limited to targeting players?
well you have to send it through a player's connection, so there has to be at least one online player
i mean any way you choose is gonna use sockets in the end
but going raw and de/serializing data to a byte stream yourself is kinda pepega
i mean yeah, question is do i just implement it myself or is there a better (already implemented) way
redis is a cool message broker
or how star suggested and make an http service to pipe things through
yea redis is awesome
gets you lot of resiliency and even if the server is down or something, it will hold the message for em
i guess i could just serialize to json and send through redis
yea that would probably be best
when switching servers through bungee order is
preconnect to other server
player connects to other server
disconnects from the current one
right?
or is it
preconnect
disconnect
connect
i could probably just use the db then no? i need to store the data i want to send anyway so might as well just lock the row on leave and use that as "messaging" effectively
ya synching some data between servers
ah yeah you should look at HuskSync
It's what I use for my servers, uses Redis for super fast transfer and DB to persist data snapshots
I did something like that a while ago with just mysql
worked without any issues
didn't even require redis
yeah most of my fear is related to MPDB and that whole mess
so having a lightning fast Redis cache makes me feel a lot better ๐
what could go wrong?
latency, database connections, weird locking, etc.
with something as critical as player data, having more confidence is always good
Eh, latency shouldn't be that big I would say
db connections? use a connection pool xd
i feel like there would be race conditions though with db only
you kinda need a "hey get this players data" message to be passed to other server
i mean these are just my lived experiences lol
idk what specifically went wrong
but people lost data and it was not cool
if I recall correctly from when I did it, I waited 1-2s before making the request of the data on player join
so just half-assing a player data system like that isn't what I would do lol
thats such a bad solution though
yeah HuskSync waits like 150ms lol
barely noticeable by the players
would rather set up a seperate socket just for "hey data is ready"
not really about the player experience
2 seconds is defo noticeable too lol
rather solution being bad
you have transfer packets now too so, why not use them?
what lol
yeah 2 was extreme, it was like 800ms
that's not really related to this
transfer packets are for swapping servers without a proxy
lets say for some reason your db insert / update
gets delayed for 2 seconds and player already ends up on the other server
but couldn't you transfer data with it?
no?
now you pull the old data then
not like well
I swear I saw that on patch notes
and certainly not their entire player data
and was even spoken here
I mean, in that case you could do the famous "hey, player data updated"
i feel you have to for any robust solution
redis messaging channels is the way to go i guess
pluging messaging would be perfect if it didnt require a player
what if you send it on disconnect like 100ms after
in theory the player will already be in the other server?
so there will be someone there xd
same issue, also you dont know if the player actually disconnected or switched servers i believe
why is having a player even required?
does it send data to a player via the proxy?
or what
i got no idea honestly, but it would be so much more useful if it was just a connection between servers
yeah, wonder why that's not a thing in more modern proxies
like velocity
paper and velocity could implement something like this
the minecraft protocol has a custom payload packet for client <-> server communication, plugin messages is just spigot's name for that
being a minecraft packet means that a player needs to exist to use it in its connection
oh so it uses that "hack"
i mean it isn't a hack
hence why I put it in ""
the purpose of the packet is to transmit custom data lol
I would call it a mini hack cause it's actually being used in a way that "kinda" isn't meant to be used
why's that?
1s mid valo
whats even the purpose? wouldnt the client need a mod to have the ability to react anyway then?
yes, the purpose is for mods to use that for their communication needs
it's also used for stuff like sending the server/client brand
debug markers too iirc
yeah like Xaero's Mini/World Map use that for sending which map to use
which is very useful for servers behind proxies since the client has no way of knowing which server it's on
chunkyborder uses it because it's cool
I think the Logblock Visualizer also uses it which is p cool
Kinda want to make a simple rest api to use between servers. So player isn't required.
if only there was this highly optimized program that could act as a message queue between programs ๐
๐คท if only. I prefer my own way though ๐
I mean, it's intended for client/mods to communicate with the server, and basically what they do is "use" that to communicate between servers.
can i use javascript by nested?
what
%javascript_itemattloreline_%javascript_itemattlore_NeutralDamage,1%% this.
%javascript_
item_
attloreline_
%javascript_itemattlore_NeutralDamage,1%%
is it at all possible to create virtual worlds/runtime only worlds in bukkit where there's no folder created for them and they don't persist after restarts?
yes and no, impossible if you want truly runtime only worlds
you can "fake" it by creating world and stopping the saves then deleting the files
impossible without a server fork that is
ah unfortunate
ty for the response
take a look at slime world manager
they change the way worlds are saved, might be able to hijack parts of that process to get rid of io operations by caching
sounds like bukkit doesn't give much of an option to not save worlds
ill take a look at swm though
you cant do it with bukkit, nms on the other hand should be possible
if you want to go that route
personally though, a fork is better when you need to edit source this extensively
if you do not hold a huge world (aka small minigame worlds)
then it most likely is
since the chunks will need to be cached regardless
yeah but it would likely be dozens of relatively small worlds (possible 100+, or around 1 per online)
doesnt matter
a player being present = chunks around the player are loaded to memory
file is used for persistency
when player leaves the area
^ you can see how file can be avoided if each "world" would have a player present in your requirements
and you dont need persistency
i mean for performance overhead, whether having 30-100 small and near-identical worlds takes up significantly more memory than 1 massive world that has all those small worlds side by side
probably not much
you get the overhead of world stats
ideally you would group and tick those worlds individually with a custom fork
to make it truly scale
(similiar to how folia works, but way simpler without the region stuff)
i see
my issue with a fork (and kinda nms) is needing to keep maintaining that fork it every time I want to update server version
might be a small price to pay for some gains though
if the worlds are the same
you can probably just load one world and load from it each time
even utilize slime world api
and simply not save
idea here is for a prison server, each world is a player's mine and only a certain region is modified. rest of the map is loaded either from a schematic or world, whichever way is better
considering it
i mean
io is only heavy in the sense
most of the action would happen when a player breaks blocks, i dont think much would happen on actual ticks?
you need to wait for the operation, if you put io work on another thread then your cpu is smart enough
to do other stuff
ideally i dont want io though
everything happens on ticks
you break block = calculation happens next tick when server receives the packet
ah
unless you multithread but thats beside the point
folio does sound like it'd hel pthen
i also saw someone here working on a project where one world exists and all players mine there, but everyone sees a unique mining region dependant on blocks they broke themselves/etc)
not sure if thats discontinued/public or not, but i thought it was a good concept
its made for your exact use case
divides worlds into regions, so you can tick each "region" individually
hm
with a world where you spread players that much
you have the exact use case of folia
i'm gonna interject and say that its still incredibly experiemental and a large majority of plugins do not work on it due to how it works, your plugin selection will be quite limited
i assumed they are going with a custom plugin setup regardless
i understand that, this would be customly made mostly though
especially if they want to do no io worlds etc
i expected that too but gotta specify to make sure
๐
just make sure you understand multithreaded programming properly if you want to do folia route
yeah
would also do j21 so you can use scopes etc
any idea on this though? considering taking this route as well
structured concurrency makes your life easier
havent heard of that before
you could do it with packets
java 21
i got that, i was talking about scopes
adds virtual threads and structured concurrency
oo
sounds like a lot of research needs to be done
easily doable with packets afaik, but you would still get bottlenecked due to single threaded nature of paper - spigot - bukkit
also hypothetically, how would one go about forking paper or its forks like folia? i remember seeing about cloning projects and applying git patches or smthing, havent seen a fully comprehensive guide before though
i see
less memory usage, cpu is the same
actually probably not
since you need to hold player state yourself then, so about the same
you just move who handles the data from server to plugin side
check contributing.md
one sec
@cerulean birch here
theres also the paper discord which'll help you a bit more when it comes to help and info about folia 
you need a linux instance or you can virtualize it with WSL
i see
i just do WSL then hook to the wsl from windows with intellij (albeit a bit buggy sometimes)
dont remember needing to run linux to make a paper fork damn
so what does linux instance do for that
package managers
so just apt over homebrew?
is this just a onetime process though to get started working on the fork
if you want to maintain it
you will thank yourself later for setting it up on anything unix
mac works too if you got one
Pretty sure paperweight works fine on windows now
still slow no?
Not really, at least when I tried
Uhh, I got this for loop inside of my saveData method to save player data to my database:
Set<NamespacedKey> namespacedKeys = PLAYER_DATA_REGISTRY.getPluginDataForNamespace(tableName).keySet();
int index = 0;
statement.setString(++index, dataKey.toString());
for (NamespacedKey namespacedKey : namespacedKeys) {
PluginData<?> playerPluginData = playerData.getPluginData(namespacedKey);
setValueInStatement(namespacedKey, playerPluginData, statement, ++index);
statement.addBatch(); // Add to batch instead of executing immediately
}
statement.executeBatch(); // Execute all accumulated commands in the batch```Even though I printed the value of `namespacedKeys` in the console and 3 items are in there, the for loop seems to run only once before exiting. Why could that be?
There is no warnings or errors in the console
any ChatChat users wanna help out?
build.gradle:
compileOnly name: 'ChatChat-API-1.0.0-SNAPSHOT'
cloned the project, built the API.
if I include it from maven, I get an error:
[14:58:32 ERROR]: Could not pass event ChatChatEvent to M0-Pagrindai v1.0.0
java.lang.NoSuchMethodError: 'net.kyori.adventure.text.Component at.helpch.chatchat.api.event.ChatChatEvent.message()'
at me.m0dii.pagrindai.submodules.chateditor.ChatEditorListener.onChat(ChatEditorListener.java:93) ~[M0-PagrindaiBase-1.0.0.jar:?]
at com.destroystokyo.paper.event.executor.asm.generated.GeneratedEventExecutor4712.execute(Unknown Source) ~[?:?]
or am I using outdated plugin itself, though I downloaded the latest dev build
I just relocated adventure in my plugin because it doesn't have a message API
You would have to use the relocated version of adventure
cant seem to find deserializers inside ChatChat
also I have a quite a few utility methods that use Components from adventure and they dont work with CC relocated ones
Stupid question, you have the right one imported? Are both imported?
well, the issue is, if I use the ChatChatEvent and get the event.message(), it returns me the relocated ChatChat component class
Lemme setup a workspace for ChatChat, just kinda want to see for myself how it's structured
and I use adventure from paper itself
When loading data from a database synchronously, I take it that if it takes longer than 50ms is when I should worry about performance
Since that's when the server may fall in TPS
no, you should worry before (in fact, you should just not do sync database access at all):
- the latency might differ on the setup (db on the same host? TCP performance of the host?)
- the latency might scale unexpectedly (it might take far longer with more data suddenly)
- the main thread might already suffer performance-wise without your database access (if it's already taking up 40ms per tick, a 50ms database access would be bad)
- depending on what you're doing, there might be multiple requests per tick suddenly
Should I be accessing the database asynchronously even on startup/shutdown?
I access it asynchronously all the time except those
Hey guys, what's the most optimal way of storing inventories or Container contents in MySQL? Here's what I'm currently doing.
if (event.getBlock().getState() instanceof Container) {
Container container = (Container) event.getBlock().getState();
Inventory inventory = container.getInventory();
sqlHandler.insertContainer(container.getBlock().getLocation().getBlockX(),
container.getBlock().getLocation().getBlockY(),
container.getBlock().getLocation().getBlockZ(),
InventoryUtils.inventoryToBase64(inventory)
);
}
public static String inventoryToBase64(Inventory inventory) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream);
// Write the size of the inventory
dataOutput.writeInt(inventory.getSize());
// Save all the ItemStacks to the stream
for (int i = 0; i < inventory.getSize(); i++) {
dataOutput.writeObject(inventory.getItem(i));
}
// For PlayerInventory, save the armor contents as well
if (inventory instanceof PlayerInventory) {
for (ItemStack armor : ((PlayerInventory) inventory).getArmorContents()) {
dataOutput.writeObject(armor);
}
}
// Close the data output and convert the byte array output stream to Base64
dataOutput.close();
return Base64.getEncoder().encodeToString(outputStream.toByteArray());
}
it might be acceptable there, but slowing down startup and shutdown isn't optimal either (although you can't really prevent it at shutdown I guess)
I feel like slowing it down at shutdown makes sense though
I wouldn't want the plugin to start disabling itself as it's still saving data to the DB right?
yeah
Getting this error everytime I try to restart server, server randomly crashed @ 60 players
57921 Portal: 34222645
[17:05:35 INFO]: Max TNT Explosions: 100
[17:05:35 INFO]: Tile Max Tick Time: 50ms Entity max Tick Time: 50ms
[17:05:35 INFO]: Preparing start region for dimension minecraft:chunkworld
dont crosspost
Truly horrifying error
How does writing a plugin to handle MOTD in a waterfall/bungee network work?
shouldnt be much different from writing a plugin to handle MOTD for a singleton server i imagine
any news?
Is this chat chat integration for a private plugin? If so, you can fork it, replace the spigot api with paper and remove adventure so it uses the one from paper
No and No
ChapChat
what is wrong ?
it's ChatChat lol
Im talking about the plugin where you want to use the chatchat api
Ok, then you can do what I said, which is to make chatchat use adventure components from paper
Is not a rewrite, just 2 changes in the build file of chatchat
does it compile?
also, why do you have lines 17-18 when you have paper api ๐คจ
don't ask, haven't got around to removing it lol
alright I see there's a java version issue
ah
how do you the thingy on build.gradle.kts

sec
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
}
ah it's set somewhere else
whatever
fixed
yeh fucking around too much
should probably have a decent look at the project structure first
Is this where I come to get a hacked account back
?not-discord
Looking for discord support?
HelpChat is a Minecraft plugin and development support server and is not affiliated with discord in any way.
If you require support from discord, we recommend you to visit their official support website at https://support.discord.com
On this website, you can read their FAQs, or open a support ticket if necessary.
I am having an issue with VaultAPI. My plug in is not able to detect it for some reason. I am compiling with JDK 17 for 1.20.4
My dependency import in the pom.xml is:
<dependency>
<groupId>com.github.MilkBowl</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.7</version>
<scope>provided</scope>
</dependency>
When the function setupChat() runs, it returns false because chatProvider == null
private boolean setupChat() {
final RegisteredServiceProvider<Chat> chatProvider = getServer().getServicesManager().getRegistration(Chat.class);
if(chatProvider != null) {
vaultChat = chatProvider.getProvider();
}
return vaultChat != null;
}
Anyone have an idea why chatProvider.getProvider() is returning null?
do you have a chat plugin?
Yeah, I got EssentialsXChat installed
Yep
public void onEnable() {
if(!setupChat()) {
getLogger().severe("Disabled due to no Vault dependency found!");
getServer().getPluginManager().disablePlugin(this);
return;
}
I'm not sure if EssentialsXChat supports Vault
did you try LuckPerms?
No, would prefer to use UltraPerms tbh
because UltraPerms isn't listed either, and it's closed source so I can't check the source
I should also clarify this plugin has worked before with UltraPerms and EssentialsXChat
can you try installing luckperms to see if it returns null or not?
and you can remove it after
Sure
EssentialsXChat doesn't manage prefixes, groups, etc. (why is that even in the Chat vault api?) so it can't support Vault
I'd think that UltraPermissions would support it... but I can't check
yeah ig UltraPerms doesn't support it for whatever reason
But why doesn't EssentialsChat work?
EssentialsXChat doesn't manage prefixes, groups, etc. (why is that even in the Chat vault api?) so it can't support Vault
I see, hmm. The plugin I am trying to get to work is a custom global/local chat plugin
Something must have changed I guess
Cause this use to work with UltraPerms
if this is for a private server, you can hook onto UltraPermissions API: https://ultrapermissions.com/wiki/api
Yeah, its a custom plugin for my server
Apparently adding UltraPerms as a softdepend fixed it I think
oh then it's probably registering it in onEnable instead of onLoad, and having its name start with a U doesn't help ๐ฅฒ
Ah I see.
how do you use shadowjar in kotlin dsl? (gradle)
did you apply the shadow plugin?
tasks.shadowJar {
// stuff
}
or if that doesn't work, then tasks.withType<ShadowJar> or something like that
PlaceholderAPI.booleanTrue()
how do I actually build a paper server jar while trying to make a fork? i cloned the repo, ran the ./gradlew applyPatches, all imports and everything seems to be in order. just not sure which specific tasks or command to run to get a jar and also where that jar will show up (not much of a gradle user)
nvm i think i found it. was looking in the wrong file
also surely its easier to ask this in paper discord
i just assumed that plenty of people here have experience with this and its not a very long explanation of which task/command to run and where it would show up
It is somewhere around these lines, probably on PlaceholderapiPlugin
it should be written in the docs
suggest giving it a read
yeah it was in the main readme.md, i was looking at contributing.md trying to find building instructions
looking at the wrong place ig
createReobfPaperclipJar
Do you guys make your configs in yaml or json?
Coming from the modding scene, I feel more comfortable with Json but idk if it really supported
yaml is just a much nicer human-editable configuration format than json
much less syntax to manually write
true
is this possible to let it rain only in certain chunks in one world ?
there might be better ways but one way can be by manipulating the biome of each chunk
since some biomes don't show rain
mhh i dont want to change the biom, because the non raining bioms are looking not good. Any other solution for e.g manipulate client packets ?
hypixel has this btw too. But i dont know how they do it
just call player.setPlayerWeather
on weather change events
@digital temple
and well check for chunk
I donโt think it updates immediately (rain transitions slowly to clear etc). Iโm assuming he wants a more seamless looking route but I donโt think this is do-able for a single dev.
And either way stated from bit and Ivan are probably your best bet
in conjunction with listening to this event (completely cancelling it)
player wont realize a difference
i think it does what bitpex mentioned, checking when you enter a chunk
worldguard also has it btw
downside to setting player weather is it doesn't make it 'rain in certain chunks' so much as it just makes it rain everywhere or not depending on what chunk you're in
i guess it really depends on which one you actually want
true, but vanilla minecraft (ex desert biome) doesn't have support for only raining in certain areas iirc
yeah all it does is not show the rain animation depending on chunk biome
Standing on the border of a chunk and looking into the distance seeing rain, only to then walk into that chunk and everything is clear. Youโd be unable to tell from distance if a chunk is rain or clear
But it might not matter for the use-case 
that sounds good to me. im checking if a player is entered a worldguard region and set the players weather
another problem with NameSpaceKeys
i will check, if the target itemstack has a specified key from ecoitems.
The current NBT tags shows that the key is this: PublicBukkitValues:{"ecoitems:item":"fishing_rod"}
NamespacedKey key = new NamespacedKey(Main.getInstance, "ecoitems:items");
but NamespaceKeys does only provide [a-z0-9/._-]
Any different solution to get the specified key ?
get the plugin instance of ecoitems
new NamespacedKey("ecoitems","item")
oh
Cannot resolve constructor 'NamespacedKey(Main, String, String)'
oh u remove the first arg
NamespacedKey key = new NamespacedKey("ecoitems", "items");
'NamespacedKey(java.lang.String, java.lang.String)' is marked unstable with @ApiStatus.Internal
sounds not like the best xd
Paper hasnt annotated it Internal, most stuff should run paper (if u dont run paper, u need to reconsider)
but ye
if spigot some how yeets that and make it inaccessible to u, the api consumer, u can flame me
you can also use this ๐ if u dont want to use internal
alright ill keep that in mind ๐
i forget the exact code
like Bukkit pluginmanager getplugin or smth
correct
PersistentDataContainer data = itemStack.getItemMeta().getPersistentDataContainer();
NamespacedKey key = new NamespacedKey("ecoitems", "items");
String nskValue = "empty";
if(data.has(key, PersistentDataType.STRING)) {
nskValue = data.get(key, PersistentDataType.STRING);
}
if(nskValue != null) {
if(nskValue.equalsIgnoreCase(condition[1])) {
meetCondition = true;
}
}
condition[1] = fishing_rod but it fails on nskValue.equals check. Why is ecoitems stressful ._.
What is โnskValueโ actually set to?
.
nskValue = data.get(key, PersistentDataType.STRING);
the name from the item
its "empty" like defined befor. Because he failed in nskValue.equalsIgnoreCase
condition[1] is "fishing_rod" the name from ecoItems
try this
since that's what ecoitems would use itself
ill think you mean this
EcoItem ecoItem = EcoItems.INSTANCE.getByID(condition[1]);
instead, what you mean ?
this
or EcoItems.INSTANCE ig
thats exactly like i used here
wait no you need EcoItemsPlugin
not EcoItems
wait
if you have the code imported
then just use that; there's probably a method for it
if not then #development message & #development message
oh wait
im looking in the source (wow, a paid open source plugin!)
yes xd
@digital temple Try ```java
EcoItem ecoItem = ItemUtilsKt.getEcoItem(itemStack);
// do whatever
lol what is ItemUtilsKt
yep, worked, but i cant test it right now
The Kt is because it's not part of the actual class
googled ecoitems, saw it was open source, and searched for persistentDataContainer
ยฏ_(ใ)_/ยฏ
good for now but currently i think i cant use this
ill get this error on building
java: cannot access com.willfp.libreforge.Holder
class file for com.willfp.libreforge.Holder not found
aaaaalright
I find the solution finally. You can "test" a CustomStack from ecoItems with another ItemStack
Just use customItem.test(is)
case "ecoitems" -> {
ItemStack is = Items.lookup("ecoitems:" + condition[1]).getItem();
if(is != null && is.getItemMeta() != null && itemStack.getItemMeta() != null) {
CustomItem customItem = Items.getCustomItem(itemStack);
if(customItem == null) {
return false;
}
if(customItem.test(is)) {
meetCondition = true;
}
}
}
this will not work
guys I have a question, should I make a String class that just saves all messages so I can just call them as needed in my other classes?
any ChatChat devs/users can help me figure this out?
I have a custom format for staff-chat with priority (tried with higher AND lower number than default)
for me, it works fine, since, I suppose, I have some permission that changes it, but for my staff, only the channel prefix is applied, the else is inherited from default format
for the record, I have given them chatchat.channel.format.staff permission
well, nevermind
it was chatchat.channel.format.staff.staff
Does anyone else struggle with plugins becoming too much of a web with each other? I have a core plugin which I know I want all my plugins to rely on, however there is also two other plugins (One used to add custom items, one as an economy plugin) which many of my other plugins will be depending on which I feel like will make things pretty hectic
The thing is that, I depend on that custom item plugin and that economy plugin mainly to just use 1-2 methods from their API I wrote
Is there a better way to go about this? It would be neat if my plugins could communicate with each other without depending on one another
use your core for the main api, and make your core hook into the rest maybe?
so you use the api from your eco plugin through the core api
But that would result in circular dependency
Since my currency and item plugins depend on the core plugin
Then make another plugin that doesn't rely on the core and just forwards the other plugin's apis? idk
How would that forward the other plugin's APIs? I assume it would need to depend on all those other plugins, and then those plugins will need to depend on that "api bridger" plugin which would result in circular dependencies again
look into di frameworks to get ideas on how dependency spagetti is solved
in your case of 2 3 dependencies it's probably not a big deal enough to use a framework for it
Is DI framework like Dependency Injection, but in a bigger scope?
(instead of being between classes it is between plugins, in this case)
no, eco plugin has api -> bridge depends on it and implements it -> exposes their apis through the bridge plugin
if that makes any sense
eco plugin depends on core
but not on the bridge
Ahh I see
Yeah that sounds like it makes sense
is there a way to parse legacy as well as minimessage formats to component?
ex. the text &chello <red>world would be parsed with both legacy and minimsg
well, kind of
package ru.decalium.battlepass.util;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.ComponentSerializer;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.jetbrains.annotations.NotNull;
public final class MixedComponentSerializer implements ComponentSerializer<Component, Component, String> {
private final MiniMessage miniMessage;
private final LegacyComponentSerializer legacySerializer;
public MixedComponentSerializer(MiniMessage miniMessage, LegacyComponentSerializer legacySerializer) {
this.miniMessage = miniMessage;
this.legacySerializer = legacySerializer;
}
@Override
public @NotNull Component deserialize(@NotNull String input) {
input = miniMessage.serialize(legacySerializer.deserialize(input)).replace("\\<", "<");
return miniMessage.deserialize(input);
}
@Override
public @NotNull String serialize(@NotNull Component component) {
return miniMessage.serialize(component);
}
}
you either replace all legacy color code with their MiniMessage equivalents, or first deserialize it as legacy, then serialize and deserialize again
eh I just used Kyorifier
transform the & shit to <> equivalents and only then parse MM
kinda tried that, didnt seem to work
the legacy codes got removed but no color applied
whats that
since Im using ChatChat it already has it
yes whole pattern is made to solve dependency spagetti
isnt DI was made to invent object oriented programming
What about what Mr. afonso said? about that 'bridging' plugin?
why. just. why.
Note that the second doesn't work bc minimessage will be escaped
cuz players dumb
their problem.
can't you edit it's meta?
There is also a class named FireworkEffect
i kinda dont see the point
I don't really get what you meant then with using a DI framework
all you would end up doing is that add another step as a dependency
eh, I wish
Wdym with a DI framework though?
looking it up online most things that pop up are about .net framework or simple dependency injection
there are di frameworks for handling load orders and injecting dependencies
What is a DI framework though
I'm not really following how this applies to plugins or how I'd use that in plugins which depend on one another
im tring to make a apply sytem from google froms to discord but i dont now what im dowing worng here
const POST_URL = "https://discord.com/api/webhooks/##################################";
function onSubmit(e) {
const response = e.response.getItemResponses();
let items = [];
https://script.google.com/home
for (const responseAnswer of response) {
const question = responseAnswer.getItem().getTitle();
const answer = responseAnswer.getResponse();
let parts = []
try {
parts = answer.match(/[\s\S]{1,1024}/g) || [];
} catch (e) {
parts = answer;
}
if (!answer) {
continue;
}
for (const [index, part] of Object.entries(parts)) {
if (index == 0) {
items.push({
"name": question,
"value": part,
"inline": false
});
} else {
items.push({
"name": question.concat(" (cont.)"),
"value": part,
"inline": false
});
}
}
}
const options = {
"method": "post",
"headers": {
"Content-Type": "application/json",
},
"payload": JSON.stringify({
"content": "โ",
"embeds": [{
"title": "Some nice title here",
"color": 33023, // This is optional, you can look for decimal colour codes at https://www.webtoolkitonline.com/hexadecimal-decimal-color-converter.html
"fields": items,
"footer": {
"text": "Some footer here"
},
"timestamp": new Date().toISOString()
}]
})
};
UrlFetchApp.fetch(POST_URL, options);
};```
lets say you got class a that depends on b and c
and c depends on b
normally you need to manually care about load orders
but with a framework you inject these classes
Right but how do I make a framework? It feels kinda alien to me to be able to inject classes that are not present in my project
What about like
Having an interface in my core plugin, which for example my economy plugin implements?
So that I can use the methods from that economy plugin without actually having it as a dependency?
then you lose modularity
and unit testability as well (not really used in bukkit development but still )
How so
I know this is a very specific question but not sure where else to ask, the essentials discord doesn't really have support for dev questions.
Basically I use EssentialsX Chat to handle chat on a server. I want to add cosmetics to apply a color to player's usernames, ranks etc. and was working on making a ChatRenderer, but this will just override whatever Essentials uses right?
Is not like eseentials has any complex chat system. It will be better if you replace it entirely
ChatChat on top
well
had a few issues with it already
an odd bug is that if you are in a different world X in location A, you can see the messages from the world Y in the same location
btw, @river solstice the issue you had with ChatChat regarding Adventure not being present in the API, turns out I've already opened an issue regarding it, I just forgot ๐ญ https://github.com/HelpChat/ChatChat/issues/220
Also, can you open a ticket for this? I might be able to look into it these days.
PR them ๐
- open an issue (which already exists)
eh I'll just fix it myself
we are using it in production environment so it's kinda a dealbreaker rn
the issue is probably here
it's just comparing distances, but doesn't take world into the account.
Opened an issue just so you won't forget lol. https://github.com/HelpChat/ChatChat/issues/223

- hella clean code, gotta check ChatChat's source.
- what's that color theme/plugin?
like variables have different colors, etc.
that's quite nice
then everything is one package as dependency
what you probably want is something like gradle bundles im assuming
so you dont have to list each dependency every time
Ngl, that would probably give me brain damage. If you want a nice theme (no changing colors for variables), I recommend Mattom One Dark. It is a modified version of Atom One Dark by Matt: https://gist.github.com/LichtHund/58eae0bdff2f67385de24a10a8af3c81
monokai pro filter spectrum is amazing as theme
It feels weird tbh, I personally like it more when variables have different colors depending on the scope/type (fields, method parameter, variable)
+ unused/used
fair.
how th do I install this?
I use Atom One Dark so
Also, yeah now that I think more about it, it can really get messy with changing color variables
For you it will probably be named Attom One Dark Copy when you import it. I modified it to give it a better name (in my humble opinion)
you might not like it
๐ฅฒ
no spaces around *
shit font is big af in matt's one
how do I change font size?
i think matt uses fire code tho
uhhh not sure
found it
Fira code*
you might want to turn on the Change font size with Ctrl+Mouse
is that intellij?
yeah
like completely black?
๐
๐
i kinda started with C#
and found the theme kinda nice
that's why I went with it in java too
basically
waaaaait what
i did not know
๐ฎ
game dev?
also that's not exactly fully the theme, I think rainbow brackets does some coloring for variables too
ASP.NET, Core, Framework
ah
and yes, had quite a fair amount of Unity
oh
๐ฅน
in uni we made a shitty tower-defense style game
as well as few other ones
somewhat a FPS with multiplayer
and a VR game
based on Iron-lung game
not sure about the term in english, but probably computer science, yeah
had a side study of game dev
and probably software dev too
but major is compsci, yeah
makes sense
It actually comes with a specific font and font size. I decreased mine.
I think it comes with size 18 and I use 13 or 14
But I also just have scroll to change font size enabled
O interesting
Blitz review my issue right now!!
Didn't know that was possible from color scheme
And others too..
Review your issue?
ChatChat
It is an issue, alright?
Well, that's something compeltely different
you asked me to review it
I would say 4/5
Beautiful issue
lacks some details
Overall, decent. Would recommend to friends and family
Ir doesnt even matter
I might make some PRs, then you WILL have to review them
๐ฆ
the fix for my issue is like one line of code
I am lazy and tired. I have at least 10 issues assigned to me on different projects
Its never the fix. Its always the testing
And testing Spigot stuff is awful
Though I would like the chat range to be able to work through worlds (shared)
Might add that too
Do it
Test in production
๐
Who else better tests than consumers
I don't have a production environment
You are my customer
So go fix and then go test
You just.. "fix" the issue, and hope noone creates another ticket
Already tested the fix
Works like a charm
Being Blitz Id argue your speed in fixing the issues
๐ฅธ
Dude... I spent like 4 days figuring out why the hell our connection to the DB doesn't work, got multiple AWS tickets created in the process, and the connection still doesn't work sometimes. I am not the right person for the job (whatever the job might be)
25 open issues on ChatChat, how much you wanna bet I'll make a PR resolving them all tomorrow
๐ง
Yeesh
Setup staging, make github actions spin up a spigot server and bot iself
I can't be bothered
how would i make something like %identifier_param_<BLOCK>%
I mean, everything after %identifier_ and before the ending % just comes to you as a string
so you would get param_<BLOCK> and it would be up to you to parse that
anyone knows the app to overview the maps with schematics?
question is why you use AWS for db?
Dw. it isn't for a minecraft plugin. Also, it is an issue from AWS that their support team just keeps ignoring.
Using AWS is still a big mistake from what I have heard
overall relying too much on those services
make it hard to transition out of it later on
I mean, it is a mistake if you don't have money
but if you're a company worth $14B
$18B*
it probably isn't that bad
these web service companies do make it hard to switch off from their platform for already existent apps but, they also make it easy to not have to maintain infrastructure
either way, this choice was made years ago, before I even knew what AWS is, or even what a function is.
What's the standard for working with MySQL? Should I get data from the DB and update classes whenever the plugin is loaded, then periodically update it at some set interval, or should I only request data whenever I need it and update as needed? It should be noted that I'm working with contents of Container types so it can get big, also I'm using HikariCP for performance gains. Finally, I'm a bit confused, given DB actions are not symmetrical, or async, do I need to be treating them as async with scheduling? In my testing, it seems to be mostly instantaneous, but my DB is also local so idk. Can anyone provide some tips for me? This db thing is kicking my ass.
so the company you work for is worth 18b?!
mine is only like 3b ๐
any database requests should be handled async (use the scheduler). Regarding the when to update, etc. it highly depends on the use case:
- Data is only required every so often: Making a request each time is fine
- Data is required all the time:
- Data is from a player: Request on join and cache it. You can then choose to "sync" the
Database to the cache, aka make updates every x time or not. - Data is required for 2+ players or whole server: Request on plugin start and cache it.
- Data is from a player: Request on join and cache it. You can then choose to "sync" the
That's my recommendations. Should note that database requests don't take that long. (unless you do some very unoptimized queries or have a very very large size database)
@worn jasper so data is being sent and requested every time someone places a container, or interacts with an inventory. Which could happen with n number of players.
Container = Chest?
Chest, Shulker-Box, Furnace, Barrel, etc..
Is that per player?
Yes
And. I'm tracking the contents of said things.
Same answer.
So no fear of using too much resources?
nha, resources are almost never the problem in mc plugins xD
when interacting with databases.
Just do them async, off the main thread, and you are fine.
Lol okay, good to know. I was concerned that 1000+ containers, and their contents, would bloat RAM for minimal gain.
tyvm
Would require probably way more than that xD
to be a ram issue
besides, when players leave, you remove it from cache
so, only things actually being used can be used.
Unfortunately not. The containers are player agnostic
You could in theory even go further down and only load data from loaded chunks
but no idea if that's efficient or not
wdym?
Here's the project I'm building. https://github.com/mkaulfers/hardcore-seasons
can't really check it all rn
But why exactly wouldn't you be able to remove from cache on player leave?
thought it was player specific only
or can other players access those containers too?
Basically, the short and sweet is, containers act as a "Seasonal" reward for hardcore servers. Participating players who die, lose their stuff to the survivors. The survivor of x season, can go to a different server, non-hardcore, and claim all of the generated loot, items, etc..
Think of it kinda like an Async PubG type gamemode lol
was never a pubg guy
Fortnite?
suppose you could try this? if you require other people to also have access to the containers while players are offline.
hmhm
I'm trying to setup some form of encouragement to give hardcore a shot. People might play it more if there's the potential for rewards if they outlive everyone. xD Eg why chest-data needs to be player-agnostic. Anyone can open a chest at any time and when they do I need to update it's contents such that the DB is always in-sync with what's going on in-game.
DB doesn't really require to be fully in sync at all times. If you cache stuff, then that isn't an issue.
Just sync every few minutes, that should be fine, as said, you might give the chunk loaded idea a try
In theory, should be the most efficient.
Yeh so my initial thought was to just cache it all in some data manager, and periodically update. I went away from that for fear of chewing up RAM which has now since been alleviated.
You request data on chunk load, when it's unloaded, you put it a "awaiting removal queue" or whatever ya wanna call it, which removes it from cache after a minute or so, this makes it so that if the chunk is loaded again after a few seconds, no need to make a request, you just check if it's in that queue, if yes, get it back to the main cache and voila.
I like that
that's an idea on how it would be the most efficient I suppose
Should be fairly straightforward to implement as well.
You can use a caching library like caffeine for caching, it offers time based, size based and whatever caching
a true classic
Does it support working on a proxy? And modifying the format? To apply colors to username etc.
it should've said this should never be null
real
No idea, check it
bcz it shouldn't. the only case this should ever fail if the UUID of a player changes from when they join to when they quit. And the only time I've seen this happen was when people used those cross platform plugins
Someone here good with maven deploy?
I have a multi-module project with the root only having the pom.xml and no source...
Right now it seems there are issues with the dependency resolving as the modules seem to rely on the parent pom? Is there a way I can make it not needed?
Like I get an error like this if trying to deploy or install: https://paste.helpch.at/uwulinumoq.csharp
Only fix for me is to deploy the parent to local maven repo. Remote is currently skiped as I don't see why I should upload only a pom file for this... But this would obviously cause issues to anyone trying to get the dependency.
Is there a way to change a player's display name which is visible to specific players
I am trying to do this using ProtocolLib but I am not sure what Packet to use
displayname entirely? like both tab and nametag?
lets just say nametag
oh
uh
hold on theres been a convo relating to this recently
wait, theres a Entity called TextDisplay?
display entities!!!
haven't used them myself since i dont really do mc much but
they seem cool
didn't know that existed
i think they're pretty new
1.20 maybe
or 1.19 idk
TextDisplays are awesome, my favorite part about them is they canโt be seen through walls (on Java) so you canโt see the names of NPCs or holograms through walls
Can do that with entities too. Think its a team object. HideName or something like that.
Doesnโt that prevent the name from showing up?
It might. I'm pretty sure there was one that was specific to through walls. Similar to crouching.
Erm I donโt think so but maybe, hidename prevents the name all together
No idea, but I feel like youโre really trying to shoehorn this โissueโ lol
There very well might be other ways of doing it, I was just stating the reason I like TextDisplays
Why is it an issue? Just showing its possible with normal entities.
Youโre solving a problem nobody is askingโฆ OP (shadow) hasnโt stated that they canโt/wont use the solution somebody provided them. Maybe youโre just posting this alternative method for if somebody were to stumble upon it looking for a non TextDisplay solution?
Either way you do you king, if you want to juggle things with armorstands on the NMS side go for it youโre a king. But since textdisplayes were added I was providing my input in response to shadows lack of knowing about them
And again Iโll state if you want to go the entity route go for it, if it works for your usecase amazing. Nothing wrong with it
Youโre solving a problem nobody is askingโฆ
Can do that with entities too. Think its a team object. HideName or something like that.
It might. I'm pretty sure there was one that was specific to through walls. Similar to crouching.
https://www.spigotmc.org/resources/must-have-name-hide-no-lag-client-side.83899/
โฆ ok man ๐
So, I've got this plugin called "Artifacts" which implements custom items for my network.
The current system I have is for any of my other plugins to use a Artifacts#registerArtifact method to register their own items.
This works fine, however if Plugin1 registers an artifact that for one reason or another Plugin2 might need to check for, Plugin2 will need to depend on Plugin1 just for that reason.
Which feels quite inefficient?
Currently each plugin implementing Artifacts holds static instances of these in a <PluginName>Artifacts class, but again this feels pretty inefficient.
why not abstract away the artifact
as in pl1 depends on artifacts and uses artifact interface
to create and register
p2 does not need to know about p1's implementation details
it knows Artifact interface
etc
Yeah I know but
If any other plugin needs access to one of these artifact instances
That other plugin needs to depend on the plugin implementing that artifact
Okay well the current system I have otherwise is, my core plugin has a namespace package where I just store a bunch of public static final namespaces
i dont see how p2 would need to know implementation details of p1
look at vault for example
you know you can access economy through vault
I mean, to do Plugin1Artifacts.ARTIFACT_1
ah, are you caching them in a singleton or smt?
Never really used Vault
caching needs to happen on the artifacts plugin
not on individual plugins that implement stuff
you can ALSO cache there, but access needs to go through the main one
Right, but I can't really have public static final variables there
The closest thing to that would be a public static final NamespacedKey, Artifact map
yes you cant "register" then either
regardless
have a hashmap
with namespace:item as kety
key
and use that to cache - register - retrieve
he is trying to use things of p1 in p2 while p2 depends on p1 and p1 in p2, basically a loop if I understood correctly.
I mean for now no, but I suppose that can also happen
-.-
but thats not possible since implementation and what is implemented
is abstracted away
Does it make sense to have a class or multiple classes in my core plugin which holds a lot of singleton NamespacedKey objects?
yes
thats how di frameworks kinda work
in a simple form as well
you provide them with a singleton - factory
Okay cause that was my 'temporary solution'
and they provide instances
But then no matter what, I will have to go back to my core plugin and write new namespaces any time I add new instances of artifacts for example
I assume that's unavoidable though
why not dynamically register them
Wdym? Through a register() method?
p1 calls register method
yes
if you need them all in one place make your register method
update a file or smt
But how does p2 have access to NamespacedKeys registered through p1?
it can be plain string
or a custom object as key
thats provided by the core
as in the interface
Ah right so i'd just have to "manually" type the string myself
Meaning that if for one reason or another, p2, p3 and p4 need to get the same object reference registered by p1 i will have to repeat the RegistryClass.getRegistry().getValue("Something") for each?
since these seem to be singletons
you can also use the class itself as the key
and depend - retrieve from there using it
which kinda defeats the purpose but its better than hard coding strings as namespaces
Okay so recap
My core plugin should have some kind of Registry class that holds Map<NamespacedKey, Object> and a register() method to put items in this map?
yeah a more narrowed down scope
ya
In my case Artifact
and in the case of these all being singletons
you can just go
LightningArtifact.class as key for example
and it gives you its already initialized instance
is it fine for it to be an abstract class instead of an interface?
i usually do interfaces first then dive into actual implementations*
but it does not matter honestly
it has to do with having to unit test everything at work though
The Artifact class originally was an interface, but I need anything that extends it to have a bunch of code run in the constructor
in spigot it doesnt matter honestly
you probably want a factory though
is my guess
An Artifact interface with a Factory subclass? Or what do you mean
I don't even know if you can create subclasses in Interfaces tbh, never tried
cant comment much without knowing the details
but having a lot of shared code usually signals that it can be factorized away
https://paste.helpch.at/eririluwih.java That's the class I'm on about
Some of the code in there is a year old and I haven't looked at too much
ah i see now, abstract class is fine probably
unless you run into an issue no point creating one when you dont feel any
Okay though I'm thinking
if Artifacts depends on my core plugin, I don't really have access to the class ArtifactItem from my core plugin
Which means I'd have to move that abstract class to my core plugin right
Though is it really correct to have an abstract class in my API package of the core plugin?
i would keep it seperate and depend on artifacts
on everywhere that uses it
if all your plugins will use it you can define it as a transient dependency
Not all plugins no, it's just to do so that my map will store Artifact objects as values
Instead of just Object
Ah you recon all the artifacts should be in a map inside of my Artifacts plugin?
yes
For SRP
artifact logic goes into artifact module etc
However, my core plugin should have singleton instances of the NamespacedKeys to be placed in the map?
Yeah I mean I might
i would just modulerize it away personally
But in case I want plugin2 to use an item from plugin1, i'd need that key to get the artifact
since these are items you can follow mc convention on the namespaces honestly
minecraft:grass etc
and just go with string
i would also probably make a factory on the artifact module
to get these items
yeah I mean my current namespacekey is plugin:item
A factory to get the items?
instead of implicitly calling the "artifacs"
