#help-development
1 messages ยท Page 350 of 1
why can't Player#sendBlockChanges work with a BlockData too?
BlockData + Location
Because it has no position associated with it
then make the user apply a Location
make a map<BlockPos, BlockData>
You're welcome to PR
anyways I'll literally just copypaste you the code
wasn't there even a CLA thingy with spigot contributions? lol
and you can just PR that
No, that's not how the CLA works
I can't contribute code I don't own
gplv3 go brr
Doesn't matter
a
uhm guys
this is not gonna fix my problem rn lol
I'd love to see a method for sendBlockChanges with a BlockPos + BlockData
I don't think you're going to see any noticeable performance gains from a Map<Location, BlockData> though tbh
I will
tbh, probably worse
It seems you're trying to set an astronomically large region of blocks
because then I do not need to get thousands over thousands of Blocks from the World per tick lol
well try it and seel
Map and bucketing seems terrible
Yeah, see that's the problem lol
you don't need to index anything
im seing these insane performance drops with 6000 already
6000 
You think a Map with > 6k entries is going to be better?
is NMS obfuscated now? cuz I can't find a solution to have a backup/default fallback of my methods
At runtime, yes, nicuch
is there no other way to do implement a sendBlockChanges method with BlockDatas and some positioning?
I've worked A LOT with fake blocks
and can assure you this is a better solution performance wise
idk what what world a Map<Location, Something> is ever better
Let's assume getType costs you maybe 300mu
do they have different names for each version?
that can break everything
Yeah, mappings change from version to version
any way to automatically detect a few classes and methods?
Better than using the existing impl which fetches block type from the palette for every entry
ye
but that is not the issue in that impl
the issue is that you cannot create a BlockState on demand
without fetching it from a world
^
How can i place doors?
Map<Location, BlockState> is worse in every way that matters for this than a List
wouldn't that be good?
lol
insert is worse, iteration is worse
List<WrappedBlockData> maybe
memory is worse
why wrapped block data
what is the point
the server already issues non world placed BlockStates
it's just a record of Location-BlockData
See BLockStateItemMeta
why not just create a Wrapper for on-the-fly blockstates?
Alternatively, World#createBlockState(Material/BlockData, x, y, z, @Nullable Consumer<BlockState>) might be a viable solution
BlockState is a wrapper of Location/BlockData
that is the entire point of that type
Hmm
why Consumer<BlockState>?
I want to separate this blockstate
why
Convenience for general use case
aren't BlockState kind of static in the code?
no
Like how #spawn() accepts a Consumer<Entity>
or maybe a createBlockState(BlockData, Location) method hm
yes
yes plz
How, where would that come ๐ค
creating a secondary type that does literally the exact same seems useless
World ideally
RegionAccessor 
what about that?
Could be under Server or Bukkit. idrc. If you're passing a Location it has a world
Ye
Block states have a world associated with them, no?
yea
yes
Right but think of the general use case
BlockState#update() should still be possible
spigot maintainer team can decide
ยฏ_(ใ)_/ยฏ
I wonder what the CraftBlockState int flag does
help plz.
ERROR] .... Could not pass event PlayerInteractEvent to mains.VanillaCustomItems v0.1
java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because "time" is null
at events.Events.onRightClick(Events.java:26) ~[VanillaCustomItems-1.0-SNAPSHOT.jar:?]
at
(only some of the error, not full thing)
I know time is null, but I tried to make it not null, but its null in that so it can't make it not null.
line 25:
Integer time = map1.get(Integer);
line 26:
if (time > 0 | time < 0);
how do I make it not null, but also let it later be set to an Integer that won't be overwritten? plz help
so whats the TLDR now?
also use || instead of |, as it does some micro optimization
if(methodOne() | methodTwo()) executes both regardless if methodOne returns true
really?
yes
you guys gonna PR a createBlockState(Location, BlockData)?
tbh i never even known you could use | instead of ||
i didnt even know single | exists
thought | was only for catch statements
should you use || in catch statements as well then?
no
u cant right?
The flag in CraftBlockState is to do with the type of update to perform when setting the block in the world. You can set it to 3 as that's the default iirc
Or more appropriately, there are constants somewhere
It's like update light | update physics or something
this has everything needed in a BlockState, no?
it should
then why don't create that? xD
so would i do/be able to do this?
if (time || time);
else {
time = 0;
}
to get around time being null?
Again, I still don't think this is going to have the noticeable performance improvements you think it's going to have. Unless you benchmark internals, I'm not convinced
You still have to create those BlockState instances somehow
That's not the problem, strictly
The problem right now is that we fetch data from the world and then override with our own
fetching data from the world takes time and is wasteful, we could just create the object with out own data to begin with
its literally 100000000000000x more performant to create the Object with the data instead of getting it from the world which takes until I am a grandpa
Little bit of an exaggeration lol
While that's just one of the many issues, it's still completely crazy to needlessly create hundreds of thousands of these wrapper classes to just later be collapsed into chunk-segmented multi-block update packets again. Scattered heap allocations, good for nothing.
At this point I just want to advise @orchid gazelle again (xD) to create an application specific implementation for this pretty seldom use-case of block updates.
best if condition seen today java if (((regex.length() == 1 && ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) || (regex.length() == 2 && regex.charAt(0) == '\\' && (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 && ((ch-'a')|('z'-ch)) < 0 && ((ch-'A')|('Z'-ch)) < 0)) && (ch < Character.MIN_HIGH_SURROGATE || ch > Character.MAX_LOW_SURROGATE))
I had initially proposed a Consumer<BlockChangeDelegate> which would have avoided most of that, but the implementation was significantly worse as a result
would methodOne and methodTwo be time? or what, im just trying to fix the error to stop time being null temporarily
It's also awkward to work around a Consumer
public class CustomBlockState extends CraftBlockState {
public CustomBlockState(Location location, BlockData bukkitData) {
super(null, new BlockPos(location.getX(), logation.getY(), location.getZ()), ((CraftBlockData) bukkitData).getState());
}
}
Please don't make a child class
and yes you need to create this class to use the protected constructor
or just make this one public
I want you to try that to see if there are performance improvements. Again, I still don't think there will be
At least nothing significant
@orchid gazelle benchmark time
Yeah, no, I'm more thinking about cached packets with direct write into the block positions and the one combined ID field. That's all a block update really is. You'd have to segment into chunks ahead of time and when moving the virtual schematic they want to draw, check whether chunk boundaries actually changed.
Maybe it would be more performant to just send individual block updates, as the whole overhead of segmentation probably doesn't help that much. Would be something one needs to benchmark to find out.
use this class
stick it in your thing
and measure the improvement
Gimme 1sec
The client would need to process a lot more packets
it has a network overhead
@echo basalt
It's a tradeoff. Depends on where you want to do the work. Again, it's not that trivial to judge this and would very likely need some end to end benchmarking.
uhh
It's the nms blockstate btw
3rd param
uhh
craftbukkit != nms
yeah
here
I know
you're creating a CraftBlockState and passing an NMS blockstate as the 3rd param on the constructor
BlockState org.bukkit.craftbukkit.v1_19_R2.block.data.CraftBlockData.getState()
i hate how there are so much full paths
uhm
why are you using CraftBukkit?
oh
I am not passing any nms things rn
oh wait am i
well, the constructor works lol
and now im gonna create the object and pass it to sendBlockChanges?
yea
just map each block to a CustomBlockState and send the thing
if it yells about world
I'm not sure creating a state by CB is going to be faster that reading one from the world
just pass the world instead of null on the 1st param
The thing is
BlockState blockstate = new CustomBlockState(new Location(player.getWorld(), block.getX(), block.getY(), block.getZ()), block.getBlockdata());
``` like that?
every time you call getBlockState it creates a copy anyways (and that copy then fetches the block type and all)
yea
building
yes a state is always a copy
But creating your own from scratch is by definition faster than creating it from read out data, xD.
basically we want to create a block state with pre-set block data
bro lol
instead of fetching an snapshot from the world, changing the data anyways and sending
'time' (Integer) is null, but it won't let me check if it is null
And it can be fully async, as you don't need to read from the world anymore. It's still far from what I think would be optimal, but it's most definitely better.
isn't that 894mu?
wait
1000 mu = 1ms
its 0,8ms
Those are ns
@worldly ingot that's a decent improvement
btw. Illusion ty for giving me code I can use now XD
ah and, its even a little more since passing the Blockdata from the custom block object takes longer than just having a static Air Blockdata
still too slow but better xD
wdym?
is it mapping the blocks
thats the full time im debugging:
public static void showRendered(Player player, ArrayList<SchematicBlock> blocks) {
if(blocks == null) return;
ArrayList<BlockState> states = new ArrayList<BlockState>();
for(SchematicBlock block : blocks) {
BlockState blockstate = new CustomBlockState(new Location(player.getWorld(), block.getX(), block.getY(), block.getZ()), block.getBlockdata());
states.add(blockstate);
}
player.sendBlockChanges(states, true);
}
the sending or iterating you mean?
imma debug that real quick ok?
decent enough
is?
is by doing it all yourself in a single loop
uhm
instead of converting it using NMS and letting bukkit organize it again
thats gonna take me forever if I do that lol
this is probably gonna be a problem
Whats being tried here?
you just need to put that into packets
because I want way more than 6000 blocks lol
guy wants to send multi-block-change in big amounts while retaining performance
never worked with Packets
If its a LOT. Just send chunk packets. Editing is quite hard but its very fast.
I am doing that async already
I honestly find doing chunk packets async to be a bit... slow
then I should not do it?
you could
try and see
thing is I've once done interception to inject "fake" blocks into chunk packets
What would be the advantage of a chunk packet over a multiblock update packet? Isn't the latter just a differential update instead of sending the whole chunk again?
and had some weird performance issues because fetching blocks from the palette would take anywhere from 0.1ms to 50ms
lol
I got an idea
would it be more performant to calculate which blocks are on the outline of the multiblock?
and only send those?
Number of packets being sent is way smaller -> Every packet needs a header
calculate changes yeah
oh wait thats dumb nvm
Only works if the rest is actually being shadowed. You're gonna have to get into maths again, lol
if you're sending a big square you only need to send the blocks that are actually being changed
so the middle blocks would probably not be sent
that's a bit painful to impl
ehh thats a lot just for edge-cases
computationally expensive type deal
its mostly not senseless fills of blocks lol
Wait, is it? Are you talking about modifying existing chunk packets or sending custom made ones? Because if I'm not mistaken, the PacketPlayOutMultiBlockChange updates an equally large area like the PacketPlayOutMapChunk does.
let me check
I think it's just the differential version of it. But I'd love to know, thanks for checking, was just about to!
how to disable players' movement temporarily in implements CommandExecutor
MultiBlockChange after 1.16 updates a single chunk section
MapChunk sends all non-empty sections from bottom->top
Max out jump boost and set the players movement speed to 0 via a multiplicative scalar mod with a op value of 0.0
But you should probably approach this with a manager
setWalkSpeed(0) go brr
@echo basalt will it be faster when implemented into spigot actually?
or add some attribute, which is safer
pretty much
Of what an improvement are we talking of
same as what you're already seeing
implementing it on spigot is basically what you did
Wait, chunks are segmented again? Is a section a y-slice?
always have been
each section is 16x16x16
aka 4096 volume
you can represent each block position in the section with a single short
Few nanos probably, as you could get rid of the super call in the base class, who's only purpose is to access the inaccessible constructor without the overhead of reflect.
Let's say that the heightmap says the highest block is always 128
the mapChunk packet will only send the first 8 sections
Is its gonna get PRed now that Choco saw that its a serious improvement?
idk ask him
Okay, nice, learned something new. So I guess when sending multiblock updates, you have to segment even harder... But it's probably still better than polluting the network with a thousand little packets. Not that their header is significant, but networking overhead is.
Ok
I mean
You are right the ClientboundSectionBlocksUpdatePacket is probably faster. Its already a multiblock change in a single chunk.
the Single block change packet
has 2 fields
- long: Block position, as a long
- varint: blockstate id in the global pallette
on top of the packet id
Yeah, that's what I guessed, I never did chunk manipulation before. Thanks for looking at it again! :)
I think that cached packets with all wrappers already instantiated and just modified in place would be the absolute fastest you could get. You'd just have those slices prepared and only patch them before sending.
Why does mojang use 20 bits for a y coordinate? ...
In contrast, each multi block change packet has:
-
long: section position index, as a long
-
boolean: suppress light updates
-
long, containing the state id and the position, for each block
because the other 12 bits add up perfectly to 4096
What do you want to say by that? That it's not that big? I mean, again, it's not at all about byte size here, it's totally about the overhead of carrying that packet through a big number of buffers all throughout the world from computer A to B. Also, heap scattering again, the computer (server and client) just cannot process them equally as fast.
you only need 12 bits to represent where the block is at, in the section
JEEZ 200FPS while rendering 6000 new fake blocks every tick lmao
They use 22 for x and z respective and 20 for y
Last time i checked mc worlds cant go beyond 2k or something
cmooon why is this lagging?
I guess it's for future-proofing?
I've done the same with air-undos and its still lagging like shit @echo basalt
Been there. Had a server where you could ride ships and the waves would be animated.
Can be done completely async but we noticed a big bottleneck for many players: Bandwidth
yeah welcome to multi block change
Does anyone know how to make EssentialsDiscord send a embed message when a player joins?
Well, where's that excerpt from? If you have the bits available, you might as well use them, I guess. Not sure if it could have been packed any tighter.
Ouch, that makes me fear the networking bottleneck of my current project a bit, xD.
I would just go 24, 24, 16
65k blocks in height sounds reasonable to me and minecraft worlds can grow quite a bit into x and z
Our server had 1 Gbit mirrored which was more than enough. But some people just had
a bad connection...
yeah you gotta watch out for bandwidth
server I worked for was sending like 80mbit worth of particles to each player :p
DoS over minecraft ๐
made a very simple culler that worked directly on the network thread
went down to like 400kb
Idc about that for now since the function is only for builders rn anyways lol
Yeah, that's what I was getting at, the client's bandwith. The server should have an ample amount of that, or you should switch providers, xD. Can you just estimate what kind of sizes you were talking about with your project, so I can get a feeling for what's acceptable?
Server 10Gbit should be enough lmao
Sry this was way in the past. But in the neighborhood of mb/s
But we also approached this very naively. Lack of experience
Oh, I'm doomed then
oh god
Well, whatever, people gotta afford proper internet these days
0,2
haha mobile data go boom
Noice. But that should be fine, right?
5 * 8 * 128 * 128 * 30 = 19660800 = ~19MB/s at 30fps (worst-case). Of course I'd only update when it's needed. I'm planning on hosting web-guis in there, so 30 frames is an overkill anyways.
How are you streaming this? Whats your backbone? Kafka? Or Redis?
WebRTC in the browser which approximates the image down to frame colors using webassembly, then sending it over a socket to my plugin which segments into cached packet's buffers and sends em out
Well 30 fps on a 20 tick/s update loop is also questionable ^^
compression go brr
Segmentation is currently as fast as 0.0xms, web assembly is still choking a bit
I'm running in a new thread, haha
you could render the frames on the computer that's streaming, no?
I do, read the webassembly part
Ah interesting so this is handled completely disjunct from the main thread
that way you're only sending 1 byte / pixel instead of like 4
Does the minecraft server compress it? And it can't compress around frame borders, as it's not aware of bigger areas and has no notion of an image.
Exactly, it's funny that the client can even draw map updates this fast, haha
now
That's what I'm doing. I'm sending a compressed color lookup table to the client, expand it with gzip to a byte[1<<24] to have O(1) approximation speed and only send the number of bytes
what if you make it 2-way
and like
clicking on the maps
actually clicks on your pc
๐ค
possible
That's the whole plan
and then make a public server and let everyone click
But the browser is gonna be in a VM very likely
and pixel detection is a pain
yep, also gonna do that
Talk about multi-cursor support, :).
This project really goes right to the edge of what can sanely be done on a server with many people. You literally gotta optimize the hell out of it.
anyways I'm starting to get the motivation to work on this stuff again
thats pretty cool
I've done that before, yeah
Yeah, I know these. But most of them use custom GUI frameworks. I think that's stupid and want to stream a headless browser.
I want my new system to support abstract shapes
also there is a bug that lets you rotate maps
how to execute method every 30minutes?
but you can't position them in the middle of a block which makes it look really bad
That's great to hear btw, love me some competition! :)
Which is being rendered completely useless by integer based positions.
Man my mc folder is full of unfinished projects which had a pretty decent start 
Continue them then lmao
I work on stuff like that too
i have the same issue lmao
but much stupider
You don't want to know how many soft- and hardwareprojects I've trashed over time
i lose motivation and quit the project xd
how to i set the command doesnt exist message
Anyways let's see
one of the config files. Bukkit.yml i think
how can I estimate a boundingbox based on just the direction it's facing and the block the top left corner is on ๐ค
this is mod ?
Nope all done server side
with resoure pack
Nope
No resource pack
Its magic
wait how it work then on maps but side arrow
?
is on maps to
Yes those are invisible maps
so they can be transperent
how to execute method every 30 minutes?
Map colors 0x00-0x03 are rendering transparently and either show the frame behind or the world, if the frame's invisible, yes.
Jup this is all abstracted away. Its a bit like swing. You have a canvas to draw on
and a bunch of abstract widgets with events. Like a button where you can register
hover and click actions.
How would I remove an objective at a score
like: If I had Online: 1 at the score 3. How would remove it?
How can i check if a block is interactable in the interactevent because using Material#isInteractable() the ide says that it doesn' t exist the plugin is for 1.12
haha bad code go brr
theres this in the spigot.yml file but it doesnt work
unknown-command: Unknown command. Type "/help" for help.
(this is for scoreboards btw)
sounds intresting on one hand and complicated in other hand
imagine having actual alignment lmao couldn't be me
๐
Every block is interactable
Not at all complicated to get it working if you're comfortable with abstraction, but it requires quite the attention to detail to optimize it and not get lost in inefficiencies due to your abstractions.
So umm, 'player1' is null but I tried to set it to the player but it is still stopping at line 32 saying that 'player1' is null, before it can get to the part setting it as the player.
lines 32 to 38:
Player player = event.getPlayer();
String player1 = map1.get(Player).toString();
if (player1 == null) {
player1 = String.valueOf(player);
} else {
player1 = map1.get(Player).toString();
}
How could I get it to go to the if and else and not just give an error an stop?
bruh
Here are some links to get you started on learning Java:
- https://www.codecademy.com/learn/learn-java
- https://www.sololearn.com/learning/1068
- https://www.learnjavaonline.org/
- https://programmingbydoing.com/
- https://docs.oracle.com/javase/tutorial/java/index.html
The last one is the only official one, however some of those concepts assume that you already know a bit about programming.
Well then the player is not in the map. Also why is your variable named Player with a capital P?
Ah and Illusion, is there any other optimization I can do on my faking blocks?
- get(Player)
- Player#toString???
is this private project or you got it on github?
Cache
Closed project behind NDA, sry
Caching? They are on different positions every tick
how do you get the server to run in intellij?
Should it be lowercase?
gradle plugin
u can do without
But you can cache the block data with its relative position
could I possiblity get the link?
Should I have to put value as milliseconds to delay?
Well, blockdata is stored in custom Objects
you can literally just make your buildscript run a command after compiling
ticks (as the javadocs state)
1 tick = 50ms (ish)
AH
Yes
Um
that command can be a script that copies the plugin from your libs folder to a server folder
(With optimal performance)
and starts the server
20
yeh
Can you explain further? Blockdata is in a custom block object
Give your schematic an anchor point and every block in it a relative position to that anchor point.
Then you can reuse the entire schematic as it is and only need to add the current position
of the 'display' schematic to each relative block positon. You can even reuse the packet. You just need
to change the right bytes which contain the new position
Oh my god, finally somebody else who gives this kind of advice.
Hm?
๐
I'm a Never Nester and you should too.
Access to code examples, discord, song names and more at https://www.patreon.com/codeaesthetic
Correction: At 2:20 the inversion should be "less than or equal", not "less than"
Changing the right bytes is gonna be a bit of a pain tho, xD. It would be great to not have to copy anything at all and completely work in one source. Like, have the packet data point at your schematic values (which is impossible), or just work off of the packet slices.
Ah, nothing, you just don't see people who actually understand computing everyday here, it's a relief. Others would ask a factory to create a wrapper for them, while you propose reuse of packets and wrappers, xD.
Yeah you will have to put in some work before its usable ^^
mm lovely none of these line up
no result ๐
that's my brain when I'm looking for an explanation
minecraft's snapping doesn't match mine
I guess my first objective is to estimate what blockface it's actually going to snap to
Im doing the first part already but yeah
"Just need to change" ia easier said than done lol
I had the plugin print 'player' and 'player1' to the console and they both are the same just its not executing the event?
I've got a question about encryption if someone is familiar with it.
I want to encrypt a file with a password using AES. For the key generation you have the salt which has to be same for decryption - same for the IV. So is it just fine to store salt + IV together with the encrypted data? Everything else doesn't really make sense to me. Want to be sure tho.
alternatively you can also hardcode the salt
or depending on the usecase the salt can be something inferred from something else
storing the salt in the same file kinda makes the salt pointless
what event causes redstone to change shape, cancelling blockphysics prevents redstone lvl from changing but not the shape, and also fences and similar stuff
Why is my plugin not doing the event? The final 2 things are equal ( 'player' = 'player1' ) in an if statement and it keeps going to the else...
part of the event not working correctly:
if (player.getName() == player1) {
player.sendMessage("gooooooooooooooooood!");
double maxhealth = player.getMaxHealth();
player.setHealth(maxhealth);
player.sendMessage("ยงcYou've been healed!");
map1.put(String.valueOf(Integer), Integer.valueOf(Math.toIntExact(currenttime)));
} else {
player.sendMessage("problem with player names, idk but ig they dont match or smthn..");
}
console print to confirm:
[INFO] .... [mains.VanillaCustomItems] [STDOUT] player = CraftPlayer{name=amazingmation} and player1 = CraftPlayer{name=amazingmation}
ive been working on this all day ๐ซ
You have to compare strings with .equals, not with ==
The == just compares the two objects addresses in memory. Strings are immutable (any operation on a string will return a new string and that new string will have an own memory address), thats why you should always compare with .equals because its comparing the content of the string, not only the addresses in memory.
is this right:
if (player.getName().equals(player1)) {
Yes, if player1 is a string
yes it is
If player1 is a Player then do: if(player.getName().equals(player1.getName())
then this is fine
yeah its not a player because it doesn't let me do .getName() after it
๐๐
sure
what event causes redstone to change shape, cancelling blockphysics prevents redstone lvl from changing but not the shape, and also fences connecting and similar stuff
Can you send the complete code?
ye
this mf is just copypasting his question
heres a pastebin: https://paste.md-5.net/simufiquli.cs
yeah i dont understand people who do that like every 5 min
im just trying to get help, because I tried googling the stuff like 10 times and it didnt work
not u
oh k
why's that so laggy? Any ideas mr. illusion?
lighting updates maybe
did you add the flag?
my fucking scroll wheei is sticky grr
String player1 = String.valueOf(player);``` will call Player#toString on your player variable, which is just the string representation of the player object, not the players name. Later you compare the players name with its string representation and this will not be true. I don't get why you want to compare the player with itself anyway.
I am just trying to see if its the same player doing the event for the delay thing im trying to do.
so should I convert the player name to a string and them compare them?
okay so i just dont need that if statemen then
Not really, at least right now it doesn't achieve anything
okay thx ill try that rq
But I still dont get what your actual plan is
basically i have an item that, when right clicked, heals the player, but I am trying to add a delay between when they can do it so they cant just spam it
will this code stop the main thread for 2 ticks?
Bukkit.getScheduler().runTaskLater(BlockBattles.getInstance(), () -> {
location.getBlock().setType(DIAMOND_BLOCK);
}, 2L);```
no
why would you preffer to run it async instead of in the main loop?
its not about lighting updates, as I set the flag to true. Also, my hardware is not on full load
Ok. Then its probably the best to store the timestamp when the player uses it and when they try to use it again, calculate the difference of the stored timestamp to the current timestamp. Than allow or deny it depending on how long your delay should be.
So that it doesnt block the entire server. That thing youve sended will be executed in the main thread btw
maybe just the sheer amount of blocks hm
i am confused then
if I run that th emain thread will stop for 2 ticks?
no, it will run 2 ticks later than when you called it
No, it will queue your task and run it after 2 ticks
So the thing works mostly again.
I tried with the code in there to do the delay, not sure if the delay works yet cause I gotta figure out why (hopefully only one more) line of code doesn't work lol
Yea just tell me if you got any further questions
its just 6k
not that critical
Do you mind sharing the runServer task? I tried and cant figure out
cries in not done optimization
I use it as part of paperweight 
You could work with the multi block change packet to reduce bandwidth
Ah rip?
its just 1.4mil ns
Is that a clientside lag? D:
that should not lag like actual garbage
Yeah at that point you can only resend all the chunks
mm this is not the hitbox I was hoping for
probably
I drop down to 20fps so I suppose yes lol
But gl resending all the chunks
yes
I've heard that the client's fps loop is dependend on the networking look and vice versa (or something like that). Would explain that if you send massive amounts of data
But 6k blocks aren't that many blocks
What size is that rectangle?
for (int z = -20; z < 100; z++) {
arr.add(Bukkit.getWorlds().get(0).getBlockAt(x, -61, z));
}
}
so 50x120
so I guess 12 packets max, right? If I'm not completely stupid rn
especially not with multiblock-packets
hwo can I remove blocks async?
about that yeah
Let it be 20, that's still a joke. Think about my display, for example. There's gotta be something else
yes
I wonder how the client implemented this. Are you sure you are not spamming these packets?
max 1x per tick
Wow, that would suck actually, as I thought they operate in separate threads and only share concurrent packet queues.
but its already lagging when doing it one time
It could also be that network and tps loops are linked. Not sure which
You're most definitely missing something then. This is unacceptable tbh.
Are you sure on that, did you send it only once and it lagged?
yes
Not allowed/possible
I moved my cursor one time, and it did exactly one call
the interesting thing is that it is sometimes spiking and sometimes not
okay hopefully last question, no promises tho cause im bad, I am trying to set the Integer value in the HashMap to the current time, but (for some reason) it wants a string and not an Integer as the key and it wants an Integer instead of a long for the value. I had it this way before fig1 but it gave the error in the game console fig 2 but now its giving the error in the IDE fig 3
fig1:
map1.put(String.valueOf(Integer), Integer.valueOf((currenttime)));
fig2:
https://paste.md-5.net/puwafeqasu.cs
fig3:
map1.put(Integer, currenttime);
thx u have been so much of a help and given your time for my benefit, I can't thank you enough ๐
@old cloud
How do you fetch currenttime?
Long currenttime = System.currentTimeMillis();
@EventHandler
public void onBlockPlace(BlockPlaceEvent event) {
Player player = event.getPlayer();
Block block = event.getBlock();
Location location = block.getLocation();
BlockFace direction = player.getFacing();
if (block.getType() == DIAMOND_BLOCK) {
for (int i = 0; i < 5; i++) {
Bukkit.getScheduler().runTaskLater(Data.getInstance(), () -> {
switch (direction) {
case NORTH -> location.setZ(location.getZ() - 1);
case SOUTH -> location.setZ(location.getZ() + 1);
case EAST -> location.setX(location.getX() + 1);
default -> location.setX(location.getX() - 1);
}
location.getBlock().setType(DIAMOND_BLOCK);
}, 20L);
}
}
}
``` Why does this code place all the blocks at once instead of placing them 1 every second
So is the boolean you were talking about the trust edges thingy? Just want to make sure that you're not force updating lighting maps on all of these chunks.
no its on Player#sendBlockChanges
Yeah, and what's behind that Mr. BlackBox?...
Yes, its a long. So your Map needs to be of type long, not int ๐
the boolean is called something like surpressLightingUpdate or something
boolean suppressLightUpdates
Ok, so you don't have it flipped
yeah
ah and, would it be faster to directly use states.add(new CustomBlockState...); rather than
BlockState blockstate = new CustomBlockState(new Location(player.getWorld(), block.getX(), block.getY(), block.getZ()), airData);
states.add(blockstate);
``` ??
Because you queue your tasks all at once, not after each other.
could you explain me how to fix it?
yes ill do in a few minutes
dont worry
@EventHandler
public void onBlockPlace(BlockPlaceEvent event) {
Player player = event.getPlayer();
Block block = event.getBlock();
Location location = block.getLocation();
BlockFace direction = player.getFacing();
if (block.getType() == DIAMOND_BLOCK) {
for (int i = 0; i < 5; i++) {
Bukkit.getScheduler().runTaskLater(Data.getInstance(), () -> {
switch (direction) {
case NORTH -> location.setZ(location.getZ() - 1);
case SOUTH -> location.setZ(location.getZ() + 1);
case EAST -> location.setX(location.getX() + 1);
default -> location.setX(location.getX() - 1);
}
location.getBlock().setType(DIAMOND_BLOCK);
}, i);
}
}
}```
this did the job
idk if it is the best way
Thats one way you could do it, yeah
How should I control multi user development on github for a free and premium version of a plugin? We want to have our free version open source to everyone but have our paid version closed source, but we need to be able to work on it at the same time. Our issue comes when we want to be able to update the free version and be able to push those code updates onto the private github repo? Hopefully that makes sense
just make it all opensource
I dont wanna make the paid version open source though for obvious reasons
what reasons? tons of plugins do it
bro this is pretty obvious isn't it?
because they can just steal the code?
How can I do something like version: ${version} in my plugin.yml for gradle?
a lot of premium plugins are open source
Not because others plugins does it, you have to follow them you can be the exception
sure but it makes life easier
lol your code isn't special
The home of Spigot a high performance, no lag customized CraftBukkit Minecraft server API, and BungeeCord, the cloud server proxy.
if someone really wanted to they could steal it or replicate it anyway
I mean if you selling the jar, you can ge tthe whole src from the plugin
indeed
๐
How would i make it so that this can be saved to the config.yml onDisable and restored onEnable?
if (args[0].equalsIgnoreCase("claim")) {
if (plugin.getKingdoms().containsKey(player.getUniqueId().toString())) {
if (plugin.getCanClaim().containsKey(player.getUniqueId().toString())) {
if (plugin.getCanClaim().containsValue(playerKingdom)) {
if (plugin.isClaimedChunk(chunkID)) {
player.sendMessage(ChatColor.RED + "Chunk is already claimed");
return true;
} else {
plugin.addChunk(chunkID, playerKingdom);
player.sendMessage(ChatColor.GREEN + "Chunk claimed");
return true;
}
}
} else {
player.sendMessage(ChatColor.RED + "You do not have permission to claim chunks");
return true;
}
} else {
player.sendMessage(ChatColor.RED + "You are not in a kingdom");
return true;
}
}```
but it will promote piracy, they can just put the code on some other market and not worry about deobfuscation
Format it please, its really hurts to read
any1 actually buying plugins hardly want to be bothered with compiling it themself.
keeping it closed won't prevent piracy
exactly
obfuscation
it'll make it harder
Premium plugins can't be obfuscated anyway afaik
no it won't
they need to buy a copy to pirate it first lol
maybe use the free version as a github template for the premium version, that might work. But yeah, everyone's right, the code won't be private even if there's no open source premium xd
yea then they charge back
likely win
and you don't get anything
or download it from ||darkColor||spigot
wtf that would be dumb
"Everything that can be executed by a machine, can be interpreted by humans" -Take as u want
Dont lost ur time trying to hide your code because people who really want your code, will do everythint o deobfuscate it
obfuscation is useless anyway
The offer in a premium plugin is NOT the code, it's the support
now when I changed it to a long it says this:
Required type:
Long
Provided:
Integer
it said that to this:
map1.put(Long, currenttime);
HashMap:
static Integer Long = 0;
public static HashMap<Long, Long> map1 = new HashMap<>();
now any of you upvoters, help me with my question ๐ฆ
i cant think of an effective way to format it
#help-development message help lol
Only the second type has to be a long, keep the first one like it was :)
I mean the entire plugin is based off making GET requests to a rest api, if we make it mandatory to have a license key for that we can try and prevent abuse of piracy
your variable is an integer named Long
Not wondering to be rude, but im seeing you havent learnt java - I woulod suggest first learn the lang where you are coding
and just limit the amount of requests you can make
spigot will auto deny if you have any licensing server
Those rest apis can get emulated really easly
Point is that you can't even use licensing system with spigot ๐
Wait spigot wont let me put my plugin onto spigotmc if we have a rest api that needs a login key??
why spawnParticles method is is from player?
anyone knows? ๐
you can do it in the world, or in the player
One sec I will read it
doing it on the player spawns client-sided particles
doing it in the world spawns particles for everyone
oh tysm
"Your plugin must not depend on internet connection" So basically you cant use licensing system
- Taken from spigot rules
All resources must run directly from downloaded file without any manual installation steps or access to a specific server. This means that licensing systems of any form are prohibited. This also means that all applicable code must fail-safe in the event of (web) server error.
now the required type is a string should I just make the current time a string?
I didn't know that's a rule and I don't understand the point, a plugin can be ran offline but doesn't make a lot of sense most of the time, does it?
i'd just store current time as a long
I guess we can create a not so updated version of a json file that just has like a few hundred thousand lines, still annoying to do though
okay ill do that next time, instead of just asking ppl for help
yes, that's pretty much what's recommended, that way you can get help more easily
Ill answer in some minutes, kinda busy rn
@raw sky dont lost your time obfuscating and using license systesm, they will be cracked. Take as an example Miscrosoft, they used to have a really secure licensing system and look some years ago, they OS not only get cracked, they also deobfuscated parts of code
current time is a long
Long currenttime = System.currentTimeMillis();
it wants a string cause the name is a string ig idk really
obfuscation and drm is just not worth it
whats so bad about storing data like that? sure 100k lines in json isnt the best but it doesnt get looked into consistently, it takes about 2 seconds to load
whenever you get the time, cause in 5 to 10 mins i gotta go
and I cant use a database online because "no internet connection" or whatever
the issue is in the map that will store the time, not in the variable that will be put
I'd probably learn a bit of java. before doing something like this you'd probably be fine doing like W3schools or something
why do you need 100k lines of json
Json is not database and will never be
its an index of every spigotmc plugin and some of its data
https://paste.md-5.net/opozetavav.bash
that's as close as i can get. its positioned with a command so im not going thru the effort of figure out where the final few }s goes
DRM can really easly be brute forced, even thou you can modify the jar bytecode directly and make to it to call your own backend which replicate the original license api
good lord why
if we have some of its data then it would be multiple hundred lines
its going to handle the management of plugins, it auto updates them and everything
Just use proper database, it's wrong usage for json
installs, updates, deletes
but I cant depend on a internet connection
depend on it*
You don't need Internet connection for database
your entire plugin depends on it???
you can soft depend tho
there are local dbs
how are you gonna update plugins without relying on internet
And I'm also pretty sure it's not point of that rule on spigot
its not they are targeting DRM shit I'd assume. Also you can use spigot libraries feature
though a moderator would have more insight than me
we make a request to a api online, we get all the plugin data, version, sha256, malware, etc from there. We have a project that scans through every single plugin on spigot and index's them
probably could ask optic or choco
Ive say it many time that rule is stupid and shold be re-writed but so far md5 doesnt respond dms neither temp nor support email, we cant do much
malware? shouldn't you just report that... Also optic has a nice anti malware tool
optic is literally working on making it natively scan in runtime
the ability to prevent anti-malware in the title is beneficial, we will host plugins from other sites too
so that any plugins trying to do foul stuff get stopped by the server itself
we also need to store a lot of the data for a few new projects
Isnt this guy the owner of that weird site that we were laguthingat it some months ago?
MCLicense?
๐คท๐ฝโโ๏ธ
nope
probably not
I know who owns it, I do not own it though
Oh weird mainly his project is trying to be MCLicense-v2
Which wont success because of spigot rules and also you have to talk with md5 because he can take legal actions about the project because of their wrriten TOS
mine?
Anoyne know show to do that my plugin.yml works like this?
version: ${version}
becomes
version: 1.0.0
MCLicense is just a licensing software though, wont be just for spigotmc or anything
in resource section of pom <filtered>true
but you are a part of it?
If im not wrong Spigot TOS have something against hosting their platform resources im not sure tho
I am not, I just have close connections with them is all
I'm using gradle tho
and I see no pom
Im really thinking he is the owner but with another account, he has the same ideas as the owner
any ideas?
I don't gradle
"Virtual Ventures" runs "MCLicense" and "Portal Box"(the plugin you are working on)
If you wont have your message lost, pelase open a thread on this channel, that why spigot discord allow them
๐ I dont think it...
well the issue is that nobody will get in that later then
You are not paying anyone to get instant support si please you must be pacient - thanks sir
sure, but nobody will see it later on
is it a better idea to use gradle or maven for my projects?
version?
XD
whatever you like more
I am thinking about the version of my plugin, sorryyyy
Maybe maven or gradle?
yeah, just edited
own preference
both have down and upsides, whatever you like more
How would i save the chunk to config.yml onDisable and restore it onEnable?
Well maven or gradle (Java building enviroments), are based on developers preferences we cant help you much there
id say try both, see which you like more
I've used both maven and gradle and honestly I have no particularly strong feelings. I like the xml format of maven ๐คท๐ฝโโ๏ธ
i use maven because im just used to it
alright, I thought there could be some important leads to take into consideration, but all of you point that it's preference based so I'll stick to that, ty ๐
same
same, i just switch depending on the project sometimes
I'm switching over to gradle ๐คท๐ฝโโ๏ธ cuz why not its good to know both tools
got an idea
Which is the breaking block particle=
I a mtrying BLOCK_CRACK but it doesn't spawn any particles
you have all your particles turned on?
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType().getId());
just checked, all particles on
In my case i mainly prefer maven because of their format (XML) and that is really easy to create custom plugins for it
what's the best way to verify that someone has purchased my resource?
Via spigot account id if im not wrong, never did something like that related to spigot api
how do i do that?
if not tell them to show you their paypal transaction id
and check if you have that same id
if you have they have paid
Well i dont think because premium plugins must not depend on any backend nor internet connection
it won't depend on it
https://spiget.org/ well this is the api documentations
i'm making a bot in discord to verify purchases for support
maybe he wants to give role in their discord
Oh right, idk never used spigot api(s)
Any idea why mongo shity logs still persist, while i already disable the full logger ๐ก
do you know how to put the version of the plugin into the plugin.yml directly from gradle's config?
Why dont u use maven instead of losting time trying to find that
this doesn't help me verify purchases tho
I don't want to move the whole thing over to maven, too much of a hassle because I just started using IDEA u.u
What have the IDE to do? Doesnt mean anything
I meant Intellij
Build enviroments doesnt care about IDE ๐ idk your point
But setting up the compilation does
Nothing will, if a somewhat talented dev wants to pirate your software for the public.
Yeah, but what the problem? Maven is really easy
he just wants to use it for a discord bot.....
That's fine I just don't want to provide support to people who pirate and thus I'm verifying on discord
maven is easy, setting it up on intellij can be confusing xd
For example, modify the plugin bytecode or even decompiling it, modifying it and building it again
In general I'm not worried about piracy
nope I don't even do it for maven either
I wasted like 1h setting up gradle lol
the version number doesn't matter to me
Oh, so you're about handing out tokens you gotta provide if you want support?
No bruh, maven already cames with IJ ๐ค
you can do gradle init in a maven project
so does gradle
people who buy get a role on my discord
both are integrated equally
Yeah
Yeah, so tokens, in the end.
They area already integrated, just need to tell IJ to download them
Okay so how can I check?
I think you are not getting it, (afaik) there's no such thing as "Click here to compile your file into jar with everything already perfectly set up", so you have to set up a bunch of things manually to compile for the first time
just do it manually and get some staff, I mean its not that huge of a deal if x person needs support just have a manual verification process
can someone join to my local server per dm rq and test if it also lags for them?
i don't want to do it manually that's why i'm asking for ways to verify it
Listen and read this phrase many times and you wont do any protection way - "Everything that can be execued by a machine, can be interpreted by humans"
Just dont lost your time instead make an update to the resource
Well, you need to bake a token into the plugin. No need to recompile, just patch the class's constantpool and change the string. No idea how to get spigot to execute this routine tho. Ask md5, lol
I'm not doing DRM in my plugin....
smh verano he's not doing DRM
Buts its applied to what you want to do too
its a support token he wants
no its not
I don't want tokens
OH LMAO
could ask md5
but otherwise not sure
I want my bot to check if someone has bought the plugin and then give them a role in Discord
i dont think it will posible, if im not wrong public apis, must not violate some TOS against digital money
it is possible...
Well, if you want to automate that, you need a proxy anyways. Maybe the spigot api allows some sort of purchase validation as a param when relaying to an external download.
you could also just paypal api to check payment emails.
I can always verify through the PayPal API but that seems less effective than scraping info off Spigot
what do you mean?? its automatically all setup without touching a single button
Yes bruh
Look
use the minecraft intellij plugin if you arent already
well, maybe for maven but it took me a while to set up the gradle environment for my project xd
OH
yes thats 3 clicks
there's one?
where do I get it? lol
use mc dev plugin and its 2 extra clicks
Dont confuse things, the plugin itself doesnt contain the build enviroment
please just be quiet for 2 seconds
file -> settings -> plugins
Hey stop it, you always against what i say
its built in to intellij
No, you are the one confusing people
and the mc development sets it up for people
tbf you are actually not understanding nor providing good info
So let me explain you
I understand what you say, you don't understand what I say, no need to explain xd
ty
Does anyone know how i could go about implementing a custom save format, what general things would i need to do for that?
what do I look up tho?
"Minecraft intellij"? or what?
Minecraft
oh nice lol
like a custom world save format
essentially replacing anvil
Any alternative to disable mongo shity logs? I tried setting their shity logger to Level.OFF but didnt stop it. Its really disturbing that thing
Minecraft development its called
awesome, good tutorial, sub + like
Depends on what you wanna do, whats your main goal of a custom save format?
over using something like SlimeManager
haha ram go boom
yo Illusion lol
who needs ram anyway
@echo basalt you on your pc and able to test something out in mc rq?
I literally upgraded to 32gb ram to have more intellij windows open
I wanna know if its server issue or client issue
sure, lemme turn on my vpn
what is this in spigot config api, list of configuration sections ?
Saving and loading to a format used by a mod that already exists
aight
i want to get more ram :( im at 32gb rn and its basically always maxed
sent you the IP
fields -> list
name -> list
value -> whatever you make it (String for example)
inline -> just like value
at 32 g??
tf ru doing then
chrome, intellij, minecraft
im often with 3 intellij instances open, 2 servers, 3 minecrafts
and still at like 20
Have the same problem but having 64gb i mainly using 60gb
hmm, isnt name value and inline like a single object of list inside of fields ?
minecraft on what settings? I got all max and it's like 6GB top lol
whats using the most
chrome
m8 i gotta see that task manager
yeah, that's what i meant
OH WIAT NO
๐
i have that open too ๐
firefox is superior
Ethernet explorer >>
๐
I think each your file/tree just does not make sense xd
yeah lmao firebox is even worst haha really slowly compared with MS netscapes
google chrom like 5Gigs ram HAHAHAH
chrome with a lot of processes
ive never had any issues, and it does not use as much memory
https://www.treedoc.org/#/ you can verify it there i guess
well, its valid yaml, just don't know how to handle it in spigot api
oh weird, i always had issues with it, cache, dns, etc
i think its just a bunch of the apps that are smaller amounts of memory that are dragging it
like all the spinoff process of chrome
A Map is a data structure to map a key to a value. Any time you call it with a specific key, you will always get that specific value that was mapped to the key. Since you want to store a timestamp that will be associated with a specific player, you need a map that maps Player->Timestamp. Best practice to identify a player is using their UUID and the timestamp is of type long. So your map should be Map<UUID, Long>. Now whenever a player wants to heal, you can get their last successful heal with Map.get(uuid). Calculate the difference to the current time and if your desired delay has expired, perform the heal and update the new timestamp (the new last heal basically) with Map.put(uuid, timestamp).
yeah, its list of objects, but what objects xd
this is actually my lower usage aswell, i usually have way more tabs open which eat up ram
but why would u have so many tabs open
I have never had more than 10 tabs open at the same time
i just do
but ...w hy
u ready?
I like how database+webserver only take 4mb ram lmao
aight
The only times I've had over 200 tabs open was when I made modpacks
Before the curseforge launcher
LOl how you can work without many tabs
Currently having 10 instances of Opera GX with 20-40 tabs each instance
๐
@echo basalt how's it going?
opera gx ๐
I clicked on it again and it's spiking
click?
Better than firebot/box secure about it, no dudes
the gun is irrelevant
๐
just another project lmao
it would be like 15x better
if you uhh
only sent changes
instead of sending air and blocks again
it can bring out massive improvements
like if I move side to side
but I gotta calculate that too, thats a lot of calculations
the objects are "name:","value:" and "inline:", because you are not setting values to them
and also, I gotta send air to remove the blocks lol
I mean
I'd probably make a mask
for each block type?
and see if the mask contains the new position
if it does, exclude
god what?
It's actually pretty chill ngl
imagine there are values


