#help-development
1 messages · Page 1945 of 1
WorldGuard actually just did this for the longest time without any major problems XD
Calculating if a vector points in a BoundingBox is quite cheap.
You can easily do several hundred checks in a tick without noticing it.
Is it possible to check it a player is in a box region?
How?
His location is just a vector. Check if this vector is in the BoundingBox
x > x1 and x < x2 and z > z1 and z < z2
Ok
:v
Something like
public boolean isWithin(final Player player, final Location cornerA, final Location cornerB) {
return this.isWithin(player.getLocation(), BoundingBox.of(cornerA, cornerB));
}
public boolean isWithin(final Player player, final BoundingBox box) {
return this.isWithin(player.getLocation(), box);
}
public boolean isWithin(final Location location, final BoundingBox box) {
return box.contains(location.toVector());
}
how can i use " in messages?
nopermplayer.sendMessage(ChatColor.translateAlternateColorCodes('&', "Unknown command. Type "/help" for help."));
this gives me error
Send the error then
Multiple markers at this line
- help cannot be resolved to a variable
- Syntax error on token "" for help."", delete
this token
Try to escape them "
\"
"Unknown command. Type \"/help\" for help."
you need to escape quotes in strings
otherwise java will think its not a string anymore
and treat it like code
thanks.
Ty
hey, I'm trying to import https://github.com/yannicklamprecht/WorldBorderAPI into my plugin but none of the repos work anyone got some advice?
what class name do you think is appropriate for the start/stop methods?
I've tried importing it via that but it can't seem to find it
depends on where do you use it for, i'd call it Service
so no errors in your pom?
hmm, a service is actually what i was looking for thanks
hmm ._.
What's the most efficient way to test if a world object instance is still loaded? There isn't an obvious World::isLoaded method.
try getting a location of it?
Bukkit.getWorld() != null
maybe get a spawn chunk and check if its loaded
nah that will throw an ex probably
or does that work
yes
I was hoping for a way to avoid the hashmap lookup - and to be able to tell the difference between a world ref that hasn't been unloaded and one that just happens to be for a world that was unloaded and loaded again
If you keep a reference to a world then it will be kept loaded
no, i can call Bukkit::unloadWorld and just because I hold onto that world object doesn't keep it loaded
i mean, yes the object still exists in memory - but that's not what i mean
It will be kept in memory
It’s a bit annoying in your case assuming you rely on world objects themselves, as they’re not instantly removed when unloaded, rather they just get queued for collection whenever there are no hard/phantom references left. The lookup method is probably your safest bet.
Spigot just dereferences it
ok - here's the situation. Plugin to create an arena world. I want to reset that world from time to time and I don't want the performance overhead of calling Bukkit::getWorld(String) shitloads
Generally speaking you should only reference worlds in volatile scopes
Wat
the lookup isn’t gonna be the issue here
That’s a regular HashMap call at most
hash lookups are slow vs just using an object ref
and if i'm calling a function for every block in a chunk - it adds up
You’re just doing premature optimizations now
What? We are speaking about nanoseconds here. What are you saying?
HashMaps are incredibly fast
Sure an object reference is faster
But they have different use cases
I’m out
lol
question was about a way to test if a word has been "unloaded" or not - and the answer is no
not directly
have to go through the Bukkit world map
ya, that's fine - i'll deal with it, just didn't want to miss anything "better"
And you should be thankful it’s a hashmap and not some shitty linked list
Which would be even worse
actaully a LL is faster than a hasmap for small object counts
Not rly
there's parts in the standard libraries that do full scans if under 5k entries
a what
LinkedList scale extremely bad
i forget what i was looking at when i saw that TBH
Yeah especially when searching
And with small you mean < 3 or 4
actaully, hashmaps seem to cache too
Yes
so the first call is "slow" vs successive calls for the same key
It’s backed by an array
anyway, have the info i came for - thanks
Well should be said, a K type with bad hashCode implementation leaves you at O(n)
but since it’s String/UUID
It’s not gonna be a bad K type
Hence why it’s fast and reliable (:
I think unloading/loading might not be the best way to restore a world.
Depending on the size it would probably produce less lag to just use FAWE api and a schematic for that.
async world edit?
Smiles workload distributor guide 😌
and no, it takes milliseconds to "restore" several region files with an unload load
wtf is FAWE?
fast async worldedit
async world edit?
it sucks
Yeah well Ross are you deleting the regions files themselves or what?
yes
Ah makes sense
i delete then and restore them from a zip
loading a world takes several ticks and lags out the server. There is no way to do that async.
Fair, well anyhow conclusively getWorld is ya best bet if you wanna check whether a world is loaded or not
it causes a long tick in the 80-150ms range, it's not ideal but doing it once an hour or so is good enough
Or you do it chunk by chunk and have +1ms for 50 ticks every hour
Also 1 nano second is equal to 0.001 milli second and is equal to 0.000001 second
uh oh
Oh yeah
you missed 1000x
Happens
Then it’s even more negligible!
pico
Ross anyhow it’s good you prove our point that the map call is negligible (:
but it's really not lol
and it's not the map so much as the string function calls
wat
look, you can't argue to me that a map call is faster than just using an object reference
String::hashCode
and to lower
well, for IdentityHashMap then they may actually be equally fast
So?
You can do it several hundreds of thousands times in a single tick and wouldnt notice a difference.
I'm not saying that the map is too slow for me to use
So whats the issue then for getWorld?
just that if there was some World::isLoaded i'd use it lol
No that wouldn’t work
Btw detecting when a world is unloaded is quite the hassle
Unless you create some super shady proxy adapter design
Hi again, how can i set the display name (above the head) of an EntityPlayer? (I'm trying to rename an NPC)
Change his GameProfile 😄
would it be better to restore the chunk files in order to reset a world?
that goes brr
i was thinking of creating an implementation for that
Probably Freestyler
Altho it sounds quite dangerous
Unless you’re wiping all of them
the nasty part is not corrupting shit
yeah, all of them
and not confusing clients in render range
Sorry, could you send me an example? I'm new to nms and i don't really know how to change this
it's for a minigame
That probably depends on what exactly you’re dealing with
so the players won't be on the map
If it’s about data management corruption is probably gonna be a pivot
Maybe this works
public CompletableFuture<Void> unloadWorld(final String worldName, final boolean save) {
Preconditions.checkArgument(Bukkit.getWorld(worldName) != null);
Bukkit.unloadWorld(worldName, save);
return CompletableFuture.runAsync(() -> {
while (Bukkit.getWorld(worldName) != null) {
try {
Thread.sleep(100);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
});
}
or just listen for the WorldUnloadEvent event and wait a tick
final 😶
I am not sure but maybe a PhantomReference/WeakReference of type World would be fine where you register the reference to a reference queue and then later callback
But it sounds like he keeps references to the World objects which could make the WeakRef useless.
Yeah, then it’s probably a rotten idea to do it like that
Hm the method above might not work as intended. I think you actually need to check the file handles on the world and if they are released.
please
Yeah, should probably also use a custom thread pool to not slow the common pool down 😅
true
NMS is not part of the API. Its undocumented and if you use it you are on your own most of the time.
I would just look into other peoples plugins and see how they did it.
Or look at the protocol and reverse engineer how vanilla does it.
Humm, could the session.lock file be watched... seems like the sort of thing it should exist for actually
Probably, you can actually register a FileWatcher
isnt having everything as final and changing it to public only if u need it public better?
public variables ew
Or sth like that idr the name exactly
No
That breaks encapsulation and turns objects into passive data bags
then normal people just create a getter
System.out 
oh ok
I dont have any questions to java since arraycopy method not following naming conventions, breaking SRP and taking objects exist
Might work like this. I dont think there is a better way to check if a File is locked.
public CompletableFuture<Void> unloadWorld(final String worldName, final boolean save) {
Preconditions.checkArgument(Bukkit.getWorld(worldName) != null);
Bukkit.unloadWorld(worldName, save);
final File worldFile = Objects.requireNonNull(Bukkit.getWorld(worldName)).getWorldFolder();
return CompletableFuture.runAsync(() -> {
while (this.isLocked(worldFile)) {
this.busyWait(100);
}
}, Executors.newSingleThreadExecutor());
}
private void busyWait(final int millis) {
try {
Thread.sleep(millis);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
private boolean isLocked(final File file) {
if (file.isDirectory()) {
final File[] children = file.listFiles();
if (children == null) {
return false;
}
for (final File child : children) {
if (this.isLocked(child)) {
return false;
}
}
return true;
} else {
return file.canWrite();
}
}
Well you could ask yourself who wrote some of the java classes
Also pretty sure "out" is stateless, which is, eh, acceptable
Is it?
lol
the opposite of final
I mean generally speaking, any method that returns void must have a side effect in principle
thats what i meant
I think is uses some native implementation which is not shown to us
Ah fair
State doesnt means it has no side-effects, as said before, good objects should represents real life entity, the state object itself encapsulates is just real life entity coordinates
Well, anything that is stateful generally has side effects, whilst stateless things do not.
Tell me that a record has side effects
I messed up definitions
Technically at instantiation, but otherwise records shouldn’t… hopefully
Passive data bags!!! Sometimes useful ngl
Well, you probably know more about me in regards to the entire elegance of object orientation 🥲
Shouldnt side effects be avoided everywhere? Stateful or not? Mabye we have a different understanding about what a side effect is...
For me its an implicit change to the system
So a setter has no side effects for me. But a setter that also increments a counter does.
Ah, well I from my point of view, a setter changes the state of the system, else it would be no point in calling it as it returns void
CPP has a better construct for this discussion than java - there you define a method as const if it does not change any member state
aka is purely a calculation - or IIRC purely external side effects
I think java has annotations for that. Contracts and what not.
Yeah purely external side effect is the term
aka procedure
I don't think java (stock) has a way to say this method doesn't change member state - but there's probably an annotation for it in some library... and hey the language keeps evolving
And even Haskell has purely external side effects… pretty much unavoidable
final does that @simple summit
no it doesnt
along with an immutable view of whatever you want
if you want the return itself to not change
final on a method means you can't override it
not that the method can't change member state
on class that you cant extend it
Ross believe they meant for variables
In which it’s true unless you use sth like unsafe or reflection
anyone know how to disable elytra?
Anyway in the spirit of this discussion - avoid public static (non-final) things as a rule and use singletons VERY sparingly. Otherwise the best way to create robust extensible software is to follow a test-first practice (I prefer BDD myself). Testability of an implementation will really guild you to good encapsulation of concepts and motivate you to use more dependency injection instead of dependency creation (it's healthy to avoid newing complex things within your member initializers and constructors.
I mean singletons won’t really destroy your testability
@EventHandler(ignoreCancelled = true)
public void onEntityToggleGlideEvent(EntityToggleGlideEvent event) {
if (!config.roofPreventElytra)
return;
if (!(event.getEntity() instanceof Player))
return;
final Player player = (Player)event.getEntity();
if (player.getWorld().getEnvironment() == World.Environment.NETHER && player.getLocation().getBlockY() > 127) {
event.setCancelled(true);
player.setGliding(false);
tellCantDoThatHere(player, "glide");
}
}
singletons are cancer - they have their place but they are a pattern of last resort
Nah
Sure it’s more of a procedural pattern to some extent
But really no
They are good
it's the coupling they cause that is the problem
you're much better off to have a singelton factory than 20 different singletons
that's all i mean
Or if you need some sort of lazy init, a supplier that returns the singleton instance can be used
What
Where does factory come in play here xD
It’s not impossible to mock singletons either
it allows you to break the coupling problem
We have libraries and other stuff
There is no additional coupling problem if you design your system correctly
As said
You can still pass the instance through a constructor
Explicitly or with a Supplier
lol, i don't disagree - it's just easier to fuck up your system design by overusing singletons than to use them with extreme caution
Additionally, if you want to create abstractions, wrap the singleton with an adapter
Yeah Ross you’re right
I just don’t believe it couples your system
I'm talking to a "new programmer" you're talking to me about an academic argument.
At least not from my experience
Well, all things considered, new programmers usually don’t get the concept of tight coupling
my point is you're not wrong and I don't disagree - just that new players will screw themselves with it
Indeed
anyway, back to code 😉


i dont think you need singletones in well-designed systems
mstbe that lazy init but i never had any usecases for such solution
There's definitely valid uses for singletons
for example?
programs 😎
I have used it for serializers mostly
Don’t know if it was well designed, but it was definitely the best choice of design in my case
I still stand by using a Singleton for the plugin instance 
That’s arguably fine
I agree that singletons are not "necessary" - they are however "beneficial in some situations". Static state is always a coupling disaster waiting to happen.
Altho JavaPlugin::getPlugin
that's a lot of typing 
they must be used with care
Fine if they dont encapsule any state, just logic
and not be the default "i'm lazy so i always use singletons" lol
a static utility class is not a singleton
Yea
I use singletones as well for persistent daya types
Ah fair
I mean all singleton says is that we should at compile time ensure only one instance exists, and it should have a global access point
there's nothing bad about static helper methods - the contamination comes from mutable static state
We know right
I mean I consider static state doable sometimes, but mostly it fucks you up in multithreaded environments
I'm clarifying for all readers - not just those active in this conversation 😉
pain
yeah
thats also why some people dont like singletons cuz like u have to type out ur class and method name every time
that's arguably a singleton though: there's one static instance of the plugin that you can get statically at runtime and use to modify state
that's not really the main complaint people have with singletons lol
wait what is the best website to code for beginner?
Hi guys can anyone help me I am learning more but, basically im trying to convert java to kotlin and i have this problem:
https://cdn.discordapp.com/attachments/912851861923569675/941370925704683550/unknown.png
Thank you
if i use Collection<Player> players.add(p) will go red, and just say unresolved reference
Pass Bukkit.getOnlinePlayers to the constructor of an array list
Can you show me how that would look please ?
I will try
new ArrayList<>(Bukkit.getOnlinePlayers())
dont know if u saw the img (discord link) but i have problem with the for loop
add is unresolved reference.
players.add(p)
You don’t need a loop if you do that
you could use addAll() if you are just going to add all the players
I don’t see a new
ArrayList<Player> players = new ArrayList<>();
players.addAll(Bukkit.getOnlinePlayers());
one way of doing it if you want your own array for all online players
You can just use the arraylist constructor
Thanks
Think you could even do new ArrayList<>(Bukkit.getOnlinePlayers);
Mhm
That’s what I said to do
ArrayList<Player> players = new ArrayList<>(Bukkit.getOnlinePlayers);
I didn't see that, but maybe the other way I showed might be easier to translate to kotlin?
No idea
like you I don't use Kotlin either
is there an easy way to create spawn egg recipes without creating one for every spawn egg?
as they are all different items
probably could use an enum
place all the spawn egg items in said enum then you could easily apply the recipe regardless of which egg it is
Yeah you could loop over a list of the spawn egg items and do it that way
well with an enum wouldn't need to do any looping, just check which it is
I think they want 1 recipe for each item
But don’t want to specify 50 recipes or whatever
yeah, place all the eggs in a single enum
then it wouldn't matter which egg it is, just need to check that it is an egg of sorts
does anyone have issues with intellij
it spins up to 99% CPU usage
for no apparent reason
after a while
this is what I am talking about, you can put more then a single value in one enum
Now what I don't know is if you could register a recipe just using one egg, might have to create your own methods for checking?
but with an enum, could easily still do it I suppose, technically would be registering multiple recipes but just more easily done instead of typing out every registration XD
Hi, i'm doing a trail with blocks and this blocks disappear after a few seconds. I tried getting the player location but that block is just in the middle of the player, so i tried subtracting to the location, but weirdly the block appeared up the player and not down
Yes
Also that isn’t a valid config path you are using
Config paths can’t end with .
this is my code
that middle number is the y value, which is up or down
positive values make it go up
subtracting or negative values make it go down
but i'm subtracting, not adding
Subtracting 1 should be the block below the player
I need to write a text file with common responses...
You should not read a config while the server is running. Rather read it once the server starts or a player connects (if its player specific data)
and store the data in properly named variables. Configs are there for persistence. They do not exist to be abused as data objects.
which event are you using? Playermove?
yes
Do you just add a Map<String, Object> to your classes or do you use proper fields?
Accessing those objects is error prone.
I would use Block#getRelative() instead
instead of using the getTo for the location, try getting the players current location instead. using event.getPlayer().getLocation()
I only say try that, because some things with the events
they haven't quite happened yet
from appearance it shouldn't make a difference but you never know lol
What are you trying to do here?
make a trail of blocks below the player
as they move
for some reason instead of the block going down using the subtract method it made it go up more?
add(0, 1, 0) gives the block above
They are using subtract
Thats why i would use getRelative. Its more concise.
Block below = event.getTo().getBlock().getRelative(BlockFace.DOWN);
That may work too
But i would heavily filter this event
That’s not going to solve it if the subtract is returning the block above
That means the getTo is messed up somehow
Try setting that block with no offset and see what happens
which is my theory
public void onMove(final PlayerMoveEvent event) {
final Location to = event.getTo();
final Location from = event.getFrom();
final int toX = to.getBlockX();
final int toY = to.getBlockY();
final int toZ = to.getBlockZ();
final int fromX = from.getBlockX();
final int fromY = from.getBlockY();
final int fromZ = from.getBlockZ();
final boolean blockPassed = toX != fromX || toY != fromY || toZ != fromZ;
if (!blockPassed) {
return;
}
// What happens if player goes from one block to another
}
That too
which is? like i said before i'm new
you have an error at the top. From should be getFrom
my idea was wrecked anyway. didnt know that most mobs dont even have heads lmao
They do with minecraft-heads
What happens if you set e.getTo().getBlock() instead of subtracting
Which block gets changed?
thx
yea but that would be a kind of complicated thing
i just wanted to make eggs craftable with their heads lol
Block below = event.getTo().getBlock().getRelative(BlockFace.DOWN);
This has to work
That’s the same as subtract
the one in te middle of the player
well it could be how the event works, I don't have my IDE opened to look at the implementation
Very interesting
Can you print out the coordinates of the getBlock() and the getBlock().subtract()?
Also you’re not jumping or anything right?
plain walk
this works
1.17
getTo gets the location at the players feet
weird that subtracting is essentially doing adding though
The issue is that subtract is adding
Lol
It makes no sense
only scenario I can think of for that happening is somehow a negative is getting in there
yeah... did he subtract a negative number? 😄
What version is he using?
1.17
Weird
I just looked at the stash and there weren’t any changes
that is if the player is already at 0
What?
I am aware of this, but if the server expects it to be positive at all times for y, this would cause some issues if it was absolutes
guys please
Version?
1.8.8
That would be a very specific bug lol
Lol
something weird is happening
lol
Unresolved reference: INK_SAC
the block gets placed and then it gets unplaced but for some reason also placed again
INK_SACK
indeed, but would only happen at y0 and it is possible that it has always been there just no one noticed since most people don't do much stuff at y 0 lmao
I knew that
The event fires every time they moved and you’re not checking to make sure they left the block
I would have to look later at the server code though
It could be a problem with the objects that are being used. Do changes to the Location
retrieved by getTo reflect to the game state?
but that is the only thing I can think of that would cause such a thing
I don't know of anything else that would
Mabye he just moves the player down
but i'm sure i'm leaving the block
You are
Here’s what’s happening
They move
You set it to gold and cache the old state to be reset after x time
Then they move again over the same block
You set it to gold and cache the old state, which is gold because you already set it
oohhh i see the point
Then you have it reset at x+1
Now after x it goes back to stone or whatever
And after x+1 it’s gold
this seems like a plausible thing too
since the location from the event is in relation to the player lol
how do i stop that from happening @brave sparrow ?
@midnight shore
This still doesnt fix the issue with revisiting
True
You’d need some sort of Set of blocks you’ve changed and haven’t reverted yet
my goodness all of this just for a dumb trail of gold blocks
Hm im cooking up something with a PriorityQueue...
Ok i stopped writing this. Way too spoon feedy. But this is actually not a trivial problem.
i'm trying using a hasmap
Some fragments:
private final Map<Block, RevertableBlock> revertableBlockMap = new HashMap<>();
private final PriorityQueue<RevertableBlock> revertableQueue = new PriorityQueue<>();
...
@RequiredArgsConstructor
private static class RevertableBlock implements Comparable<RevertableBlock> {
private long lastVisit;
private final BlockData originalData;
@Override
public int compareTo(@NotNull final SpigotSandbox.RevertableBlock other) {
return (int) (other.lastVisit - this.lastVisit);
}
}
Then polling every tick until current time is reached. Revisiting -> edit timestamp then re-insertion into PrioQueue.
😖it doesn't work
i see weird stuff there
im not really following what you are doing
what is a priority queue
and why it is not for example Deque used here
Done! it is working just pertect
PriorityQueue is basically that every element has a priority associated to it dovidas
is it something similiar to tree
with levels
also
due to how its sorted
isnt it a slow
queue
// Java program to demonstrate the
// working of PriorityQueue
import java.util.*;
class PriorityQueueDemo {
// Main Method
public static void main(String args[])
{
// Creating empty priority queue
PriorityQueue<Integer> pQueue = new PriorityQueue<Integer>();
// Adding items to the pQueue using add()
pQueue.add(10);
pQueue.add(20);
pQueue.add(15);
// Printing the top element of PriorityQueue
System.out.println(pQueue.peek());
// Printing the top element and removing it
// from the PriorityQueue container
System.out.println(pQueue.poll());
// Printing the top element again
System.out.println(pQueue.peek());
}
i found this example
output:
10
10
15
this means that it pulls values sorted by lowest values
Surly you just need a simple FIFO queue?
An unbounded priority queue based on a priority heap. The elements of the priority queue are ordered according to their natural ordering, or by a Comparator provided at queue construction time, depending on which constructor is used.```
i've just never seen this class in my life
an element with maximum ASCII value will have the highest priority.
maximum ASCII value is 255
theres a constructor where you can pass in a comparator
aah food on my keyboard
rip
why am i even eating here
its so weird
that highest priority values in PriorityQueue are not at the head of the Queue
Variable 'user' is accessed from within inner class, needs to be final or effectively final
smh this sucks
I mean, you would want to join the completable future if you need its value on the current thread
im in the async pre login event
Well then join the completable future ?
lets wonder what that does
it holds the current thread until the completable future is done
wew thats good to know
Or just use AtomicReference
dunno how creative an atomic ref is if you need the value afterwards
I think you could use WeakRef too however pretty sure that that will get GC'ed, but under some circumstances it might be a better option than a full blown atomic ref
Really depends on what FourteenBrush wants, if it’s to use the value instantly in coordination linearly to the snippet they are showing us a mere ::join might be sufficient, but yeah if he wants to store it in some reference non blocking definitely AtomicReference.
i want to load the user from the database and cache it after that
to log him in when the actually joins
i think thats better to do it in the playerjoin instead of asyncprelogin
I load them in the asyncprelogin
Maybe I shouldn't since they can still be denied access
hmm
Can't you check if the event gets cancelled?
heh?
Yes I could do that
Assume a lot players are spam joining
ah that way
I assume disallowing the login event does not fire the quit event
Probably not
Yeah probably not
Since quit likely happens when a player has joined already
Hmm, does it fire any event?
but whats an alternative then conclure?
iirc tho, disallowing the APPLE event won’t cancel execution of PLE or sth weird like that
I mean just load em in APPLE
now were talking about apples
I load data in the APPLE
Yaa
But If they get disallowed in that event, the data will stick around
Since the data only gets unloaded in the PQE
this sounds weird going from dos attack to apples 🤡
I searched YouTube and couldn't find any video showing just this scene, and everyone was saying Apple when prompted and was missing out on the dialog, so I decided to upload this myself.
var dto = repository.getOrMake(event.getUniqueId())
storageInterface.loadUser(dto).join();
or sth
the user object from the cache
if they join they arent in cache yet
Basically you have a cache object which is capable of creating objects on its own
Well the method would create a new user and put it into the map for the UUID given
not sure why you are wanting to do it on the prelogin, I would recommend login event for getting DB stuff, but it depends what exactly the data is and what it is for. If the stuff in the DB isn't to be used right away but is just needed for some things, then use the join event. If you kind of need it right away then best to do it at the login event. In either case make sure your DB calls are done on another thread.
and then return it
APPLE does not use the server thread frostalf
So assuming he is declaring a callback for APPLE, it should be fine
don't know what apple is
AsyncPlayerPreLoginEvent
^
Ah ok
public void loadUser(UUID uuid) {
User user = loadUserData(uuid);
this.userMap.put(uuid, user);
Bukkit.getScheduler().runTask(this.plugin,
() -> Bukkit.getPluginManager().callEvent(new UserLoadedEvent(user)));
}
That's what I do
an user object stores a lot of data which comes from the database so why would i create an user object when i dont know the values? and then load it?
in either case prelogin is a bit iffy for DB calls though, because a lot can happen where the player doesn't make it to the login event 😛
Well, your data mode shouldn’t be dependent on the storage implementation
How to set an item in inventory that is enchanted? thanks
It’s just architectural layering at its finest to some extent
Let me give you a class of mine
In my case I need to load the data that early, because I may disallow connection based on that data
I just need to make sure I somehow unload it if the player never makes it to the Join event and thus the Quit event doesn't get called
this is what expiring caches are good for 😛
FourteenBrush I see, it’s hard to explain but let me try
xd
Good idea
Wonder if an existing impl of that exists that expires every X seconds unless a condition is met
Guava has one
in is actually quite nice using it because you don't have to worry about it in the end if it isn't needed
the queue will take care of it once it expires 🙂
it expires when it isn't being used 😛
or you could have a pre-determined time to expire everything
If you just wanna check if the value is still be used
I'm pretty sure most caches support weak keys/values
yeah in guava it has a method to get it again if it expired in the cache
Yeah I want to expire if Bukkit.getPlayer(user.getUUID) == null
you could easily make a runnable to do that
check the cache for any non-valid things and then force expire them
but since the cache items will expire anyways at some point
to keep the cache up to date
you could just simply let the cache mechanism handle it
conclure do you mean that final fields in my case would be bad wo i better use setters to set stuff when loading the user
i better wont interrupt you typing the bible
Guava caches expire content when the cache is accessed. Thats also possible.
Unless you specify a scheduled executor
So usually we have certain classes which are serving the purpose of transferring data between two points (could be two methods, two classes or what not).
We then have a repository, or well a lookup map.
Thing is, in this situation we want to isolate the data transfer object itself from the repository. This is done by not letting the data transfer object know about the repository. However it is fine to let the repository know about data transfer objects, although make it minimal. For instance we could do sth like:
class UserRepo{
final Map<UUID,User> map;
final Function<UUID,User> factory;
Optional getIfPresent(UUID id):
yield ofNullable(map.get(id));
User getOrCreate(UUID id):
yield map.computeIfAbsent(id,factory);
}
class User {
final UUID id;
AtomicReference<UserSnapshot> ref;
void set(UserSnapshot s):
ref.set(s);
UserSnapshot get():
yield ref.get();
void update(UnaryOperator op):
ref.updateAndGet(op);
}
class UserSnapshot {
final SomeData;
final OtherData;
UserSnapshot(
SomeData someData,
OtherData otherData
)
//one of these methods for OtherData also
UserSnapshot setSomeData(SomeData d):
yield new UserSnapshot(d,this.otherData)
SomeData getSomeData():
yield this.someData
}
In this case User objects are able to live without a direct data fetch from your database
However that has many benefits
For instance testability
And the fact that your user isn’t coupled to the persistence layer / storage
When you update userdata here, it’s done atomically using User::update
(UnaryOperator<T> is just a Function<T,T>)
Anyhow
Essentially you also have a database implementation maybe something like:
interface UserStorage {
CompletableFuture<Void> load(User user);
CF<Void> save(User user);
}```
CF - completablefuture just lazy
Now assuming you might have a class MySqlUserStorage implements UserStorage (to implement the proper load and save)
This way you can load any user object at any given point of time, which helps with a lot of things in terms of testability and scalability
I think I just had a stack overflow reading all that
how do i get server tps as an int
my brain is hurting
Is getTPS exposed yet?
Maybe I should write a complete example FourteenBrush?
so i would save the actual data on the usersnapshot?
Cache it is a better word
(no)
essentially yes tho
The UserSnapshot is an immutable data carrier which represents the user data at a given point of time, it’s very nice and thread safe
In this way we reduce the amount of mutations (by having as said, a snapshot which we delegate all the data responsibility to)
?
but when creating an user, it should have a snapshot or it wouldnt make sense to make a user if you cant request data on it?
well, just instantiate a UserSnapshot and set it on the user?
So a user may exist with no data
Does someone know how I can fix this error? (Protocollib)
com.comphenix.protocol.reflect.FieldAccessException: No field with type [I exists in class PacketPlayOutEntityDestroy.
at com.comphenix.protocol.reflect.StructureModifier.writeInternal(StructureModifier.java:365) ~[ProtocolLib.jar:?]
at com.comphenix.protocol.reflect.StructureModifier.write(StructureModifier.java:345) ~[ProtocolLib.jar:?]
at me.katze.av.utils.VirtualEntity.destory(VirtualEntity.java:77) ~[av-0.1.jar:?]
at me.katze.av.utils.VirtualEntityManager$1.run(VirtualEntityManager.java:47) ~[av-0.1.jar:?]
at org.bukkit.craftbukkit.v1_17_R1.scheduler.CraftTask.run(CraftTask.java:101) ~[patched_1.17.1.jar:git-Paper-233]
at org.bukkit.craftbukkit.v1_17_R1.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:483) ~[patched_1.17.1.jar:git-Paper-233]
at net.minecraft.server.MinecraftServer.b(MinecraftServer.java:1559) ~[patched_1.17.1.jar:git-Paper-233]
at net.minecraft.server.dedicated.DedicatedServer.b(DedicatedServer.java:479) ~[patched_1.17.1.jar:git-Paper-233]
at net.minecraft.server.MinecraftServer.a(MinecraftServer.java:1475) ~[patched_1.17.1.jar:git-Paper-233]
at net.minecraft.server.MinecraftServer.x(MinecraftServer.java:1274) ~[patched_1.17.1.jar:git-Paper-233]
at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:319) ~[patched_1.17.1.jar:git-Paper-233]
public void destory(Player viewer) throws InvocationTargetException {
PacketContainer packet = main.protocolManager.createPacket(PacketType.Play.Server.ENTITY_DESTROY);
packet.getIntegerArrays().write(0, new int[] {this.entityId});
main.protocolManager.sendServerPacket(viewer, packet);
}
So you mutate the users data
In principle just the reference to the data snapshot
So you make a new DataSnapshot when you update anything?
Yep
but the Function<UUID,User> factory; might be something like User::new so when caching it for the first time, the snapshot will be null until the db completed to set it?
That doesn't seem ideal if you are updating stuff often
Myes
How so?
Lot of Object creation
Jvm handles that relatively good
Fair enough
i was just planning on doing stuff with getters and setters
Like this scales a lot better generally than having a big dto with a lot of volatile fields, which means you need to implement atomically safe methods for all of the fields
Technically my data is one field
Ah
Map<String Object>
🥲
It needed to be easy for addons to add new data to the user
Maybe not the ideal case then, like a ConcurrentHashMap directly in the User could be fine
Ye
When is a CompletableFuture not lazy?
Anyways FourteenBrush assuming you want to get some data then you could do sth like:
user.get().name();
And for changing the name:
user.get().name(newName);
And if you increment the points of a user:
user.update(oldSnapshot -> oldSnapshot.score(oldSnapshot.score()+1));
(Could probably write a nicer method to increment but everything here would be thread safe and atomically safe)
I realized something annoying in java recently
parseInt cannot throw a NPE, but parseDouble can
Good question, since I’m on phone I wrote CF as an acronym for CompletableFuture
How come :0
parseInt will just throw a NFE if the input string is null
Lol ye
parseDouble will throw a NPE if the input string is null
Interesting inconsistency
hmm ill take a closer look at it
Yeah, ofc you could go with classic setters and getters, but it’s just that you’ll run into some pretty devastating issues when the plugin scales
🥲
This is why I still use Java 1
Let’s remove JDK from JDK
is that even something jdk1
No idea
When you do PlayerInventory#getContents does that include their armor?
well thanks for helping me somewhat further tho 🙉
how do you get a BukkitRunnable to stop repeating
.cancel()
TechLewi you basically call cancel() inside run, or if you reference the BukkitTask object, invoke/call cancel() on that.
Or get its id and tell Bukkit to stop the task with that id
thanks, real quick any chance you know how to get the consoles response from a command ran by the plugin
Why would you want that?
because i dont want to dive into NMS yet and i need to get the server TPS, an alternative is to run the /tps command in console and get the response
That is even more janky IMO
lol
?scheduling yeah btw
Implement a custom CommandSender and let it dispatch a command using Bukkit.dispatchCommand()
TechLewi not sure exactly
I can PR a double[] getTps
Like there are some ways of doing it
But IDK if MD would accept it
Though, none are perfect
well i can get the double of tps with
MinecraftServer.getServer().recentTPS however when converted to a string it gives me [D@73601f1d
@RequiredArgsConstructor
public class ScrapingCommandSender implements CommandSender {
private final Consumer<String> messageConsumer;
@Override
public void sendMessage(@NotNull final String message) {
this.messageConsumer.accept(message);
}
... and a ton more
Then something like
Bukkit.dispatchCommand(new ScrapingCommandSender(System.out::println), "/help");
Bukkit.dispatchCommand(new ScrapingCommandSender(msg -> doSomething(msg)), "/help");
hmm
Although you still gotta parse the string output
And then worry about servers with different outputs
This can be used for example if you have a plugin that has a toplist in chat but no hologram support.
Just fill a hologram with the chat response ^^
Used this way back when i still used plugins from other people 😛
lol, i appreciate that however i think i just found a way by mistake lol
how to get the view in InventoryMoveItemEvent?
Click
InventoryClickEvent is generally the answer for anything to do with items in inventories
ok thanks
How do I make an itemStack by an itemMeta?
ItemStack#getItemMeta
The ItemMeta does not contain the Material. So you cant just convert an ItemMeta to an ItemStack.
Hello, I've been googling now for absolute ages. If someone could help me out with an issue, I'd be soo grateful.
?ask
If you have a question, please just ask it. Don't look for staff or topic experts. Don't ask to ask or ask if people are awake or available. Just ask the question to the channel straight out, and wait patiently for a reply. Make sure you use the right channel regarding the topic of your question. Create a thread in case the channel is already in use!
NamespacedKey randomKey = new NamespacedKey(this,"ieyyyysssds");
ShapedRecipe randomRecipe = new ShapedRecipe(randomKey, Items.getJoint());
randomRecipe.shape(" P "," D ","LLL");
randomRecipe.setIngredient('P', Material.PAPER);
randomRecipe.setIngredient('D', Material.DIAMOND);
randomRecipe.setIngredient('L', Material.LEATHER);
Bukkit.addRecipe(randomRecipe);
What is possibly wrong here
What lets you think there is something wrong here?
Since I can't craft it 😄 (Spigot 1.16.4 btw)
Show the whole code and a screenshot of the crafting table pls. This looks fine to me.
?scheduling
Idk what code part you want, the Items.getJoint()?
Why is there an iron ingot?
Iron ingot != paper
Show the method where you register the recipe in
Hm. Does your plugin come up as green when you type /pl ?
Yeah, a lot of other stuff I've written in the same Core plugin works. It's just this part
Did you forget to compile the plugin and add it into your plugins folder?
Add a debug message after each recipe and check if its displayed in the console pls.
Add a debug message after each recipe and check if its displayed in the console pls.
It's in the onEnable() Ofcourse it will show 😄
*If no exception is thrown before that and you actually copied the compiled jar
And you are sure that you joint your local server?
Yeah 😛
And no exception is being thrown at any time?
Damn drug propaganda in minecraft
None
So it's not just me being crazy xD
I've done thousands of recipes, now all of sudden it's not working. Super weird
Where did you get your server jar from?
BuildTools
You are more than welcome to join the server and test xD
I have no idea... Lets throw some random fixes at it.
Register the recipes 4 ticks later.
@Override
public void onEnable() {
Bukkit.getScheduler().runTaskLater(this, () -> {
// Register recipes here
}, 4L);
}
Alright, Ima just test to run the server with only my plugin
Ah important: Never reload.
You should always do that when developing your plugins. Have a local minimal setup with just your plugin and its dependencies.
I am 😛
Now I'm removing the dependencies for my plugin
Still nada
Ill try to delay it
Delaying it didn't help either
listen for the PrepareItemCraftEvent and check if getRecipe returns null.
Let me guess. Now it works.
So...
But it realises the recipe is there o.O
Either the result is null or another listener sets the result to null
?scheduler
?scheduling
@ivory sleet would it make any sense to replace an entire usersnapshot instead of using the getters and setters?
Print out Recipe#getResult() in the craft event
I actually already tried what you're suggesting. I changed to a vanilla item instead of a custom
Imo yes fourteen brush
*If recipe is not null
ah on an user object creation
Wow that was a tiny picture xD But the result is the actual Itemstack
Well then another listener is tempering with the PrepareItemCraftEvent
Wdym?
Why would it be?
Set the result to null or something... no idea why-
Maybe recipes with permissions.
Are you op?
Yeah
🤷
Hi, how do i update plugin from 1.17.1 to 1.18? thanks
just change the version of your spigot dependency
Anyone else wanna have a go why this doesn't work? :3
did you test if the recipe exist and gets it shape and so on from the api after adding it
How do i do that?
using maven?
yeah
I mean, the console reacts to the recipe from PrepareItemCraftEvent so
change the version in your pom and reload it
ok thanks
i would try setting up an runnabl the prints every tick the result slot
maybe its changing but not vissible or its changing but get deleted directly
Interesting idea. I'll try it
do bukkit itemmeta objects use NBTTags internally?
Nothing is literally changing ;-;
There is noo way... This is NOT working 😄
private NBTTagCompound blockData;
Yes it does
its a wrapper
i made nbt serializer for ItemStacks
its more user friendly than using yaml tags
No
Well, it stores the nbt. However, modification method like setLore does not touch the tag
Yes. It just reads the compound tag, not actually wrapping it
@Overridden
int applyHash() {
int hash = 3;
hash = 61 * hash + (hasDisplayName() ? this.displayName.hashCode() : 0);
hash = 61 * hash + (hasLocalizedName() ? this.locName.hashCode() : 0);
hash = 61 * hash + ((lore != null) ? this.lore.hashCode() : 0);
hash = 61 * hash + (hasCustomModelData() ? this.customModelData.hashCode() : 0);
hash = 61 * hash + (hasBlockData() ? this.blockData.hashCode() : 0);
hash = 61 * hash + (hasEnchants() ? this.enchantments.hashCode() : 0);
hash = 61 * hash + (hasRepairCost() ? this.repairCost : 0);
hash = 61 * hash + unhandledTags.hashCode();
hash = 61 * hash + (!persistentDataContainer.isEmpty() ? persistentDataContainer.hashCode() : 0);
hash = 61 * hash + hideFlag;
hash = 61 * hash + (isUnbreakable() ? 1231 : 1237);
hash = 61 * hash + (hasDamage() ? this.damage : 0);
hash = 61 * hash + (hasAttributeModifiers() ? this.attributeModifiers.hashCode() : 0);
hash = 61 * hash + version;
return hash;
}
wtf is this
it seems like metadata version flag or some sorts?
i am using lombok to simplify my development process and i the SLF4J logger in lombok is not outputting anything to the console, is there a way i can attach lomboks logger to the server console's one
Well the server logger uses Log4j, not SLF4J.
You'd probably need to import the SLF4J binding.
It's probably trying to call a method from a newer version of Log4j
(We don't support 1.8 anymore btw)
case in point
They use this version of Log4j
lombok moment
so what version of the binding do i need
hey @ivory sleet would i do my caching stuff in the userrepo class too?
How does your user repo looks like?
2.0?
basically yes
repo/lookup/caching manager/glorified map whatever you call it

I like Glorified Map
@lavish hemlock it doesnt error out but it says it failed to load class still
Hmm shit
i think my current cache interface isnt enough
czn u give a link
the implementation is in the same package / cache
https://github.com/FourteenBrush/MagmaBuildNetworkReloaded/blob/master/src/main/java/me/fourteendoggo/MagmaBuildNetworkReloaded/storage/Cache.java
wait @lavish hemlock the scope was just set to test, it initialized now and i get this error:
java.lang.NoSuchMethodError: 'org.apache.logging.log4j.Logger org.apache.logging.log4j.spi.LoggerContext.getLogger(java.lang.String)'
but the method exists
org.apache.logging.log4j.spi.LoggerContext.getLogger(String name)
@ivory sleet
how can i get an bit of code to sleep for x milliseconds
run it on another thread and call Thread.sleep(millis) on it maybe?
Whats the xy
hmm um well i have a bukkitRunnable which repeats every 5s but if tps is less than 15 then the runnable will cancel and the server will restart broadcasting at custom intervals?
??
Can anyone explain to me how to do queries or edit multiple regions at a time with worldguard/worldedit?
BukkitRunnable run task timer (1, 20 *5) probably
what are you trying to do
I'm asking here because I can't really search the forums for it easily. (keyword function will talk about java functions instead of datapacks)
I'm making a simple plugin that has a custom command to run the vanilla /function command to run a datapack function
I know this isn't the best way to do things, but I'm low on time so I'm just adapting the datapack. Is it possible to do this? If so, it feels like it would be a single line of code solution.
Sorry if this is bothering
I need some help if anyone wouldnt mind
so i rewrote all my code to one of my plugins and now when i toggle it, it always says [Plugin] Toggled "on" (it doesnt toggle off) also it doesnt do what its supposed to do (its and autosmelt plugin so it wont smelt the blocks just drops the ore naturally) all other commands work as intended. ALSO ive ran debug messages for each block and it is identifying the blocks correctly without error, just not smelting as intended
Bukkit#getConsoleSender#dispatchCommand iirc
isnt /function vanilla so you cant override the behaviour?
I want vanilla behavior
They don't want to
Just need some way to call it within a plug-in. Thanks
Ah that isn't even it
its an autorestart plugin where when tps is lower than a certian amount it will restart the server, which you can set broadcast intervals about restart in a config, but i need to sleep the code or something or just get it to wait for next broadcast interval
Use bukkit scheduler
It's Bukkit#dispatchCommand(Bukkit#getConsoleSender, <command>)
Sadly there's no datapack api present at the moment
Who speak spanish?
can i use a scheduler within a runnable?
This server is English-only.
yes
oh ok
hola is that spanish?
Thank you
Yeah
Pero si puedes entender más cuando alguien te escribe más texto mucho mejor
ah yes yes english only
wait so i would create a scheduler within a runnable and another runnable in the scheduler
The meaning Is please
ah
how do i get the existing config for the logger so i can use it in another program without it looking like this:
https://gyazo.com/f510b34196a79e589ac4315ab5aa7efe
I can understand a little that speak here but i have only basic english level
Why don't you use your plugins logger?
well im using a utility i made that makes my plugin more optimized and i use lombok for logging in that util, and i need to port the plugin logger config into the lombok logger config so it doesnt look like your logging a logger
just read this but i dont see how to implement it into my current code can i send it in a paste bin
How I can connect the Twitch API that to send message when a streamer is on a live?
the api will tell you
oh finally
i can see this channel
Hey guys, i'd like to ask something
Im trying to make a plugin which allows you to see your last 5 kills in sword lore.
The problem after 5 kills it stops registering kills in sword lore. (Thats because 5 line is allowed)
How can fix this? Where should i start?
Delete the oldest one
well i have think about that but i couldnt make it properly
Can you point me where should i look at for this?
I would keep the last 5 names in the PDC and then modify that first, then use that to update the lore
That way you can remember which lore lines need to be changed
i meant it as a link but thank you so much ur help
and your time
have a nice day/nightr
[Server thread/ERROR]: Could not load 'plugins\mcPlugin.jar' in folder 'plugins'
org.bukkit.plugin.InvalidPluginException: No public constructor
Im getting this error and im not quite sure why.
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.plugin.java.JavaPlugin;
class Base extends JavaPlugin {
public Base(){}
@Override
public void onEnable() {
Bukkit.getLogger().info(ChatColor.AQUA + "onEnable" + this.getName());
}
@Override
public void onDisable() {
Bukkit.getLogger().info(ChatColor.AQUA + "onDisable" + this.getName());
}
}```
This is all i have so far with my plugin.yml like this
```yml
name: JansFirstPlugIn
version: 0.1
author: MrUnkn0wn
main: Base
and this as my project strukture
nevermind cant send screenshots :x
forgive me if this is a stupid problem its my first time creating a plugin
i guess "main: Base" this is the problem
i thought so too but when i changed it it instead told me that it cant find the class
you should use the whole class name
so as far as i can tell it is finding the class atm
then you should add the class name at the end