#development
1 messages ยท Page 117 of 1
yea lol
Oh... I forgot about that lol
Okay kinda think this works
@Override
public PlayerTime read(JsonReader in) throws IOException {
PlayerTime playerTime;
String uuidString = null;
Duration duration = null;
in.beginObject();
String fieldname = null;
while (in.hasNext()) {
JsonToken token = in.peek();
if (token.equals(JsonToken.NAME)) {
//get the current token
fieldname = in.nextName();
}
if ("uuid".equals(fieldname)) {
//move to next token
token = in.peek();
uuidString = in.nextString();
}
if("time".equals(fieldname)) {
//move to next token
token = in.peek();
duration = Duration.of(in.nextLong(), ChronoUnit.MILLIS);
}
}
playerTime = new PlayerTime(duration, UUID.fromString(uuidString));
in.endObject();
return playerTime;
}
I know I shouldn't assign them to null, but not sure what else, I'll just need to check for null in other classes ig
or disallow nulls in one way or another
either return null, or throw an exception, or provide with default values
So this would be acceptable?
if(uuidString == null || duration == null) {
return null;
}
playerTime = new PlayerTime(duration, UUID.fromString(uuidString));
yeah, then when you're reading from the file check if what's returned is null
or if you're putting them in a list you can just List#removeIf(Objects::isNull)
Ohhh that's smart, well I assume this doesn't just serialize it automatically, so I need to use this class somehow?
huh?
Well, how do I actually serialize and deserialize using this new adapter?
I've only used the standard one which failed
Because duration could not be (de)serialized
you need to register it, new GsonBuilder().registerTypeAdapter(MyClass.class, new MyAdapter()).build()
and from then on use that built gson instance
I tried this
public PlayerTimeManager(ParkourPlugin parkourPlugin) {
this.parkourPlugin = parkourPlugin;
this.playerTimes = parkourPlugin.getPlayerTimes();
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(PlayerTime.class, new PlayerTimeAdapter());
builder.setPrettyPrinting();
gson = builder.create();
}
public String test() {
String jsonString = "{\"uuid\":\"3a7e5c5ee48340f7b5f4797220fe4d69\", \"time\":100}";
PlayerTime playerTime = gson.fromJson(jsonString, PlayerTime.class);
jsonString = gson.toJson(playerTime);
return jsonString;
}
Not sure if that'd work tbh
U right, I just don't think I need it to return a string
Ummm so it prints this
[20:36:54 WARN]: [net.valdemarf.parkourplugin.commands.Testing] {
"uuid": "3a7e5c5e-e483-40f7-b5f4-797220fe4d69",
"time": 100
}
Not sure if it's good or bad lol @lyric gyro
I think it's correct json format
mhm
I have some custom items in my plugin, and want players to have the ability to add attributes. To avoid this getting too complicated, I want to avoid using ADD_NUMBER, ADD_SCALAR or whatever since it can be hard to understand. I instead want it to only use add number, but I want to get the default attribute value with a placeholder so that it can be used to calculate the new attribute value. I essentially want to compress all attributes in to one attribute, how do I do this?
I have a yml file that contains:
effects:
speed:
duration: 10
level: 2
jump:
duration: 10
level: 3
how can I get all properties (speed, jump) of the "effects"?
for example in DeluxeMenus there are items: and It gets everything inside items: and adds them to menu
hey, i have an itemstack array with 3 rows worth of items and im wanting to put them in a custom gui. i was going to use .setcontents but i want it to start 1 row from the top of my gui
is there any way i can acheive this? Thanks!
@dense drift https://paste.helpch.at/rejalewana.js
This is the adapter class
I'm guessing it never leaves the while loop
Does someone know why I'm getting a thread dump crash from this?
I think u got it, duration might've been null - testing now
Okay so one of them was null https://paste.helpch.at/subumupomu.md
Not sure what this means? [00:12:21 ERROR]: [ParkourPlugin] [ACF] com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected END_OBJECT but was BEGIN_OBJECT at line 1 column 10 path $._id
I did end it ```java
if(uuidString == null || duration == null) {
Bukkit.getLogger().log(Level.SEVERE, "DURATION OR UUID IS NULL!");
in.endObject();
return null;
}
I recommend sepearating it into two if statements. that way when ur debugging youll know exactly which param is null
also can u send the whole class
I'll try that
btw if I use while(in.hasNext()) like I see most people use - I just get this thread dump https://paste.helpch.at/fiwetezoga.md
Hi, im creating a mine plugin. The mine will be essencially big, something like 100x100x100 at most, so im having performace problems on how bukkit sets block type to the 1 million blocks. I've been reading a lot of articles about it, and learned why it is laggy but due to the spigot version that im using (1.8) i was not able to found a solution that at least works. So if you guys have some explanation article/code that works for spigot 1.8.x i would be really grateful ๐ thanks
Have you set a maximum amount of blocks to change per tick/second?
That's where I would start
not really
Do that and schedule portions of the area to be changed every time the task is run
yes, i already try that but i want a really fast change, like literally 1 second
referring to the second option
waow
im founding how to because i've seen in a server that makes it soo fast
Does not perform light update
Does not send updated blocks to player (requires a relog)
Does not work if specified coordinate is in a not loaded chunk
im assuming thats fine right?
in this case
yes but preferably that players do not have to relog
something like when the mine resets, the players are teleported to the front of the mine
err.. 1 million blocks isn't that much
I mean it is quite a bit, but it shouldn't take long, if anything I'd suggest using the worldedit api rather than bukkit, it'll skip over the dumb slow api wrapping
you can also give the โจ illusion โจ of speed by setting a hollow block first, then filling the insides
lowkey smart
๐ i deserve to work for google
yes, i was trying with worldedit as well but dont find how to do it exactly
thats a good one o.0
definitely try to figure out worldedit too though as emily suggested, you can compound the benefits
nvm im dumb
ok guys, thanks for the support! ๐
epic
๐
i mean honestly, just lean into the vibe of a cool refilling animation or something
mine resets totally don't need speed, they can be cool as hell
fixed
fucking bet
honestly true
anyone who has netty knowledge:
do you know why a pretty empty ServerBootstrap with a single handler that simply System.out.println a message about the the operation a handler runs is constantly performing operations (channel registered/unregistered, active/inactive, read, handler added/removed) without any connection?
Does Placerholder API works with a BungeeCord Plugin? I want to provide my own placeholders
mhh, thx. If i get this right placeholders can only display by spigot plugins. So since i just want to provide my own placeholders via a bungee plugin, users need a bride or whatever to display my placeholders?
Hey, so I'm creating a TypeAdapter for json and running into this problem - https://paste.helpch.at/subumupomu.md
The class: https://paste.helpch.at/lenaguwici.js
I'm using a for loop instead of while(in.hasNext()) because it caused a thread dump https://paste.helpch.at/fiwetezoga.md
I've been trying to fix this and google it for a long time, but can't seem to find a solution.
Eeh I suggest something like this
in.beginObject();
while (in.hasNext()) {
switch (in.nextName()) {
case "uuid" -> ...;
case "time" -> ...;
default -> in.skipValue();
}
}
in.endObject();
Also what's the actual json you're trying to read?
This
And storing it inside this object https://paste.helpch.at/uhobasusal.java
Had to create a custom TypeAdapter for Duration
New error https://paste.helpch.at/uqaribetav.md
uh that doesn't look like a json.. lmao
No, but it's how it's stored in the database, I need to deserialize that lol
I know what's wrong now though
Expected a long but was NAME at line 1 column 114 path $.uuid
while (in.hasNext()) {
switch (in.nextName()) {
case "uuid": uuidString = in.nextString();
case "time": duration = Duration.of(in.nextLong(), ChronoUnit.MILLIS);
default: in.skipValue();
}
}
I need to convert the name to a long somehow
if you're using the "normal" switch case with : you have to add a break; statement
Oh yeah ```java
while (in.hasNext()) {
switch (in.nextName()) {
case "uuid" -> uuidString = in.nextString();
case "time" -> duration = Duration.of(in.nextLong(), ChronoUnit.MILLIS);
default -> in.skipValue();
}
}
IntelliJ recommended "enhanced switch" like the one you sent above
mhm
sweet
Any tips on how I could store personal bests? Instead of just a leaderboard of times - could this be done in a TreeSet as well? I just need to only have one time from each player in the set or map
Right now I use a hashmap so I can use putIfAbsent which is nice, but for json, a TreeSet would be way easier, just not sure if it would even be possible
eh?
Hmm, I'll just try.
store their personal best as a long unix milisecond time
and then format that with something like simpledateformat
so its stored as an long but you can then convert that to whatever format you want on the fly
then just check if the new value is smaller then the old pb, if so then change the time and do your fancy you have a new pb thing
i would say store the personal bests with the player's uuid
I mean I already got an object that contains the duration and uuid, so I'll be able to store them in a treeset anyway I think
Should be able to do anything from this right?
probably? i dont know the ins and outs of leaderboard creation.
Hmm, I'm trying to do that but running into the problem - I know what it means but like I'm 100% sure that it has been initialized, even though it wasn't from the start
If I initialize it as null I just get this warning
So it's always reassigned anyway?
i would say if a variable hasnt been initalized, what does it actually return.
because its doubtful that it would return null
Yeah I know, but this is what I mean
boolean personalBestAlreadyCreated = false;
for (PlayerTime playerTime : personalBests) {
if(playerTime.getUuid().equals(player.getUniqueId())) {
// The player has beaten the parkour before
if(newTime.compareTo(playerTime) < 0) {
// Personal best has been beaten
personalBest = newTime;
player.sendMessage("Congratulations! You've beaten your previous best time!");
} else {
personalBest = playerTime;
}
personalBestAlreadyCreated = true;
break;
}
}
It's a guarantee that this will assign it to something
It cannot go through it an still not be initialized
Since I also got this
if(!personalBestAlreadyCreated) {
personalBest = newTime;
personalBests.add(newTime);
}
IntelliJ gotta be wrong
ยฏ_(ใ)_/ยฏ
try it and see ig
i usually just make every a new whatever
so it has an empty array rather then a missing array
The compiler was incorrect, weird
it does say might
how do i get the location of a placed water source in 1.8.8
?
This will return an error if oldBest is null right?
leaderboardTimes.contains(oldBest)
PlayerInteractEvent check right click if they have a water bucket in their hand
a key can't really be null
NullPointerException โ if the specified key is null and this map uses natural ordering, or its comparator does not permit null keys
From TreeMap
It's TreeSet but same thing ig
hey
can anyone help me with finding a water source location
in 1.8
@EventHandler(ignoreCancelled = true)
public void onBucketFill(PlayerBucketFillEvent event) {
Location loc = event.getBlock().getLocation();
if (locations.contains(loc)) {
locations.remove(loc);
return;
}
event.getPlayer().sendMessage("You can only pickup player placed water");
event.setCancelled(true);
}
@EventHandler(ignoreCancelled = true)
public void onBucketEmpty(PlayerBucketEmptyEvent event) {
locations.add(event.getBlock().getLocation());
}
}
Currently using this, but the build says 'cannot find symbol'. I'm guessing its that i cant use event.getBlock().getLocation() in 1.8?
Did you try this?
where are you getting that error? (what line)
only thing i can think of is that locations doesn't exist
or that you're not importing something
Any good ways to remove the first digit of a long? Is it just converting it to a string and then removing it?
what calculation?
Lmao
Found this to store the first digit, just wondering how I can remove it
millis % (int) Math.pow(10, (int) Math.log10(millis))
it would be possible with log10 (get number of digits, multiply by first digit, multiply by 10^number of digits, subtract)
but stringing might be easier unless you need the better performance
actually thats not so bad
I mean better performance is always nice
It will be running a lot (in onMove event)
ok yeah definitely then
Difference between log10 and just log btw?
Oh yeah I can't just valueOf of a double
Do I just
(long) (millis - firstDigit * Math.pow(10, Math.floor(Math.log10(millis))))
Then?
Not sure what that returns if there are decimals, if it just rounds up or what
should work
Ummm nope
long firstDigit = millis % (int) Math.pow(10, (int) Math.log10(millis));
long newMillis = (long) (millis - firstDigit * Math.pow(10, Math.floor(Math.log10(millis))));
player.sendMessage(
"Congratulations, you've finished the parkour in " +
firstDigit + "." +
newMillis + "s");
Trying this instead to get the first number number/((int)(pow(10,(int)log(number))));
Works now
Thx for the help!
Ohhh yeah that's a problem
If it's 0 it's just gone
if (newMillis < 100) newMillis*=100;
i updated the code to use event.getBlockClicked().getLocation().
It compiles now but instead of preventing the player from picking up a water source, it sends the message and doesnt even cancel the event.
what would be the best way to go about scrolling a gui. I have a skill gui but the width is about 5 guis. im wanting to scroll collume by colume rather than just having 5 pages. should i have an inventory object for each frame or should i pass a scroll amount integer into the gui creator class and it can have some if statments to decide where to put items
thanks
No, 3.093
aight I'll try that
wait valde
Ye?
do you want something like
123.4 -> 23.4
Yeah
o.O
wait so are you just inserting a zero in the tenths place and shifting the other digits right
It's separated into two different numbers, so the 0 is just being ignored
player.sendMessage(
"Congratulations, you've finished the parkour in " +
firstDigit + "." +
newMillis + "s");
newMillis just ignores the 0
if it's the first digit
Yeah
there's definitely a string format way of handling leading zeros
let me look it up
The format() method of String class in Java 5 is the first choice. You just need to add "%03d" to add 3 leading zeros in an Integer. Formatting instruction to String starts with "%" and 0 is the character which is used in padding. By default left padding is used, 3 is the size and d is used to print integers
I mean if I'm converting to string I can just check if the value is less than 100 beforehand, then add a 0 to the beginning
Or would that cause worse performance?
this is likely better than than adding a zero to the string yourself
not positive though
it's also easier this way imo
But with that way you're not sure how many 0's need to be added
you tell it what your total # of digits is
zero or otherwise
and it will decide for you how many zeros to add
lemme take a crack at making a demo
This should work no?
long newMillis = (long) (millis - firstDigit * Math.pow(10, Math.floor(Math.log10(millis))));
String newMillisStr = String.valueOf(newMillis);
if(newMillisStr.length() == 2) {
newMillisStr = String.format(newMillisStr, "%01d");
}
and then just check if the length is 1 as well ofc
int testMS = 23;
String output = String.format("%04d", testMS);
System.out.println(output);
prints
0023
Oh this should work right?
String newMillisStr = String.valueOf(newMillis);
if(newMillisStr.length() < 3) {
newMillisStr = String.format("%0" + (newMillisStr.length() - 1) + "d", newMillisStr);
}
No errors
i dont think you even need to test the milis length
and you also probably dont even need to convert the new milis to a string, just use the int/long version with %d
I don't too many 0's though
oh, I'll try that
if the string length is above 3 then the format will just not apply any extra zeroes
by default
int testMS = 77523;
String output = String.format("%04d", testMS);
System.out.println(output);
prints
77523
Oh
Isn't this how you meant?
you dont need to use the stringmilis . length in there at all imo
just decide on a precision that you want to show
do you want your times to be to the nearest tenth? hundredth?
Oh yeah idk why I put that there
Same issue with just newMillis
.
what do you want your finished string to look like
how many digits do you want
xxxx.xxx
^- here
on the second half of the value
If the number is like 093 I just want it displayed as 093 and if it's 009 I want it displayed as 009
It will always be 3 long I think
%.3f
f expects a double/float
and d expects an int/long
you need to either pass an int/long var into the 'd', or use 's' instead
When using s instead it gives me a warning with basically the same
And wdym by pass a long var into it?
that's because newMillis is a long
your issue is that you are setting a variable of type long to a string
since string.format returns a string
like gaby said
Long.parseLong(String.format())
so
String stringified = String.format(...)
I thought you said I didn't need the string?
you want to keep the output of String.format as a string
you dont need any strings before you call String.format though
Ohhhh
long newMillis = (long) (millis - firstDigit * Math.pow(10, Math.floor(Math.log10(millis))));
String newMillisStr = String.format("%03d", newMillis);
Like that I assume then
Imma test that then
btw i didn't catch what exactly you were doing with that first line, that turns millis into newMillis
what is that doing
Well I only have one number stored that shows the time like 8305 if it was 8.305s
So I need to split it into two variables
Atleast that's what I've done now
Could probably just add a "." after the first char...
so you have a long that holds the milis
and you want to extract just values that are below one second
so if you had the long
10370 // 10.370 seconds
you want to get out just the
370
you can just use modulus for that
I mean I don't really want to "get it out" I just want to add the "." and "s"
long totalTime = 10370;
long justMilis = totalTime % 1000;
System.out.println(justMilis);
prints
370
i see
Actually what I just created wont even work lol
in that case you can probably just use some time class to convert miliseconds to seconds, maybe
if it's like 12.384s it will print 2.384
if you're just converting from milis to seconds this is actually ez to do by hand
I am
Idk why I've complicated it so much
int totalTime = 77523;
int seconds = totalTime / 1000;
int milis = totalTime % 1000;
String finalTime = seconds + "." + milis + "s";
System.out.println(finalTime);
prints
77.523s
you get the seconds by dividing by 1000 (it automatically rounds down because you're using ints/longs; integer division!!!)
you get milis component by taking the modulus of it by 1000
and then just put em back together however you want
So
long millis = duration.toMillis();
long seconds = millis / 1000;
long newMillis = millis % 1000;
String finalTime = seconds + "." + newMillis + "s";
player.sendMessage("Congratulations, you've finished the parkour in " + finalTime);
Makes sense
Bruh I overcomplicated it so much lol
I see, thank you very much! My plugin is almost done
sure thing
Probably very bad for performance atm but yeah...
just for reference, if you want to do fancier stuff like minutes and hours, you can do:
int totalTime = 77523;
Duration timeLeft = Duration.ofMillis(totalTime);
String hhmmss = String.format("%02d:%02d:%02d.%03d",
timeLeft.toHoursPart(),
timeLeft.toMinutesPart(),
timeLeft.toSecondsPart(),
timeLeft.toMillisPart());
System.out.println(hhmmss);
prints
00:01:17.523
200 lines of code in onMove event lol
Tyty, I'll save this
you can easily edit that ^ to remove the hour component
Ummm @torpid raft with this it won't keep the first 0
oh you're right
wait
yeah youre right
you
will need to do the string format thing alongside that
yup probably gotta do that
int totalTime = 77523;
int seconds = totalTime / 1000;
int milis = totalTime % 1000;
String finalTime = seconds + "." + String.format("%03d", milis)+ "s";
System.out.println(finalTime);
good luck ๐ฅฒ
I save a hashmap to a file
for (Map.Entry<UUID, User> entry : userHandler.getUsersMap().entrySet()) {
this.getConfig().set("data." + entry.getKey().toString(), entry.getValue());```
This is how its being saved, why?
```yaml
data:
de4b97ab-b9be-4c4a-8778-f964f13d2a13: !!me.hyperburger.revblocks.user.User <<< What is this?
blockCount: 12
name: HyperBurger
This gives me errors py 20.01 11:03:18 [Server] INFO org.bukkit.configuration.InvalidConfigurationException: could not determine a constructor for the tag tag:yaml.org,2002:me.hyperburger.revblocks.user.User 20.01 11:03:18 [Server] INFO in 'string', line 2, column 41: 20.01 11:03:18 [Server] INFO ... ab-b9be-4c4a-8778-f964f13d2a13: !!me.hyperburger.revblocks.user.User 20.01 11:03:18 [Server] INFO ^
How can I remove the !!me.hyperburger.revblocks.user.User from being saved
I believe that's the default serialization of snake yaml
or bukkit, either of them
register a custom serializer or set each property manually
set("data." + uuid + ".name", name)
Hey Quick Question: the MoveEvent calls twice which causes my Score to go up by 2 instead of by one. is there a super easy fix?
I need to check if the Player is below a specific y value and in range of a specific Location.
but the MoveEvent calls way to often
You could use a runnable then
I fixed it I just forgot a break in my loop
Does anyone know how I can reload the default config without passing around objects from file to file? reloadConfig() doesn't seem to do anything
Don't keep an instance of ConfigurationFile, always get it from Plugin#getConfig - if that's what you are asking
reloadConfig will indeed reload the config, you just need to call getConfig again after it
Do it need to run it right after, or can it be ran some time after? For example, I'm using the config to let users set a GUI title, so would getting it then be fine?
Yep, I already currently get it from Plugin#getConfig
but don't store it, every time you need to get the config just call getConfig each time
That's what I'm doing, but once the config has been "reloaded", it still has the old value until I reload/restart the whole server
it uh shouldn't do that
you'll have to share some code for this, chief
Yeah, gimme 2 secs I'll do tat
namely the main class and prolly wherever you're getting the config as well
Main class:
public final class MotixBounties extends JavaPlugin {
public static MotixBounties instance;
@Override
public void onEnable() {
MotixBounties.instance = this;
// Create config.yml configuration
this.saveDefaultConfig();
// Create messages.yml configuration
MessagesConfig messagesConfig = new MessagesConfig();
messagesConfig.getFile();
this.getCommand("bounty").setExecutor(new BountiesCMD());
}
@Override
public void onDisable() {
MotixBounties.instance = null;
}
public static MotixBounties getInstance() {
return instance;
}
}
Reload Command:
case "reload":
PlayerData playerData = new PlayerData(p);
playerData.reloadConfig();
MotixBounties.getInstance().reloadConfig();
Common.tell(sender, Common.getPrefix() + messagesConfig.getConfig().getString("reloaded_playerdata").replace("{player}", player.getName()));
break;
The player data and messages config reloads fine, it's just the default config
does PlayerData#reloadConfig depend on the plugin config?
I can show you the class for that if you want
public class PlayerData {
private static File playerDataFile;
private static FileConfiguration playerData;
OfflinePlayer player;
public PlayerData(OfflinePlayer player) {
this.player = player;
}
public FileConfiguration getConfig() {
if (playerData == null) {
playerData = YamlConfiguration.loadConfiguration(this.getFile());
return playerData;
}
return playerData;
}
public void saveConfig() {
try {
playerData.save(playerDataFile);
} catch (IOException e) {
e.printStackTrace();
}
}
public void reloadConfig() {
playerData = YamlConfiguration.loadConfiguration(playerDataFile);
}
public void set(String path, Object object) {
getConfig().set(path, object);
saveConfig();
}
public File getFile() {
if (playerDataFile == null) {
playerDataFile = new File(MotixBounties.getInstance().getDataFolder() + "/players", player.getUniqueId() + ".yml");
if (!playerDataFile.exists()) {
try {
if (playerDataFile.createNewFile()) {
Bukkit.getLogger().info(String.format("[MotixBounties] File for player %s has been created.", player.getName()));
playerData.set("bounty", 0);
this.saveConfig();
}
} catch (IOException e) {
Bukkit.getLogger().info("[MotixBounties] Players folder does not exist. Creating...");
Bukkit.getLogger().info(String.format("[MotixBounties] File for player %s has been created.", player.getName()));
}
}
return playerDataFile;
}
return playerDataFile;
}
}
well, the issue can be that you create a new instance of PlayerData and call reload on that object
I assume that you have a PlayerData object stored somewhere and the config for that object is not updating, right?
The player data works fine, actually. It's just the default config
so your issue is plugin's config?
The config.yml file
Is this somehow possible in a record?
public record JoinLeaveListener(ParkourPlugin parkourPlugin) implements Listener {
private ScoreboardManager scoreboardManager = parkourPlugin().getScoreboardManager();
I believe that IIJ's suggestion that a class ca be a record are somehow broken
Nono I made it a record manually, I'm just wondering if it's possible
Well, from what I know, records should be used as immutable data classes (classes with only getters, hashCode and toString), a Listener looks more like a normal class if you ask me.
Record classes, which are a special kind of class, help to model plain data aggregates with less ceremony than normal classes.
Hmm yeah ig I'll just do this then
public class JoinLeaveListener implements Listener {
private final ScoreboardManager scoreboardManager;
private final ParkourPlugin parkourPlugin;
public JoinLeaveListener(ParkourPlugin parkourPlugin) {
this.parkourPlugin = parkourPlugin;
this.scoreboardManager = parkourPlugin.getScoreboardManager();
}
yes
so now I'm feeling like playing with actual mc packets, but not using something like protocollib, I want to make my own packet listener, and injector, where should I get started ๐
I keep running into this problem, it's in an onMove event but run with like a few seconds in between.
https://paste.helpch.at/avufojuquj.cs
output:
[21:20:20 WARN]: [net.valdemarf.parkourplugin.listeners.MoveListener] Timer has been started
[21:20:24 WARN]: [net.valdemarf.parkourplugin.listeners.MoveListener] instantStart was null
What would be the best way to iterate through a package and get all classes inside of it?
@warm steppe You can scan the jar file itself
basically just scan the jar with a ZipInputStream (or JarInputStream), filter entries to your package name, collect all files ending with .class, then load them through your classloader
is that how minecraft loads plugins
sorta
spigot scans the jar using a (presumably) similar mechanism for the plugin.yml file
inside the plugin.yml contains the fqn of the plugin's main class
the entire jar is loaded into the jvm (using a urlclassloader) then the main class is reflectively instantiated
fancy
key difference is that process doesn't load every class
whereas my class scanner does
it doesn't scan jack, it just calls classLoader.getResourceAsStream("plugin.yml") and hopes for the best
lmao
or no
JarFile jar = null;
InputStream stream = null;
try {
jar = new JarFile(file);
JarEntry entry = jar.getJarEntry("plugin.yml");
same thing but before putting it in a classloader lol
any better way of listening to tab completions (to add a tab completion to a command) for 1.8 -> 1.17 support without having to setup modules?
setting up modules for one listener ๐ฉ
i might just use packets lol
oh 1.17 has transaction id in packet
cool
pog i finally got it to work with 116 lines in my tab completion listener class
all that for one tab completion arg ๐ฅฒ
protocollib ftw
So, I have a jar (jar A and I need several copies that are 99% the same, except for a word in the package / name of a class and a string variabile inside that class and also a yaml file.
package some.package.PLACEHOLDER_NAME;
public class SomeClassPLACEHOLDER_NAME {
private final String = "SomeStringPLACEHOLDER_NAME";
}```
I've tried to replace this placeholder using a Zip(Input/Outpu)Stream and ZipEntry, by copying the condent of jar A into a new jar. This works fine for renaming the package and even the class name, but for class source, well, the result file is empty ๐คฃ. Is there a library or even a gradle task I could use for doing this?
if your 'database' is stuff you store in memory, you can use some sort of network communication method to talk between your spigot and bungee instance
(shameless self promotion for that: https://github.com/Ivan8or/RadioScanner)
a 'real' alternative to this ^ is redis, which requires you to host a standalone server for it but can let you do other stuff as well like caching
however, if all you're doing is storing data you might want to set up a database server like MySQL, so that you can access the data in both your bungee and spigot as well as make life easier when querying for data
you can use my project to request the data from the spigot server where all of your manager stuff is
even if you don't decide to use my project specifically, you will have to reach over the network somehow to get your information from spigot to bungee
the most 'default' alternative is plugin messaging which is built into spigot and bungeecord but it's terrible and stinky so don't use that
you can also make your own rest API using spring boot or use a more professional messaging service like redis or rabbitmq to send messages
sure thing ๐
also in case you were asking about how to access your actual manager object from bungee, that's not possible - the most you can do is 'serialize' it (turn it into [usually string] data that you can actually send somewhere, instead of being a java Object) and send that data across where you can rebuild a copy of the object and use that copy as needed
but you're probably just looking to get a specific piece of information to/from your manager at any one time, in which case what i originally said is what you want to do!
even static methods won't help you with what you're trying to do sadly
you can definitely work around needing to access your manager object directly on the bungee side, again by using my project or anything else to send a request over to call any method on the object you want on spigot's side, then return the results to bungee where you can interpret them
guys does anyone know how to refresh scoreboard
ASM/ByteBuddy
ByteBuddy will probably be easier
thank you Yugi
Hi, why this return the text
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] words = line.split(" ");
if (words[2].equalsIgnoreCase(player)) {
sb.append(line).append("\n");
}
}
return sb.toString();
But this return ""?
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] words = line.split(" ");
if (words[2].equalsIgnoreCase(player)) {
sb.append(line).append("\n");
}
}
});
return sb.toString();
Why do that when you could just put the method call in the task?
because your method returns the value of sb.toString() before that task is scheduled
you could use CompletableFuture.supplyAsync if you really need to run that async
Ooh
Okay, thx
well the file can have like 30k lines so ig its good idea to run it async?
hm?
wdym
what's inside the file
uh uh
I'm sure there's better ways to do this instead of constantly reading the file
how 
well, depends what you are trying to do
you do /paste <nick> and it paste the <nick> logs to paste site
right
CompletableFuture.supplyAsync(() -> {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] words = line.split(" ");
if (words[2].equalsIgnoreCase(player)) {
sb.append(line).append("\n");
}
}
return sb.toString();
});
this still return "", what am I missing
make the method return CompletableFuture<String> and return CompletableFuture.supplyAsync()
and then, where you call this method you do method.whenDone() or something like that,
tysm
does anybody know how to make an entity's first letter in the name a capital if we are checking like this:
entity.getType().getName().toLowerCase()
i want it to go from zombie to Zombie
d; Character#toUpperCase
public static char toUpperCase(char ch)```
Converts the character argument to uppercase using case mapping information from the UnicodeData file.
Note that Character.isUpperCase(Character.toUpperCase(ch)) does not always return true for some ranges of characters, particularly those that are symbols or ideographs.
In general, String.toUpperCase() should be used to map characters to uppercase. String case mapping methods have several benefits over Character case mapping methods. String case mapping methods can perform locale-sensitive mappings, context-sensitive mappings, and 1:M character mappings, whereas the Character case mapping methods cannot.
Note: This method cannot handle supplementary characters. To support all Unicode characters, including supplementary characters, use the toUpperCase(int) method.
ch - the character to be converted.
the uppercase equivalent of the character, if any; otherwise, the character itself.
Hi, I have concurrency question:
So there is this method:
private String getPlayerViolations(String player) {
Bukkit.getLogger().info("getPlayerViolations; executed on thread: " + Thread.currentThread().getName());
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> fetchPlayerViolations(player));
try {
return future.get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
return "";
}```
getPlayerViolations is executed on main thread, fetchPlayerViolations is not
My question is: Will be the main thread blocked until fetchPlayerViolations return value (because getPlayerViolations is waiting for that) or no?
get/join will wait until the future is finished before returning
Defeating the purpose of asynchronous execution
thenApply I believe
the then functions
You would pass a function that defines what needs to be done once the future is complete
DocDex bad?
You cant return from there without blocking
you don't "return" it, you tell it "run this thing when the string is available" which would be by tomorrow morning for all that matters
Instead you pass a continuation
cf.thenAccept(string -> /* print it or something idk */)
// sql helper library
public class SQL {
private Connection connection;
public ResultSet query(String query, Object... parameters) throws Throwable {
String formatted = String.format(query, parameters);
CompletableFuture<ResultSet> results = CompleteableFuture.supplyAsync(() -> {
try(PreparedStatement s = connection.prepareStatement(formatted)) {
return s.executeQuery();
} catch (SQLException e) {
System.out.println("Something went wrong with your sql query");
throw new RuntimeException();
}
});
return results.get();
}
}
what do you think ๐
you should return the Completable Future itself
um why?
because you're running it async
.get means you can use the resultset ๐
and it may not exist in the time you call return
only if it exists
maybe you should wait for it
CompletableFuture#complete
it will exist
thats what supplyAsync does
anyway
uh
what
it's ok
it does put it in the completable future
Jql injection ๐ค
you can try it out
yeah i will try it

i sent it in another discord and someone said "bobby tables" what does that mean
I think I should take a nap and then make some coffee
ok but do u like the codes?
uhm
it will be the base for my hypixel framework
why do you use supplyAsync, when #get waits anyway
?
d;jdk CompletableFuture#get
V get()
throws CancellationException, ExecutionException, InterruptedException```
Waits if necessary for the computation to complete, and then retrieves its result.
CancellationException - if the computation was cancelled
ExecutionException - if the computation threw an exception
InterruptedException - if the current thread was interrupted while waiting
the computed result
why isnt it necessary
you're literally calling it instantly after you're running it async
either i'm dumb or i'm right
well you could be both
Your what
thats what i thought
hypixel framework
im recreating hypixel and i need a optimized framework to start
so i made this
Ah ok
fair enough
fair enough
see but consider the following: what if I didn't pay you for that
you can setup Prometheus and Grafana and a nice open source plugin to send data easy peasy
Especially with Pterodactyl panel
get rekt chazza
Wow insanely fast
I mean, thats fair, in which case you aren't my target audience, My target audience are those who don't want to fear maintaining solutions, dealing with the upkeep involved. Instead, they want to focus more time on their server instead as they value that, and let others handle the work for only $5 - the same monthly cost as your grafana, except they can sleep easy at night ๐
I know which solution I'd prefer, I've done self-hosted crap in the past and its such a burden, especially when shit goes wrong
Grafana self-hosted is free my man
$0 is a pretty reasonable price, but yeah if you don't want to bother I'm sure your thing is okay
optionalUser.ifPresent(user -> e.message(Component.text(
ChatColor.translateAlternateColorCodes('&', String.format(
"%s %s%s &8&l> %s%s",
user.getGroup().getPrefix(),
user.getGroup().getNameColor(),
p.getName(),
user.getGroup().getChatColor(),
PlainTextComponentSerializer.plainText().serialize(e.message())
))
)));
Hey so I have this code in an AsyncChatEvent in Paper 1.18. However ingame this results as seen in the image. (https://imgur.com/a/98BzG4J) Anyone know how to get rid of the first part? Tried the renderer already but that one also had no success
If you use components, dont serialize the message just to combine it with a string. do append(e.message())
But I have a db where the prefix is set, how would I get that in the e.message() component?
the chat color is &6 (string)
Ok, I would suggest to use ChatColor instead. Then, convert it into an Adventure NamedTextColor. Next, you should use components something like this
text() // this returns a builder
.append(text(getPrefix() + ' '))
.append(text(p.getName(), /*prefix as NamedTextColor*/))
.append(text(" > ", NamedTextColor.DARK_GRAY, TextDecoration.BOLD))
.append(e.message().color(/*chatColor as NamedTextColor*/))
.build()```
then set this as e.message()
Ahh lovely
However the problem still exists that there a white <Smidgeee> in front of the format
d;paper AsyncChatEvent
public final class AsyncChatEvent
extends AbstractChatEvent```
AsyncChatEvent has 1 all implementations, 3 methods, and 1 extensions.
An event fired when a Player sends a chat message to the server.
Yea I've looked at it, but cant seem to figure it out :p
Ah, yea
Well, message() is only the message
You have to use that render method to set the format, and for the message, e.message(e.message().color(chatColor as NamedTextColor))
Yea I've tried since render uses 4 arguments (player, component, component, audience). However when I try for example e.renderer().render(p, Component.text("hoi"), Component.text("hallo"), e.viewers().iterator().next()); just to test and I am only online, I see the following https://imgur.com/a/UzEiCiD
Doesn't matter what I fill in it keeps holding on to those arrow brackets
Hmm, from the params of that class I assume is something to interract with the default chat forma <%s> %s 
Ah, no. Thats the default format
Yea the default mc format
But can't seem to find a function on the event or renderer about changing that
public interface ChatRenderer```
ChatRenderer has 3 methods.
A chat renderer is responsible for rendering chat messages sent by Players to the server.
something like e.renderer((player, name, message, viewers) -> /*create the component here*/)
Hmm not exactly following ๐ sorry
It's an interface right? How would I make a new instance of it
Ooh
I get it
the renderer is an Interface, you can try e.renderer(new ChatRenderer {}) and your IDE will most likely say it can be replaced with what I said
So the inside that arrow function I would create the message like I wanted to do with e.message right
This component, yes
Ah yes, let me try that real quick
Got it to work, however how would I go from &6 to for example NamedTextColor since I want to keep it flexible with multiple ranks
As in is there an easy way to go from for example ChatColor to NamedTextColor or TextDecoration
D;adventure style
public interface Style
extends Examinable, Builder>```
Style has 1 fields, 16 methods, 2 extensions, and 3 super interfaces.
A style applies visual effects or extra functionality to Components, such as TextColors, TextDecorations, ClickEvents etc.
Some examples of valid styles:
A note about fonts: the Key in this context represents the resource location of the font in the same way as Sounds
4.0.0
@winter nimbus try to work with this
np
Literally java.lang.NoClassDefFoundError: org/bukkit/plugin/Plugin
send ur utils class
show the entire class Symbol ๐คท
Paste Services
When asking for help with a config/menu/code issue please use our paste bin:
(we prefer it over pastebin.com)
โข HelpChat Paste - How To Use
what is line 25?
Do you have 1.18 nms installed?
Probs not honestly lol. But would still have the issue of not being able to access the methods from the 1.17 jar
I thought "provided" and remapped was the NMS jar?
Well yeah but you have to run build tools for NMS
Unless they fixed it no matter what I run gives me a bootstrap jar.

@echo off
set /p Input=Enter the version: || set Input=latest
set JAVA_HOME=E:\Java\jdk-17.0.1\bin
set PATH=E:\Java\jdk-17.0.1\bin;%PATH%
java -jar BuildTools-#141.jar --rev %Input% --remapped
pause
What files does the NMS jar contain? So I know if buildtools output the right file. @dense drift
You'll be able to access net.minecraft.server imports.
So with the 1.18 update, buildtools turned into a bundler jar, meaning you have to go into the libraries in the meta-inf to access the NMS jar.
You might be able to still use NMS on spigot through the maven plugin that md_5 wrote. Not sure tbh, I really only use Paper now which has paperweight.
https://paste.helpch.at/amikecelim.cs I am getting a weird error with my bungeecord command, can anyone help?
I can't depend on this jar though.
I was told use the remapped classifier in pom which I did but still can't access the methods or fields.
Paper ๐ฅฒ
Ahh okay, yeah I won't be any help here then. I've never used what spigot offers for that. Paper's stuff works with Spigot too as long as you don't use any Paper-specific stuff.
What is line 19 riches?
I understand that the "info" variable is null, I just dont udnerstand why
this has always worked in the past
Can you print getServers ?
yeah, one sec
lobby-1=BungeeServerInfo(name=lobby-1, socketAddress=localhost/127.0.0.1:25567, restricted=false),
lobby-0=BungeeServerInfo(name=lobby-0, socketAddress=localhost/127.0.0.1:25566, restricted=false)
}```
Weird
Ok I kinda got the NMS jars to work in the build path but now another field is erroring.
WorldServer s = ((CraftWorld) this.location.getWorld()).getHandle();
Type mismatch: cannot convert from ServerLevel to WorldServer
Any ideas?
yes...
does java/kotlin have a method to turn a collection of objects into an <Object, Integer> map where the key is the object and the value is how many occurrences of that object were present in the map?
Edit:
collection.groupingBy { it }.eachCount()```
So you either need to convert it, or those aren't the same thing
WorldServer is craftbukkits interface of ServerLevel. but with the 1.18 jars being used it won't let me use WorldServer (Using org.bukkit.craftbukkit.v1_18_R1.CraftWorld)
How do I set the headowner of a skull using username? I have a custom items, and they include the option to set the item as a player skull. But Bukkit.getOfflinePlayer(String) is deprecated. I know you can use UUIDs to set the skull owner, but it can get annoying to enter UUIDs instead of usernames. Do I have to store this data my self to make it work?
Bukkit.getOfflinePlayer().getUniqueId()
is there a reason you want to use getOfflinePlayer over just getPlayer
SkullMeta#setOwningPlayer(OfflinePlayer)
And I assume it would be easier if you can get a players head even if they are offfline
if you only want to get the head of online players you can do Bukkit#getPlayer(name)
then get the uuid from the online player, and use that to get the offlineplayer
if you want to get the skulls of offline players i recommend using mojang's api to get the uuid of any player based on their username
since that will also allow you to get the uuids of players that have never joined your server
doesn't spigot also do that?
do they? idk tbh
I believe so
Warning.png This service was closed down by Mojang on 8 October 2021 due to incorrect status responses ,saying "it was a legacy system running that we (as you might have noticed) did not update correctly, or held an accurate representation of our services". See WEB-2303 (comment) ```
How do I do it with spigot in that case?
man I hate the git used by spigot, so annoying to work with
?paste
Paste Services
When asking for help with a config/menu/code issue please use our paste bin:
(we prefer it over pastebin.com)
โข HelpChat Paste - How To Use
anyone know how to fix this (pls ping me) https://paste.helpch.at/efubedopap.xml
idk what that is from but their api still works fine
"API Status" was removed I think not the api.
^
Ohhh
They had a "status" endpoint and it rarely returned the status properly.
Why fix something when you can remove it instead, right? ๐คฃ
Microsoft for you lol
mojang should remove chunks and redstone and lighting
Hello, how to handle pressure plate deactivation event?
declaration: package: org.bukkit.event.block, class: BlockRedstoneEvent
IDK if it works but with a shit ton of casting I don't have an error anymore lol.
WorldServer s = ((CraftWorld) this.location.getWorld()).getHandle();
To;
net.minecraft.world.level.World s = ((net.minecraft.world.level.World) (((World) ((CraftWorld) this.location.getWorld()).getHandle().getWorld())));
Since I have never worked with this kind of stuff, I found this https://bukkit.org/threads/how-to-convert-uuid-to-name-and-name-to-uuid-uising-mojang-api.460828/ guide and now have this https://imgur.com/a/JDrXSSC code. However, it is deprecated, and I really don't wanna use deprecated stuff, is there a better way to do this?
i would probably use java's HttpClient for the api call
something like
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.mojang.com/users/profiles/minecraft/" + "Ivan8or"))
.build();
client.sendAsync(request, BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
then you can use something like gson to parse the json response
you can't just use internal jdk stuff
๐คท wasn't my code. But it worked ever since so didn't need to change it.
well it won't work anymore on Java 17+ without flags
Well shit. Ok time to find a work around thx
Damn didn't work lol
And, umm, how do I do that. I have no clue how this works. And google isn't very helpful
anyone have a solutn?
JsonParser parser = new JsonParser();
JsonElement neoJsonElement = parser.parse(myAPIResponse.asString());
String uuid = neoJsonElement.getAsJsonObject()
.get("id")
.getAsString()
something like that should work to parse it, not 100% sure this code is exactly right as i havent tested it
this seems like a decent tutorial that walks you through this ^
https://www.twilio.com/blog/java-json-with-gson
All that and the server doesn't even contain ServerLevel ๐คฆ I hate how bad they messed up 1.18
Caused by: java.lang.NoClassDefFoundError: net/minecraft/server/level/ServerLevel
How do I get the response? Sorry for asking so much, I've just never dealt with these kinds of things before. Also, I usually avoid getting spoon fed, idk why I am doing this, I just can't find anything useful online...
Well that's probably them undoing md5's weird mappings
It's probably not in net.minecraft.server
Welp I deleted all that and restarted with the original code WorldServer s = ((CraftWorld) this.location.getWorld()).getHandle();
None of the jars allow the use of WorldServer So I'm honestly at a loss right now.
i had posted this earlier, but here's a modified version that might be a bit easier to understand
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.mojang.com/users/profiles/minecraft/" + "Ivan8or"))
.build();
// this will threaten to throw an error so surround it in a try-catch
// also, calling .get() immediately on the main thread is a BAD idea in your plugin - make sure your main thread doesn't get blocked
HttpResponse<String> response = client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).get();
// parse this value with your gson parser
String responseBody = response.body();
hey I would neeed to make place holder in another placeholder xd
could you tell me will this work
so %cryptocurrency_topplayer_3% will return player name which is top 3
now I would need to make another place holder with this one in it
like %cryptocurrency_%cryptocurrency_topplayer_3%_balance%
will that work
what would be best way to make it in my PAPI Extendion?
That will not work
You will need to do %cryptocurrency{cryptocurrency_topplayer_3}_balance%
I think that is the correct syntax
No
why for then {}
This is the one iirc PlaceholderAPI#setBracketPlaceholders
yes
How could I handle message like this in java? So it automatically assigns each [some word] to a variable?
For example:
[name] Peter
[age] 21
[reason]y not
Shouldn't this be it? https://imgur.com/a/0I1UbIX It gives me a regular Steve head.
Reflection?
how would reflection help me?
Get the field by name and set its value
[name] Peter
[age] 21
[reason]y not
this would be the string i have and i need to parse it so i could put it's contents in a embed
Parse it how?
imagine I paste this:
[name] Peter
[age] 21
[reason]y not
in a text channel on discord, ok?
I need to handle it so it adds name to name field on embed etc.
i know how to do it on the discord side
how can i get the separate fields from the message
Well, thats a different story. I assumed that variable means a field from a class
You can use a regex like \[(?<name>\w+)] (?<value>.+)
ok
thanks
and what could I do if some idiot tries to one-line all of it?
like what could i do to prevent that
This does not work for me, Java ItemStack i = new ItemStack(Material.PLAYER_HEAD); SkullMeta s = (SkullMeta) i.getItemMeta(); System.out.println(s.setOwningPlayer(Bukkit.getPlayer(UUID.fromString(uuid)))); i.setItemMeta(s); System.out.println(i); It just gives me a plain Steve head, even though the first Sysout prints true? The itemstack also has no meta attached to it
Ok... I got everything to not error in the code using the jar Spigot\Spigot-Server\target\spigot-1.18.1-R0.1-SNAPSHOT-remapped.jar after building with buildtools.
However, the server outputs Caused by: java.lang.NoSuchMethodError: 'void net.minecraft.world.entity.decoration.EntityArmorStand.setLocation(double, double, double, float, float)'
Offline mode server by any chance?
Yeah
The uuid string is valid btw
UUID is fine, I can get a player from it. The ItemStack is fine since the material prints as it should. The meta is fine and it applies correctly. But the owner does not work, I have a UUID and a valid player, the sysout prints true, still, it does not work?
Also, setOwner() works fine, so the connection is good as well
@queen plank Are you trying to get a player that hasn't logged in before in the server?
The player works though, I can get the name of them
Hello! Im trying to make my plugin work with PlaceholderAPI but I have problems with it, is there anyone who can help ?
?help
ยป Give the helpers some details
ยป Ask suitable questions
ยป Be polite
ยป Wait
Are there in any way that you can disable mouse movement completely?
Origin Realms can do that and I wonder how.
if it's the mouse cursor you care about I think having a player open an inventory resets their mouse to the center of the screen? maybe?
so maybe that's something to look into and play around with
or do you mean preventing a player from turning their head in which case you can cancel their playerMoveEvent
I mean that yes, but completely disable it, with PlayerMoveEvent you can still move your head.
It does
How OR manage to do that, hmm
are you saying that cancelling playerMoveEvent doesn't completely prevent the player from turning their head
It does
With that the screen can get very glitchy.
Have you logged on to Origin Realms?
i'll log on just because i'm curious
It'll amazed you
i found the address, where can i experience their supposed witchcraft with preventing head turning
Yeah, not in that part tho
if they had a way to completely disable movement why wouldn't they do it there
but okay, i'll try to find the cosmetics
where's it at
Because the cinematic is moving and the cosmetics stationary I guess.
oooh i see
you know what i think is happening
it's possible they forced the player into spectator mode and made them inhabit a stationary entity
Ah
not sure if that's possible though but that would explain it if it is
Smart, that's possible tho
yeah that seems like what they're doing
weird that they don't use it elsewhere that seems much better for animations than moving the player's head
I heard that spectator mode is really breaking
idk much about if that's true or not
If you force player to go into mob's view, does the hotbar will be shown?
probably yes, but they probably solve that with textures
You can also disable teleportation and exit mob's view too right?
@prisma briar they pretty much use an npc that gets ur skin and works like you were em, then you get moved into spectator mode and forced into that place
thats the most obvious, good and easiest way to do so
Yes I know that, I'm asking about the head movement
where you rotate?
You can't move your mouse
they just cancel the player move event
or maybe they force you into a mob
idk if possible
I've tried the player move event, and I'm gonna try the spectator mode now
theres definitely a way to cancel both just not sure if its in the spigot/paper api or if you need to make it happen with nms
Alright, thanks
Can player enter an armor stand?
Or I need to spawn a mob that don't have goals.
Okay that's useful, thanks
Can you also prevent the hotbar from showing up when in spectator mode?
Is there any way for me to overwrite the bungeecord default logger as I want to get rid of messaged like
[_LightDream|/ip:port] <-> ServerConnector [server] has connected
@torpid raft another question, If origin realms use spectator mode on that, how come I cannot see the invisible armor stand that ride the player when using backpack cosmetic?
maybe they use some packet shenanigans to hide it from you, not sure tbh
or texture stuff
You can see the backpack, so you see the entity otherwise.
๐คทโโ๏ธ
Man, how did they find this out xd
Can you try to give them an invisibility effect?
My ReactJS (typescript) project only searchs for an index.html in public/ instead of index.tsx in src/ when i run it
Shouldnt tsx be transpiled to js with a generated index.html?
Yeah, index.html is the entry point that "runs" the app.tsx
normally my thing just autoruns the index.tsx without me even having to touch the /public directory
anyway I can make a villager stationary but look at player without NMS?
teleport every tick ๐คท
I think that would look janky tho
maybe #setTarget(null)
void setTarget(@Nullable LivingEntity target)```
Instructs this Mob to set the specified LivingEntity as its target.
Hostile creatures may attack their target, and friendly creatures may follow their target.
target - New LivingEntity to target, or null to clear the target
and maybe tp every tick to be safe
and make sure to disable damage via EntityDamageEvent
hmm
#setAware(false)
alright, I will have a look
What is your obsession with tping every tick that sounds rather performance inefficient
yeah that's pretty bad lol
Is is possible to allow certain people (ex. with a permission) to not take up server slots?
Essentials have permission to join a full server, but I'd like something like, ex.:
100 online players / 100 slots, and 5 online staff, but they a won't count towards the total online count.
no, but you can set the slots to like 120 and show n/100 players online, the other 20 slots will be handled differently
Currently it'd be like 100 online / 105
oop
tping every second
๐
How can I disable another plugin's command?
you can remove it from the CommandMap
how?
Have been trying to figure this out but it isn't working
Bukkit.getPluginCommand("vote").unregister(new SimpleCommandMap(Bukkit.getServer()));
getCommand("vote").setExecutor(new VoteCommand());
Is this correct?
no even close.
I assumed lol
are you trying to completely unregister it or do you just want yours to take priority instead?
Either would work
pre procecss event!
Unregistering it may be cleaner
no and no
How would that relate?
check command and send "This commandd doesnt exist. Use /help" xddd
But that wouldn't make my own /vote command take priority, no?
ahh you wanna unregister an existing one, to register yours?
I'm trying to unregister "vote" from SimpleVotes
may i ask why
No
The default command is pretty bad as from what I know I can only add url's instead of TextComponents with hover and click events which i think would look better
ahhh, you can always listen to pre process command event and if its vote or simplevotes:vote cancel event and send your message
ยฏ_(ใ)_/ยฏ
๐
Why does IntelliJ say that I got no executable code on this line when debugging lol
how am I supposed to check the if statement
You probably added code inbetween at somepoint after the state of the built jar
Oh right that makes sense
Having some issues with manifesting my jar, never had this issues before.
what I know: my gradle script has added the manifest, all the packages are the same as the one referenced in the gradle script
What I don't, why it gives me the error:
Caused by: java.lang.ClassNotFoundException: me.alexirving.bot.SimplyMod```
Even though it has been manifested to it. I've used this script many times over the past few months with 0 issues.
plugins {
kotlin("jvm") version "1.6.10"
id("com.github.johnrengelman.shadow") version "7.0.0"
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.6.0")
implementation("net.dv8tion:JDA:5.0.0-alpha.4")
implementation("ch.qos.logback:logback-classic:1.2.10")
}
tasks {
shadowJar {
archiveFileName.set("${project.projectDir.name}-${project.version}.jar")
}
jar{
manifest {
attributes("Main-Class" to "me.alexirving.bot.SimplyMod")
}
}
}``` this is my gradle script
I would suggest using the application plugin for that, then you can set the main class with
application {
mainClass.set("me.alexirving.bot.SimplyModKt")
}
the Kt at the end is needed assuming your class is a Kotlin class
^
ah is that the issue ig, I feel like ive manifested some of my kt stuff.. whatever. thanks
Thanks for the help matt! worked, does the application plugin add anything else useful I should know about ?
I'm having problems playing a sound using paper's api.
git-Paper-175 (MC: 1.18.1) my server version.
My attempts:
val musicDisc = Sound.sound(Key.key("music_disc.13"), Sound.Source.MUSIC, 1f, 1f)
player.playSound(musicDisc)``` (this is the example from adventure.)
I also tried playing a Sound that's deserialised using configurate from a .config file. This is the sound I tried
```json
sound {
name="block.ancient_debris.break"
source=master
pitch=1
volume=1
}```
but it doesn't seem to work. tried adding the namespace before as well (minecraft:) but still no luck. my volume is all at 100%. minecraft and computer sound I mean.
try master
what about Player#playSound(Location, Sound.?, int, int)?
works fine for me
there is a ancient debris break sound and a music disc 13 option on the Sound enum
am using adventure's sounds not spigot's
oh
but you know, I just realised. I am async teleporting the player right before. maybe it plays the sound at the old location.
ah
oh yeah that was definitely it
jesus my ears xD
I just played 8 sounds at the same time on full volume
So i'm creating a levelup plugin that would have /levelupmax and they have unlimited levels. So basically just a prestige plugin, but levels instead so when you do the command it will level you up as many times as you can sometimes it can be millions. How would I do that. Iโm currently using a for loop but looping a million times would lag the server any ideas on how I would do it without looping so many times
I keep getting the nag author... for not properly shutting down its async tasks but the thing is I am closing the task on disable. is there something else I need to do?
my disable:
override fun onDisable() {
locationGeneratorTask.cancel()
log("Plugin disabled successfully!")
}```
and my task declaration:
```kt
locationGeneratorTask = GenerateTeleportLocations(this).runTaskTimerAsynchronously(this, 0, 150 * 20L)```
if you reloaded, don't do it, restart
Calculate cost-per-level and check their total balance.
@EventHandler void noMove(InventoryClickEvent e){
Player player = (Player) e.getWhoClicked();
if(!e.getCurrentItem().getType().equals(Material.SHIELD) && e.getSlot() == 40){
e.setCancelled(true);
player.sendMessage(ChatColor.RED + "You can only place shields in your offhand!");
player.playSound(player.getLocation(), Sound.ENTITY_PIG_HURT, 2.0F,2.0F);
}
}```
Why does remove the item that the player puts in their offhand
Why paper has deprecated the string versions of certain things? For example ping event's .setMotd("") is deprecated in favour of .motd(Component)?
They're deprecated as components are better suited arguments than strings
if you need a text component, I believe the method is Component.text("")
Hmm, thanks for the information. ๐
Bukkit has an api for getting user's input, is callled the conversation api
add a default to the switch statement, then log what it spits out if it hits default, it is possible the switch statement isn't matching any criteria therefore isn't getting cancelled
no worries ๐
Has anyone here used ProtocolLib?
I'm having trouble spawning a fake ground item. (client side only ground item)
I have an armour stand spawning correctly with it's name but i want to display an item too.
Currently it spams an item shadow like it's spawning and de-spawning instantly
Can someone help me why my website cannot get the css file? it says not found, but it's clearly exist. The code is in welcome.blade.php and this is the stylesheet
<link rel="stylesheet" href="../assets/css/style.css">
<link rel="stylesheet" href="../assets/css/components.css">
isn't views in assets? if it is you should be using ../css/style.css
It's not inside assets directory
can you do this and send me a screenshot of what it prints
var_dump($_SERVER['SERVER_NAME'] . '../assets/css/style.css');```
This will show your paths
(you will have to put that in your welcome.blade.php and ofcourse wrap it in <?php ... ?>)
Also feel free to ping me when you reply
string(9) "127.0.0.1" string(32) "127.0.0.1../assets/css/style.css"
The auto completion is there, but I don't think it points directly to the file, idk.
so resources is your root directory?
and is welcome.blade.php loaded directly or is it included from a wrapper class?
It's from the web.php
right ok so you'd have to do your paths from web.php then not from welcome.blade.php
try changing it to
./assets/css/style.css
hmmm
i do my paths like this:
<link href="<?php echo Utils::getPath(); ?>assets/plugins/fullcalendar/css/main.min.css" rel="stylesheet">
then i have a static class Utils
then the getPath(); is:
public static function getPath(string $file = ""): string
{
return ($_SERVER['SERVER_NAME'] === "{alias}" ? "/" . $file : "/{alias}/" . $file);
}
but you could probably just have it as
public static function getPath(string $file = ""): string
{
return "/" . $file;
}
alternatively if you don't want the statics just do
<link href="/assets/css/style.css" rel="stylesheet">
I also tried to put the assets directory on the root folder.
if the assets directory is in your root then it will work as / takes the path to the root directory
Still doesn't work.
it doesn't work with putting it as:?
<link href="/assets/css/style.css" rel="stylesheet">
hmmm lets try one more thing first
<link href="<?php echo __DIR__; ?>/../assets/css/style.css" rel="stylesheet">
if you
var_dump(__DIR__ . '/../assets/css/style.css');
it should look something like:
127.0.0.1/views/../assets/css/style.css
if your path is like you sent earlier
yeah try that
It goes to deeper directory.
also this image...
why are you navigating to 127.0.0.1:8000/resource/assets/...
resources will be a directory that is negated via .htaccess i'm assuming
so try 127.0.0.1:8000/assets/
Not found
Hmmmm
i've not really used laravel much, i usually do bespoke php (without a framework)
just a quick lookup from laravel formats
<link href="{{ asset('css/styles.css') }}" rel="stylesheet">
should work
or if it's a subview use:
@stack('styles')
you'd also put your css files in the public directory
{{ asset('') }} basically getting the server's ip
yeah it generates a direct path to the file requested
href="http://127.0.0.1:8000/assets/css/styles.css"> this is the result from {{ asset('assets/css/styles.css') }}
Let me try that
Even when I'm created a new style.css file inside the public directory, the website couldn't find the file.
yeah because they are protected by laravel
The result of view-source:http://127.0.0.1:8000/public/style.css is not found.
Put styles.css inside of /public/css/
in welcome.blade.php inside the <head></head> add <link href="{{ asset('css/styles.css') }}" rel="stylesheet">
then navigate to the page you're wanting to use
No need to use public/css/...?
nope, laravel will automatically parse everything
Still, not found
can you send me your welcome.blade.php
can you send me another screenshot of your updated file structure ๐
oh you was saying it was called styles.css earlier, it's actually style.css ๐
True my bad, but it doesn't work If it's not in the public directory.
Also when you're workign with frameworks, be sure to clear the cache also, as it will cache when it can't find a file then only check for the file again after a certain amount of time
to make it work outside of the public directory you'd use the same line but instead of having
<link href="{{ asset('css/styles.css') }}" rel="stylesheet">
you'd use
<link href="{{ asset('path/to/dir/css/styles.css') }}" rel="stylesheet">
You're welcome buddy ๐
Can anyone assist with this?
What version and show code
Hello, since getDisplayName is deprecated, what should I use instead?
displayName
lovely, thanks
what would be the best way to load and save locations based on what chunk they are in?
I was told that its better to save custom block data by what chunk they are in then loading the entire database of data
So getters are now legacy? ๐ค
Or is it a new naming convention
To use the same method name, just one with overload
paper thing.
displayName() uses components
getDisplayName() uses strings
that's not deprecated in spigot since they didn't move to adventure
?
?
Main thing sucks that building with paper and publishing it on spigot and telling people to use paper since it's better is not allowed by spigot ๐คก
I mean
you could relocate adventure. but yes. I know
I got my resource edited by their staff team bcz I told people to use Paper
lmao
I could, just extra hassle tho
Same
really waiting for Hangar so I don't have to deal with spigot at all after that.
Is that like paper resource forum or smt?
Hangar will be super pog
First time I hear abt it
Just checked it's github, I understand now
If I understand correctly, you just deploy your resource directly to it instead of building a jar and uploading it as attachment or smt?
i want to save to sqlite if a block has been broken before or not, for every block that exists in the world, which i was told would be better done if i load the data when the chunk is loaded and saves when the chunk is unloaded, im not sure where to start.
ive already have a way to figure out if a blocks been broken or whatever, its the saving and loading of that data to and from sqlite that i dont know what to do
Couldn't you just put some data on the block when it's placed?
And know that way
Idrm it's possible for blocks, maybe only tile entities
i currently have a hashset of locations.
its basically going to be a plugin repositroy just for paper plugins. You can see here the testing https://hangar.benndorf.dev/
I guess it depends on what you need
no paid plugins afaik either.
would it be better to just query the sqlite database every time a block is updated based on if i call it player placed or not
Not monetizing countless hours of debugging two lines of code?
Unacceptable
As far as I know mcmarket is the only other plugin resource place, right?
Or are there more I'm not aware of
nah
there's quite a few. one that's I guess a bit more known is polymart or whatever it is called
I need some help, I am kinda lost. I am working on a Minigame, and when joining the Game you automatically get put in the next available Team. that works fine, the only problem is that everyone gets put in Team RED until its full and then it goes to the next empty one. How would I make it so it balances the Team?
its probably super simple
https://paste.sentinalcoding.eu/2H9F1XGJ1r this is the current Method which picks a Team
Just check the amout of members before placing someone in a team?
have a global counter for players in a team and a method to pick the team with the lowest number
you can even do the counting in your loop
Loop through teams, get the one with lowest amout of members, place in it
ยฏ\_(ใ)_/ยฏ
oh just looked at your code
you could literally have a minPlayer variable that saves the minimum amount of players a team has, and if the current team in the loop is smaller than minPlayer change the min player amount and also the current selection
private TeamColors getLowestTeam(){
java.util.Map<TeamColors, Integer> result = new HashMap<>();
teamMapping.forEach((k,v) -> result.put(k, v.length));
List<TeamColors> collect = result.entrySet().stream().sorted(Comparator.comparingInt(java.util.Map.Entry::getValue)).map(java.util.Map.Entry::getKey).collect(Collectors.toList());
return collect.get(0);
}``` would something like this also work?
Sorting would be faster but slower 
And goddamn just import the packages ๐
And you can return without List assignment
Save space 
also to exit even faster from there, you could have a check for teamColorsEntry.getValue().length and if its 0 just set the current selection to that entry. since that means the team is empty so its the team with least players no matter the case
but this won't help that much if you only have like 2 teams