#help-development
1 messages · Page 2241 of 1
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:testCompile (default-testCompile) on project Build: Execution default-testCompile of goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:testCompile failed: multiple points
?paste
I'm still getting client server desync issues with this
int[] attempts = {0};
Bukkit.getScheduler().runTaskTimer(SuperiorSteed.getInstance(), task -> {
horse.addPassenger(player);
attempts[0]++;
if (attempts[0] > 20) {
task.cancel();
}
}, 0, 1);
😵💫
after both the player and horse are teleported the player is in a weird state where they can walk around
well it's not because of the array xd
but if they crouch they exit the horse and get teleported back
is there any other possible solutions anyone has?
ez
lines 27 and 28
you havent defined ${java.version}
BukkitTask task = new BukkitRunnable() {
int attempts = 0;
@Override public void run() {
//TODO
attempts++;
this.cancel(); //inside
}
}.runTaskSomething(plugin);
task.cancel(); //outside
OHH
but anyway bukkit is stupid
ty
yeah i got the task working but it still didnt fix the desync issue
BukkitScheduler#runWhatever(Consumer<BukkitTask>) returns void
could've returned a bukkit task instance
here's the whole function btw https://mystb.in/JimmyBulgariaFifty.csharp
fucking JDA does this all the time too >.<

I always have to wrap the sent messages into completeablefutures myself, it's so weird
is there like a "refresh" function or something
to alert the player to check if they're riding the horse
CompletableFuture<Message> future = new CompletableFuture<>();
replyTo.replyEmbeds(builder.build()).queue(future::complete, future::completeExceptionally);
why can't .queue() not just return a Future automatically
refresh what?
doesnt it return like restaction or sth lol
you could dismount and mount them again in the same tick, but that seems shitty. or send the mount packet yourself
not for .queue
is that so? lemme check
if i mount them right after the horse and player teleport, the desync happens
but if I wait a full second and then mount, it works fine
I need to find the right time to mount after the teleport, but this amount of time seems to vary
oh yeha indeed
well, too late now. I already wrote my own method for it lol
ok can u help me change my build directory from the Build Module to it's parent module target folder?
last time i tried, i deleted everything
is there a way I can read a player's packets to see if they think that they're riding a horse or not
well first of all, you should have a git repo so you cannot accidentally mess anything up
yeah inject the netty pipeline
lemme do this now
altho I assume that better alternatives exist okay1204
what is that
second of all, you want to have a parent pom that includes all your modules, and another "distribution" module. that one has all your other modules as dependency and combines it into the final jar
and is it complicated
that's how it is right now except the distribution is called build
as said, try to look at my lib and how I do it. I have a core module for all the bukkit stuff, and an NMS module for every version. Then there's the "dist" module that produces the final .jar
https://github.com/JEFF-Media-GbR/JeffLib
the dist thing has all the other modules as dependency and shades them
i'll just let it build to the target folder in Build then
is their some sort of hover event for inventories with nms I can use to stop item pop-ups when hovering over them
wanted it to build in the parent folder
why does it matter?
ig it doesnt
it seems like a dirty solution to me to build outside of the dist module's directory tbh
no
ok
i never commit the .idea folder
.gitignore are fine or those are excluded as well?
the .gitignore in the parent folder should be committed
ok
whats a .idea folder I only know .vscode
you can store all your good and bad ideas inside
intellij much more efficient than vscode. it only uses 4 letters for its hidden folders instead of 6 huehue
what about the gitignore in the submodules?
just commit them all, doesn't hurt lol
Must hide from the truth I can't let them know I know that 4 is less than 6
although you normally only have one .gitignore. do you have multiple nested git repos? 
show your .idea/vcs.xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
ok looks good
no idea why you have multiple .gitignores
i didnt make em
does this look fine?
yeah although I'd add all the unversioned files to your "proper" .gitignore
those gitignores are weird random stuff
np
^ we added those
Ok even priorities always confuse me, HIGHEST would be ran the last right? so it can also listen if the even is cancelled before it
HIGHEST is the highest priority so it can decide whether to cancel an event
Ya but like
if the even is cancelled at NORMAL priority
the highest can check if it was cancelled or not right
i mean yeah
say for worldguard
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
well
What does ignorecancelled do?
if the event is cancelled, the method wont be ran
wait so like
if the event is cancelled at normal priority
high/highest wont be ran?
wait the opposite? im confused
if it specifies that it should be ignored if cancelled
NORMAL cancels an event
if a HIGHEST listener has ignoreCancelled, the HIGHEST listener will be skipped
yup
LOWEST -> LOW -> NORMAL -> HIGH -> HIGHEST -> MONITOR
Ok just to see if i understand it right
if the even is cancelled at normal priority and the function which has highest priority and has ignorecancelled true will not be ran?
correct
ignoreCancelled = true means your listener will skip events that are already cancelled when your listener would get the event
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (args.length >= 1) {
if (args[1] == "test") {``` Would this be the correct way to use a check to see if `/kit test` is ran?
What's the difference between the two equals?
in theory, every string is a new object
so
String asd = "asd";
String asd2 = "asd";
if you now do asd == asd2, it would actually be false
it does work sometimes because the JVM caches strings
but you should never rely on that and you will get very weird results
just do not use ==
for strings
Could you show me an example of using .equals()?
?learnjava
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.
(I'm very new to java if you couldn't tell heh)
Gotcha
https://www.geeksforgeeks.org/difference-between-and-equals-method-in-java/ this is a good explanation 🙂
A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.
is there a main thread in bungee?
of course
Thank you very much!
ig i should have asked if there is a way to run something on a single thread
or if everything should be thread safe
Okay, one more thing...
Everytime I use the kit command, it sends /kit along with whatever the send is, how could I remove the /kit response?
https://fwoostyhub.com/🐪🏩🌱🎅 is what I'm talking about
that's the "help message". it gets sent when you return "false" in your command executor
you should return true instead to not show it
np
How would I make a command recognize a mob in the first argument? For example, /set-mob zombie
you can get an EntityType by using EntityType.valueOf("ZOMBIE") for example
make sure you uppercase the string
well if you don't specifically run anything async, then it automatically runs on the main thread. just like in spigot
well then how do i run something sync if i'm on another thread?
This interface represents a scheduler which may be used to queue, delay and execute tasks in an asynchronous fashion.
seems like u can only run async from that
ooh I misready
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (command.getName().equalsIgnoreCase("set-mob")) {
Player player = (Player) sender;
if (args.length == 1) {
Entity entity = Bukkit.getPlayer(args[0]);
if (entity instanceof Mob) {
if (entity.isInWater()) {
entity.getWorld().createExplosion(entity.getLocation(), 10F);
} else {
return false;
}
} else {
player.sendMessage("§cThat's not a mob, silly! Try specifying a certain mob for the command to work.");
}
} else {
player.sendMessage("§cPlease specify the mob that you would like to enable explosion upon contact with water. No more than 1 argument should be specified.");
return false;
}
}
return false;
}
I'm doing instanceof Mob, not sure how to incorporate the EntityType.valueof() function...
callSyncMethod?
I thought you wanted to run stuff async lol
nah
You could try callSyncMethod
i have no idea what you're trying to do there. You cannot just turn a string into an entity
also Bukkit.getPlayer("zombie"), this really makes no sense
lol
Right but when I do getEntity it makes me do the UUID
Oh bungee cord
ye
Nvm then
I'm trying to allow the user to enter the name of a mob and it would automatically recognize that and proceed with the code
i'll just use a concurrent hashmap to be thread safe
that makes no sense
what entity are you trying to get? ANY zombie that's nearby?
No, the user enters the command /set-mob *any mob here*, but I can't do that without making the user enter the UUID. I want them to enter a string. I was using the zombie purely as an example. It could be a parrot, creeper, chicken, you name it
ok but whaich mob are you setting?
Any mob
Entity entity = Bukkit.getPlayer(args[0]);
how will entity be a mob
it its a player
I completely understand that
Bukkit#getPlayer only returns Player.
i have no idea what ur trying to do
That's just messy trial crap that I'm entering for now
That code will throw an error.
I'm trying to make it a mob
Me neither
A player to a mob?
what is your end goal?
EntityType is what your looking for not Bukkit#getPlayer
EntityType#valueOf
They want to get some specific mob but no idea which one
But I can't without making the user enter a freaking UUID because getEntity() requires a UUID as an argument, not a string. However, this is a problem because the user enters a string. I want them to be able to do /set-mob zombie (zombie is an example, it can be any mob) and it would recognize that the user wants to set the zombie as the mob. AGAIN, however, it's forcing me to do a UUID. I don't want to make the player do this. Is there a way to make it so that they can enter a string and the code can recognize that it's a mob?
EntityType
no uuid's needed
you must be high off your ass
There is no Bukkit.EntityType thi
?learnjava
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.
I still dont get it. If a player enters „zombie“, how would you know which zombie to get? The nearest?
I'm new to this, no need to go this far lmao
EntityType is an enum
there need no be a Bukkit#getEntityType
that'd be redundant
Bukkit.getWorld("name").spawnEntity(location here, EntityType.valueOf(":String"));
this could have been solved by a simple google search listen the docs are useful but don't only use the docs
you'll fucking go crazy
private final ExecutorService pool = new ForkJoinPool(Runtime.getRuntime().availableProcessors() * 2,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
(t, e) -> e.printStackTrace(),
true);
2 threads per processor overkill for an executorservive for a db?
i feel like it'll be useful to a point
like 32 core cpus having 64 threads for a db it just too much
NO
it might be more
or even less
but yeah if you wanna limit yourself, just use the amount of available processors
does that mean it's fine the way it is?
yes well
parallelism is a representation of how many tasks it can process at once put simply
it might have some threads suspended etc
so the amount of threads could be more
ok just a question, what's the impact on performance when it isnt doing anything?
none?
well usually thread pools have an internal keep alive tme
which is...
if a thread is unused, how long should the pool wait until terminating the thread
but anyway, apart from that, thread pools almost always lazily create the threads
which means, 64 threads arent gonna be created just cuz u invoke new FJP(blah)
🙂
does anyone know how to set a horse's color? im trying to and it's not updating.
@river oracle How would I get the location like you said in the location here without an entity to work with?
show the code
Player location or whatever
Depends
Player location offset
Player view block
What entity you haven't spawned it
I'm not trying to spawn anything.
The entity that the player specifies in the argument will apply to all mobs in the server
and whenver that mob enters water, it explodes ( don't ask)
any mob of that type
Do you want it to explode when it goes in the water? Or do you want those in the water to explode when the command is run?
Well what you can do is have a Set<EntityType>
u add the entities u want to explode to the set
then what u can do is schedule a runnable that runs every x ticks, that kills those entities in water)
so all your command really does is add/remove the entitytype to the set
the runnable loops all entities and explodes them
is it bad practice to have multiple of the same event in one listener class
if it runs i think its cool
better organization
ive never thought of doing that because im unsure if the api allows it
it works but I don't want bukkit to be registering anything extra or whatever
I don't want it to cause anything performance-wise
nah its good
bump
@humble tulip I just ran some test w/fjp to see if it still works the same way it used to and rest assured
it is capable of using available processors * 2
in addition, the throughput is much higher
and the speed remains the same
but anyway, once java 19 releases youll probably wanna use virtual threads
(noticeably)
CompletableFuture is an abstraction over normal computation, it is sort of a computation builder
however in contrast of just being a computation builder, it also provides ways to do it async
with thread safety
I said its an abstraction, this is due to that it actually uses any executor you might pass it, although by default it will use its own executor which might be the fjp common pool provided that its parallelism is higher than 1 (or if it was 0)
a fork join pool is java's implementation of a work stealing thread pool
normal, traditional thread pools have a queue in which they pick off tasks and then throw them at the set of threads they encapsulate
fork join pool tries to split a big task into smaller ones, and in comparison, every thread in a fjp has its own queue
thus we usually use the name worker favored to thread
workers might detect that other workers have loads of small tasks queued, thus they can decide to steal those tasks from another worker
you can use them in combination
the real question I think you should be asking is, when should you used a cached one, vs fixed one, vs work stealing one
mye
well
thats one instance
since database requests is... calling an io device
where the request may take long time due to latency etc
well
it is advanced
but in simple terms, completable futures are a more sophisticated way of dealing with some function that gets dispatched in some executor (could be a thread pool)
depends
normally when you use a fjp, you'd use the amount of available processors
yes
altho the issue with that function is that it might change during runtime
(which well, to some extent isnt an issue Ig)
not really
well you'd be able to handle higher throughput faster
public interface Synchroniser {
void runOnMainThread(Runnable runnable);
}
Is this a good idea? It's for a plugin that supports both spigot and bungee and ^^ is part of the core. I need a way to return stuff on a thread that is suitable (eg. main thread spigot)
i dont think bungee cares abt which thread something is called from
sure, but that looks like an Executor
and synchronizer is a misleading name
it doesnt sync anything, it just dispatches the given runnable on your "main" thread Id assume
uh wym?
well SingleThreadExecutor or sth
hm makes sense
public interface SingleThreadExecutor extends Executor {}
as someone told me
processors != thread
else you would freeze your computer at 4 chrome tabs
i'm intermediate and i thought the same abt a week ago
dw
yeah well.. its all confusing, since people usually dont explicitly mention what type of thread, but newFixedThreadPool uses platform thread, which are basically os threads
(and well, there are more os threads than there are processors)
usually you have something called a blocking coefficient
t_wait / t_service
wait time is the time for io tasks to complete
service time is the time for processing tasks to complete
recommended value for nThreads is generally the amount of cores you have
not always
for fork join pool its usually beneficial
the way its algorithm works
but the general formula iirc is n_threads = cores * (1 + blocking_coefficient) where the blocking coefficient is twait/tservice
(and yes, it might reduce to the exact amount of cores you have)
mye hope u learned at least something lol
but anyway, if you have a cached thread pool, the maximum amount of threads is usually very high
so in that case its more the question of what tasks are gonna be dispatched by the pool (thus we talk about predictability when it comes to cached thread pools)
since it is bound to exceed the amount of cores you have
public class PlayerIP {
private final UUID uuid;
private final String IP;
private int numLogins;
private long lastLogin;
public PlayerIP(UUID uuid, String ip, int numLogins, long lastLogin) {
this.uuid = uuid;
this.IP = ip.toLowerCase();
this.numLogins = numLogins;
this.lastLogin = lastLogin;
}
public UUID getUuid() {
return uuid;
}
public String getIP() {
return IP;
}
public int getNumLogins() {
return numLogins;
}
public long getLastLogin() {
return lastLogin;
}
public void setLastLogin(long lastLogin) {
this.lastLogin = lastLogin;
}
public void setNumLogins(int numLogins) {
this.numLogins = numLogins;
}
}
im interested
ok i have this class but ideally, i dont want people using the api to set the lastlogin and numlogins
should i use an interface and have the last 2 methods as part of the impl?
given that their setters have no constraints on the inputs
Id facade the class with a proper interface
where you expose "safe" methods
[by safe, I mean the methods should disallow any unwanted mutations]
mye interfaces are nice
bump
gets really easy modular-ize and eventually... decouple your system
(but apart from that, static factory methods are also extremely nice)
that one is complicated
trying to work on something where i can learn a lot of good programming practices
normally i wouldnt care if people can do setLastLogin
ah yeah
I mean knowing your design patterns is always good
then java SOLID also sums it up
yeah that's what motivated me to do this
(tho generally, knowing canonical names of different patterns is always good as it helps formalizing them and communication concerning them)
ye
public class DebugLogger {
private static final DebugLogger instance = new DebugLogger();
public static DebugLogger getInstance() {
return instance;
}
public Logger logger = new Logger(AltLookupConstants.PLUGIN_NAME, null) {
@Override
public void log(LogRecord record) {
record.setMessage("[" + AltLookupConstants.PLUGIN_NAME + "] " + record.getMessage());
super.log(record);
}
};
public void log(String message) {
logger.info(message);
}
public void log(String message, Object... args) {
logger.info(String.format(message, args));
}
public void log(String message, Throwable throwable) {
logger.log(java.util.logging.Level.SEVERE, message, throwable);
}
}
should this be an interface?
forgot to make constructor private and set the parent logger
ignore those
Im concerned about the public variable
yeah i know it is lmao
but else Ig
but i'm really trying to figure this out
that was accidental
it'll have a method to enable/disable and it'll log only if enabled
well
some time ago
but since I wanted to use the logger of different platforms
like velocity, spigot etc
and they might have different loggers
so I created an adapter that would facade eventual platform loggers
but dont take after everything I do either, cuz sometimes I write code without reviewing it
I think I'll stick to a singleton since I'd like to be able to add debugs everywhere
ye
for logging its fine to have a monostate/singleton logger
but it comes at a cost ofc
of?
I mean you dont gain any abstraction
further more, you do end up hiding actual dependencies
how so?
^with that I mean, by passing your dependencies through constructors the intent of that said class is a dependency of another class becomes much more clear
ah
thats one of the disadvantages
the other one is unit testing
(which, nowadays is possible with using tons of singletons, its just that the testing procedure gets unnecessarily complicated as you need to fuck with classloaders and shit, altho there are libs to do that for u)
i guess i can abstract it and pass it to dependencies that need to do logging
one last thing
this is what my modules look like
i wanna "initiate" core in spigot and bungee
idek how i should do that
do you know of any projects with a structure similar to this that i can look at?
in core I'd have something like:
class CommonBootstrap {
void enable() {}
}
//in spigot
class CoolPlugin extends JavaPlugin {
CommonBootstrap boostrap = new CommonBoostrap();
@Override public void onEnable() {
boostrap.enable();
}
}```
whats the difference between core and coreimpl
it's the implementation of core
all the implementation of interfaces/classes
basically the underlying code of Core
i probably have a bad structure 😭
very possible since it's my first time working with multimodule projects
hm well core is like api rn
so i can rename core to api and rename coreimpl to core?
uh yes
but like api mostly consists of interfaces
just a facade, the keyboard.., the buttons of your coffee machine
how those buttons work is defined in core
that's what core is rn so i can rename it to api
alright
good luck
thanks
How do I make a tick event?
The home of Spigot a high performance, no lag customized CraftBukkit Minecraft server API, and BungeeCord, the cloud server proxy.
Then u can schedule a runnable that runs every tick and call the event
Although i dont see why u need one
How would I implement an autofill to my code? https://paste.pythondiscord.com/dozofufoju
For example, I need to set test to be an autofill with kit.
Let your class implement tabcompleter
Check if args.length is 1 and if it is, see if any of your kit names start with args[0] and rrturn a lidt of those kit names
Can i extend item stack?
Im making "custom" items and it would help me creating them easier
Create a class called customitem
And have a field that is an itemstack
And u can do customitem.isItem(ItemStack)
Also have a map ItemStack, CustomItem for quick lookups
May I have an example/documentations, please?
Look at what NickNiko posted
Comamnds will be ur subcommand eg. Testkit, otherkit
could someone check this https://github.com/ARR4NN/WardenDrops/blob/master/src/main/java/com/arr4nn/wardendrops/events/PluginEvents.java is it the right way to do a 50/50 chance
Yep
If u wanna be able to change those, u can use randon.nextDouble()
Check if it is < your chance
Your chance will be a decimal like 0.2
I'm so confused... it just simply has so many errors
Thanks, just had people complaining i think it’s just them being unlucky
Lol
I'm more or less just trying to copy and paste it and break it down, but honestly so many errors :P
That's just how randomness works
Show what u have
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import net.kyori.adventure.text.minimessage.MiniMessage;
import com.jordanhaddrick.rtm.Main;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.command.TabCompleter;
import org.bukkit.util.StringUtil;
public class Command implements TabCompleter {
private static final String[] COMMANDS = { "minecraft", "spigot", "bukkit", "google" };
//create a static array of values
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
//create new array
final List<String> completions = new ArrayList<>();
//copy matches of first argument from list (ex: if first arg is 'm' will return just 'minecraft')
StringUtil.copyPartialMatches(args[0], COMMANDS, completions);
//sort the list
Collections.sort(completions);
return completions;
}
}
I just copied and pasted whatever they had with a few more imports as I'll use them later on.
i was close enough
Class 'Command' must either be declared abstract or implement abstract method 'onTabComplete(CommandSender, Command, String, String[])' in 'TabCompleter'
reason: String[] is not compatible with Iterable<String> on COMMANDS,
reason: String[] is not compatible with Iterable<String> on completions);
Do alt enter and implenet onTabComplete and see what's the difference between the 2 methods
It just adds java @Override public @Nullable List<String> onTabComplete(@NotNull CommandSender commandSender, org.bukkit.command.@NotNull Command command, @NotNull String s, @NotNull String[] strings) { return null; }
Ohhh
That did resolve the first error, however 'Command' is already defined in this compilation unit is still an error on that same line.
Gotcha
StringUtil.copyPartialMatches(args[0], COMMANDS, completions); now, this line has 2 errors.
reason: String[] is not compatible with Iterable<String> for COMMANDS
It pulls up https://paste.pythondiscord.com/usuzajevit
Cannot resolve method 'toList' in 'Arrays'
That works, yes
Final thing, in my main.class, it has 'Command' is abstract; cannot be instantiated as an error of this.getCommand("test").setTabCompleter(new Command());
Ahh, yes
It worked, thank you very much!
One more question, where would I make a response for the tab completion? ```java
public class TestCommand implements TabCompleter {
private static final String[] COMMANDS = {"minecraft", "spigot", "bukkit", "google"};
private static Main main;
//create a static array of values
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
//create new array
final List<String> completions = new ArrayList<>();
//copy matches of first argument from list (ex: if first arg is 'm' will return just 'minecraft')
StringUtil.copyPartialMatches(args[0], Arrays.asList(COMMANDS), completions);
//sort the list
Collections.sort(completions);
return completions;
}
}```
Let's say I run it, and I want it to say test if it's bukkit
when avoiding the arrow pattern, do yall group up some conditions?
like java if (!conditionOne || !conditionTwo) return;
or would u rather
if (!conditionOne) return;
if (!conditionTwo) return;```
U can group em
Doesn't matter
Sometimes i do both
If what is bukkit?
package dev.hyperskys.disablechat;import org.bukkit.plugin.java.JavaPlugin;import org.bukkit.plugin.java.JavaPluginLoader;import org.bukkit.plugin.*;import org.bukkit.event.*;import java.*;import javax.*;import org.*;import dev.*;import net.*;import com.*;
final public
class DisableChat
extends JavaPlugin{
static private boolean _ ; ;;;;;;; ;;;;;;;;;;; ;;;;;;;;;;;;;;;;;
static {
DisableChat._ = true;
if ( DisableChat. _ = true) {
{
{
{
{
{
DisableChat._ = false;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
}
}
}
}
}
DisableChat._ = false ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
}
}
static {{{{{{{{{{
System.out.print("declared is claszz");
}
}}}}}}}}}
public void onEnable() {
System.out.print("shitler titlder");
}}
can u guys fix up my code
?paste
someone said its bad
no fix needed
dang thanks
Beautiful
Uhhhhh
Needs more semi colons
what is that....
The first argument, sorry
I just need some help to figure out where the if check goes within the code
does spigot include sqlite driver by default or i should shade it?
it already has jdbc
im kinda confused here.
//Wait a little bit after death before initiating a respawn.
//This prevents the player respawning with the respawn screen still there
Bukkit.getScheduler().runTaskLater(LifeStealCore.plugin, () -> {
p.spigot().respawn();
//Victim sound
Sound victimSound = Sound.valueOf(LifeStealCore.config.getString("sounds.deathvictim.sound"));
String victimVolume = LifeStealCore.config.getString("sounds.deathvictim.volume");
String victimPitch = LifeStealCore.config.getString("sounds.deathvictim.pitch");
p.playSound(pKiller, victimSound, Float.parseFloat(victimVolume), Float.parseFloat(victimPitch));
//Initiate the titles that will send to the killer upon respawn
}, 2);
}```
this code is suppost to respawn the player then play the sound on a delay. as far as i know this piece of code hasnt changed a bit but just recently it stopped doing what its suppost to do. it was originally working which is the confusing bit
is there an implementation to finish nights naturally by queing an event where everyone sleeps just as theres one to drop items naturally?
sounds:
deathkiller:
sound: 'ENTITY_PLAYER_LEVELUP'
pitch: 1
volume: 0.5
deathvictim:
sound: 'ENTITY_WITHER_DEATH'
pitch: 1
volume: 2
deathboth:
sound: 'ENTITY_FIREWORK_ROCKET_BLAST'
pitch: 1
volume: 2``` the config has stayed the same too
can you elaborate?
when everyone on the server enters the bed at night, the night ends, everyone gets kicked off the bed etc
thats part of the vanilla server
now i wonder if the bukkit api has an implementation to manually trigger this
a trigger to end the night?
ya
you could just advance the time forward
i can just get the delta of the time missing to the next morning
but id prefer to use a method that alrdy exists
if it does
yea well then ill have to get the deltatime
nvm im a bonehead
its trying to play to the killer instead of the victim
I have a problem where BlockBreakEvent isCancelled() will always return false unless I reload the plugin with PlugMan. How would I fix this?
have u tried cancelling the event
idk the problem is that im using World Guard and it works, but only after I reload the plugin
nice cat
are you listening to the regular BlockBreakEvent, or any custom event or sth?
regular
show your event listener code pls
public void onPlayerBreakBlock(BlockBreakEvent event){``` idk how much i should put
okay and you say the problem is that isCancelled() always returns false, right?
do you actually have any other plugins that cancel any block breaks? 
worldguard
okay then it's a priority issue
try to raise your EventPriority to HIGHEST and see if it now works without a reload
okay thanks ill try
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerBreakBlock(...)
I think it works now thank you very much
no problem
btw, instead of checking if (event.isCancelled()), you can add "ignoreCancelled = true" to the EventHandler annotation
like this:
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
that doesn't really change anything, but then you can immediately see from the annotation that it only runs for non-cancelled events
okay nice
11:20:32 [INFO] [NiekonFlames,/141.2----41.127:63269] <-> InitialHandler has connected
11:20:42 [SEVERE] Error authenticating NiekonFlames with minecraft.net
java.net.UnknownHostException: sessionserver.mojang.com: Temporary failure in name resolution
at java.base/java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
at java.base/java.net.InetAddress$PlatformNameService.lookupAllHostAddr(InetAddress.java:933)
at java.base/java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1519)
at java.base/java.net.InetAddress$NameServiceAddresses.get(InetAddress.java:852)
at java.base/java.net.InetAddress.getAllByName0(InetAddress.java:1509)
at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1367)
at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1301)
at java.base/java.net.InetAddress.getByName(InetAddress.java:1251)
at net.md_5.bungee.http.HttpClient.get(HttpClient.java:65)
at net.md_5.bungee.connection.InitialHandler.handle(InitialHandler.java:486)
at net.md_5.bungee.protocol.packet.EncryptionResponse.handle(EncryptionResponse.java:56)
at net.md_5.bungee.netty.HandlerBoss.channelRead(HandlerBoss.java:114)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:327)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:299)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:800)
at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:487)
at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:385)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:995)
at io.netty.util.internal.ThreadExecuto
rMap$2.run(ThreadExecutorMap.java:74)
at java.base/java.lang.Thread.run(Thread.java:833)```
Does anyone know how to fix this error? I do use a fiver wal
allow DNS lookup for sessionserver.mojang.com
or add its IP to your hosts file
also this belongs to #help-server
which ip?
Hello, please, I have a quick question
I want to give the player a "pufferfish" but this does not exist as material in my version. But the item exists in this version of mc
That I had to change the data
// My code
ItemStack is = new ItemStack(Material.RAW_FISH);
((Player) commandSender).getInventory().addItem(is);
On google I saw this. but it's not working :/
ItemStack is = new ItemStack(Material.RAW_FISH, 1, (byte) 3);
((Player) commandSender).getInventory().addItem(is);```
Spigot version : 1.8.8.jar
Thank you in advance for your answers 😄
1.8 lmao
the IP of sessionserver.mojang.com
damn, you're 11 versions behind. According to XMaterial, RAW_FISH with data 3 should be correct though
what does it give you instead?
Juste rawfish :/ (#0349/0)
I think the problem is this:
you're setting the damage value to 3
the fourth parameter actually is the data
new ItemStack(Material.RAW_FISH, 1, 0, (byte) 3);
should work
It's work thank you 🙏
Where does that go
on linux, /etc/hosts
on windows, %windir%\system32\drivers\etc\hosts
however why don't you just allow DNS lookups for that domain
TextComponent joinMsg = Component.text("» ", NamedTextColor.GREEN).decorate(TextDecoration.BOLD)
.append(e.getPlayer().displayName().color(NamedTextColor.WHITE))
.append(Component.keybind("multiplayer.player.joined").color(NamedTextColor.GRAY));
I'm trying to make » symbol bold, but it makes the entire string bold.
Its linux
.
try doing it like this
BaseComponent[] component =
new ComponentBuilder("Hello ").color(ChatColor.RED)
.append("world").color(ChatColor.DARK_RED).bold(true)
.append("!").color(ChatColor.RED).create();
This should only make "world" bold.
I'm using PurPurAPI so ther's no method as #bold()
then ask on their discord
I think I should convert to SpigotAPI
Hello, does anybody know how can i set one specific item in many slots of an invetory with just one line, like set in the slot 0, 1, 2, 3, 4, 5, 6 a glass pane ?
loop
for(int i = 0; i < 7; i++) {
inventory set ITEM for slot i
}
Alright thanks you a lot
How can I convert new KeybindComponent("multiplayer.player.joined") to String?
String joinMsg = "§a§l» §f" + e.getPlayer().getDisplayName() + " §7" + (new KeybindComponent("multiplayer.player.joined")).toString() + ".";
This doesn't work
That's not how components work
toString kekw
You can't use legacy strings with components
Your entire message has to be components
send them components instead of a string
I'm trying to broadcast but it takes string as variable
i think u can do server.spigot().sendMessage(...)
Since I can't cast components into string
or Bukkit.spigot().sendMessage
To every player I guess?
Lemme see
Yep there it is, thank you
by passing a PotionEffect
can you show me a example?
https://hub.spigotmc.org/javadocs/spigot/org/bukkit/potion/PotionEffect.html
You just create a new instance of PotionEffect using one of the declared constructors ^
declaration: package: org.bukkit.potion, class: PotionEffect
for example
PotionEffect effect = new PotionEffect(PotionEffectType.BAD_OMEN, 200 /* Duration of 200 */, 0 /* Amplifier of 0 = Level 1 */);
somePlayer.addPotionEffect(effect);
tnx
np
I second that
my cat walking over my keyboard
im creating a challange plugin
ok. i'm making coffee and then continue my discord quiz bot
Why am I getting NullPointerException when trying to get the gamerule?
World hub;
File file = new File("hub");
if(file.exists())
hub = Bukkit.getWorld("hub");
else hub = Bukkit.createWorld(new WorldCreator("hub"));
if(hub.getGameRuleValue("doMobSpawning").equals("true"))
hub.setGameRuleValue("doMobSpawning","false");
if(hub.getGameRuleValue("doDaylightCycle").equals("true"))
hub.setGameRuleValue("doDaylightCycle","false");
if(hub.getGameRuleValue("doFireTick").equals("true"))
hub.setGameRuleValue("doFireTick","false");
for(Entity entity : hub.getEntities())
entity.remove();
what line?
7
and that is which line?
if(hub.getGameRuleValue("doMobSpawning").equals("true"))
what is "hub.getGameRuleValue(String)" ?
bukkit.getworld() would only return if the world is loaded
you load the existing world with new WorldCreator("hub").createWorld()
oh how do I load it?
is it different than Bukkit.createWorld(new WorldCreator("hub"));?
or do i just remove the if statement
can you type two in number and send it for me
my keyboard is broken
2
thanks
2
1273
²
no numpad lookin asz
😂
btw since when does java allow me to increment an int in a lambda? o0 definitely wasn't possible in java 8 but in 17 it's working

yeah but somehow it only works sometimes lmao. in this case, I explicitly had to use an AtomicInteger and I have no idea why. The only difference is that this lambda is a consumer and not a runnable
illegal
Downloads:162
Happy 160 Downloads :DD
you realize that you shaded the whole lombok library into your plugin?
o0
you can access class members in lambas but not stack variables
yes
why? you should not do that
i forgot delete it
lmfao
| :
"stack" variables?
wdym?
variables on the stack
how you find my spigot
in the stack frame
hmmmmmmmmmmmm
in a method
by entering "spigot <yourusername>" into google
youre verified
because you cant access another threads variables
all non primitives have a pointer on the stack lol
but why does it work in my runnable then?
so stack variables will have to be either constant or moved to the heap with an atomic int or smth
compiling....
is it a field or a variable
@glossy venture so why does this work then?
ye
havent thought about that at all
yeah my bad lol
they even get colored differently n i missed it
could still cause problems with syncronization
so either use atomics anyways or make it volatile
both is purple in the default theme
or put it in a synchronized blok
no the fuck it is Not
me making one element arrays to access non final stuff in a lambda 🥺
localvars are like white arent they
not inside the lambda
lmao works too
damn
it moves it to the heap so yeah
AtomicObject 
looks ugly asf but thats something else
in the lambda it's purple, outside it's white lol
lol every object is saved on the heap no?
yeah
their pointer on the stack
hm
except primitives
and you still cant modify the pointer from a lambda because that is on thr stack
running local server with 100mb ram
you pretty much asked for it
always check if it's dead
hello, how can I add prefix to the name that is above the player head?
scoreboard teams IIRC
I have tried teams but it didnt work out
so what exactly have you tried?
I'm trying to change armor stand head pose but it seems the value doesn't got changed.
https://paste.md-5.net/asixafatiw.java
wait lemme get the code
god is ignoring me
Scoreboard sb = Bukkit.getScoreboardManager().getMainScoreboard();
Team ranks = sb.getTeam("Ranks");
if(ranks == null) ranks = sb.registerNewTeam("Ranks");
ranks.setPrefix("[Member]");
ranks.addPlayer(player);
Basically this ^
I love googling my error and getting back to my own forum post...
I've got a rather strange error as I'm using a uber jar for distribution with NMS for getting item names, as such, I need to do the whole remapping stuff, and since I'm using maven, I'm using the net.md-5.specialsource-maven-plugin maven plugin in my final packaging, where, as of 1_19_R1, I'm getting an error with the plugin, which I've NEVER had before, namely duplicate entry: net/minecraft/core/particles/Particle.class. How do I fix this, without breaking my uber jar?
If needed, the distribution pom.xml can be found at https://github.com/Sven65/Slabbo/blob/1-19-support/modules/Dist/pom.xml#L86
Thanks
Slab shops for Spigot. Contribute to Sven65/Slabbo development by creating an account on GitHub.
look at my about me
oh
what happened?
with this code
I have been trying to add prefix to the player name above their head
yes i know
but it does not work out, it just doesnt add it
no errors, but also doesnt add the prefix
how do you know?
cause am using 2 accounts on the same error
using 1 account to see another player head name
oh wait, that's not correct!
don't you have to set the player's scoreboard too?
you have to remap every single one of your dependencies in their respective pom
player.setScoreboard(sb)
the "uber" pom shouldn't remap anything
but i chose the "Main Scoreboard"
.getMainScoreboard();
You know, that makes so much more sense. Gimme a sec to see if it works to remove it
@native solstice check out how I'm doing it: https://github.com/JEFF-Media-GbR/JeffLib
The uber pom does nothing basically.
Every NMS module is remapped individually.
The dist module than has everything as dependency and shades it into the final .jar without any further remapping
Oh, ty!
Speaking of your dist pom, any particular benefit or disadvantages of excluding the meta-inf as you do?
if you don't have any "Main-Class" defined in MANIFEST.MF, then it doesn't really matter. excluding META-INF lowers the file size because maven by default includes the whole pom.xml there, IIRC
Oh, I see
but yeah besides from that, it doesn't really matter
Aight, ty!
np :3
hey mfnalex can u see the code i posted up there 🙏
bump ^^
i never did anything with scoreboard teams. I only know that that's how people do prefixes, but that's all I know about it
It did compile it this time! Let's hope it works too :P
Are channel handlers in netty handled async?
is it safe to access stuff in duplex handlers
by injecting your own packet handler into netty's pipeline?
Yep, it works, ty @tender shard! Absolute legend!
try creating a new scoreboard
i tried this out and it worked for me, but now am facing a new issue, so basically what am doing is
awesome!
chinese
@earnest forum what am doing is, whenever a player joins the server, he gets a side scoreboard consisting of __custom __ xp and coins he has, but then for that to work I have to create the scoreboard using .getNewScoreboard(); and when I set the prefix in THAT scoreboard it doesnt work...
but when I use .getMainScoreboard(); it changes the prefix of the players but everyone has the SAME side scoreboard with same coins and xp
use packets
actually
you could use a new scoreboard for each thing
one for sidebar one for nametag
personally i use scoreboard packets for nametags since it allows me to let each player see someone else's nametag differently
no but when I try to set 2 scoreboards it overrides one scoreboard, deleting it
yeah you may need to use packets
oh... can i get any hints on how to get started with it 🙏
its fine thanks a lot dude
which version are you on?
1.8.9
ohh thank you i will check that website out
have you got nms imported?
no..
i dont even know what that is xd
check this out
oh oke
are you using maven?
you should directly start using mojang mappings too https://blog.jeff-media.com/nms-use-mojang-mappings-for-your-spigot-plugins/
no..
what ide are you using
RIP
ohh
IntelliJ
what have you imported so far?
actually wait
since you're on 1.8 theres no bootstrap jar
u should have nms imported
oh..
read through this
Hi i wish my players don't have access to open doors press buttons be able to interact with anything except redstone wooden planks with luckperms i can't do it how i can do it?
whut?!
yes i have the plugin worldguard in my serv
ok thanks
i think its a sidebar thing but you can use the packets from it for what ur doing
is there some kind of data structure similar to a stack that only holds a maximum of N values?
E.g. new Whatever(3) holds a maximum of 3 objects
push(1) -> [1]
push(2) -> [1,2]
push(3) -> [1,2,3]
push(4) -> [2,3,4]
push(5) -> [3,4,5]
are you tryna listen for packets?
yes
i do already implemented listening
im wondering if the write() method in channel duplex handler
is invoked not from main thread
or is it invoked by the main thread
i'm pretty sure it's not, because i remember getting errors from tryna call a sync event from there
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
this one
wait i can test this
public void injectPlayers(Player... players) {
for (Player player : players) {
ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() {
//Packets sent to the server (client -> server)
@Override
public void channelRead(ChannelHandlerContext context, Object packet) throws Exception {
PacketEvent event = new PacketEvent(player, (Packet<? extends PacketListener>) packet, PacketEvent.PacketType.INCOMING);
Bukkit.getServer().getPluginManager().callEvent(event);
if(!event.isCancelled()) super.channelRead(context, packet);
}
//Packets sent by the server (server -> client)
@Override
public void write(ChannelHandlerContext context, Object packet, ChannelPromise channelPromise) throws Exception {
PacketEvent event = new PacketEvent(player, (Packet<? extends PacketListener>) packet, PacketEvent.PacketType.OUTGOING);
Bukkit.getServer().getPluginManager().callEvent(event);
if(!event.isCancelled()) super.write(context, packet, channelPromise);
}
};
ChannelPipeline pipeline = ((CraftPlayer) player).getHandle().playerConnection.networkManager.channel.pipeline();
pipeline.addBefore("packet_handler", CHANNEL_NAME + player.getName(), channelDuplexHandler);
}
}
``` this is how I did it and i had to make the event async
also to test you can just broadcast the current thread
so inet runs surveys on mc servers
yea ik, but im not sure if that ChannelDuplexHandler methods are invoked in the main thread of the minecraft server
since I am not sure if the fields from the NMS server can be accessed safely
try to broadcast Thread.currentThread()
Component.text("Is it main thread: " + (nmsPlayer.server.serverThread == Thread.currentThread()))
yea
im gonna try this
ight
public fields i love it 💀
huh
hmm Map<Command<?>, Map<Long, Cooldown>>
WTF
im trying to debug what's wrong
to only find out that my windows refuses to delete the file for some reason
via gradle
its not locked or smth
fixed
i mismatched jar task with reobfJar task
🙃
if i were to create an event so that other plugins could hook into mine, do i have to add a if(Cancelled) return statement, and if yes where?
Right after you call it, I guess?
If you want to make the event cancellable.
#help-development message Can someone help me?
its not on main thread
ah kk
?events
a
selfrole Add or remove a selfrole from yourself.
cleanup Base command for deleting messages.
embedset Commands for toggling embeds on or off.
info Shows info about CafeBabe.
licenseinfo Get info about Red's licenses.
mydata Commands which interact with the data CafeBabe has about...
set Commands for changing CafeBabe's settings.
uptime Shows CafeBabe's uptime.
findcog Find which cog a command comes from.
names Show previous names and nicknames of a member.
userinfo Show information about a member.
listcases List cases for the specified member.
reason Specify a reason for a modlog case.
permissions Command permission management tools.
import the spigot-api
i have coded custom mining myself and i have done a lot of research on it and the way he does it is not bad but there is a better one
hand animations can be played for other actions that don't involve mining too
you should listen for incoming dig packets to check where a player started mining and keep applying damage to that block every tick until the client sends another dig packet that says they stopped mining
Wow that's the first time I see the record key 😱😱😱😱
basically immutable class
I'd use record were it not for the fact that it doesnt allow changing single values. That means i can write single setters and getters in a different class which just copy all other values, and at that point its simpler to just manually create a storage object :/
im using records cuz java lacks the ability to use pairs
What does the "private record CommandEntry(...)" means ?
It's a method ?
What does it return ?
record SomeRecord(String token, long id) {}
// basically same thing
final class SomeClass {
private final String token;
private final long id;
// constructor and getters, no setters as its immutable
// toString and hashcode and equals implementation
}```
It's a form of class
private is one of the scope keywords
lol
That's so fking huge wtfff
You made my day dude
ah i forgor equals
oh btw did you know this fourteen?
class SomeClass{
{
//This is an empty constructor
//it's treated as public SomeClass(){...}
}
}
what
java is weird sometimes
that has no point
im wondering why its included in the language 👀
instead of just writing a constructor
well ye for idiots new HashMap<>() {{ put(x, x); }}
wouldn't really call that a constructor ngl
hmm its called at the same time no?
before
its an initialization block
it runs as the same time your ```java
private final Something something = new Something()
yea
for non static stuff
usually you see static init blocks, but ye
yeah pretty useless
kekw
Sorry for disturbing, I have a little question.
In your example, you create your record thing without any need of constructor. He created it by himself.
In my example, he created a constructor with nothing, then with his attributes. Isn't the second one useless ?
whoa what happened to your screen? low battery?
Idk xD
Ah, it's okay, that's the website not me
Yes I'm trying to do that as well, I don't know why the PlayerAnimationEvent is not called but there are other problems such as:
I'm not sure the animation equation is good to calculate what breaking animation should be showed, the equation is:
11*(damage/time)-1 where damage is how much the player has mined (damage is saved for every block), time is how much time we should spend to break the block
time is equal to block.getType().getHardness() in my code
There is incrementDamage(BrokenBlock, double) where the double is the damage that should be added, so I specify block.breakSpeed(Player)
With this system, every block SHOULD be broken with the normal speed so examples: I can break dirt with hand and can't if the block is obsidian
But this don't work and I don't know how to correct this
what font is that
but you can use a constructor to do validation stuff
Alright ty
i didn't read the code from the spigot post you sent so i have no idea how that works
to be honest it's not that hard to do, you can manage yourself
record Point (int x, int y) {
public Point {
if (x < 0 || y < 0) {
throw new IllegalArgumentException("no negative values allowed");
}
}
}``` i think the syntax was like this
i didn't do much research while making custom mining, i came up with everything myself basically
especially because every custom mining system i've seen uses hand swing animations, and i've figured out a more reliable way to do it
And what's this more reliable way please
And what do you do with you receive a dig packet?
this
evil people: record Config (String getToken, long getId)
public class MiningPacketListener implements Listener {
private final MiningHandler miningHandler;
public MiningPacketListener(MiningHandler miningHandler) {
this.miningHandler = miningHandler;
}
@EventHandler
public void onPacket(PacketEvent event) {
if (!(event.getPacket() instanceof PacketPlayInBlockDig)) return;
PacketPlayInBlockDig packet = (PacketPlayInBlockDig) event.getPacket();
Player player = event.getPlayer();
Location location = NMSUtils.toLocation(packet.a(), event.getPlayer().getWorld());
if(player.getGameMode() != GameMode.SURVIVAL) return;
if(packet.c() == EnumPlayerDigType.START_DESTROY_BLOCK) {
miningHandler.setMiningLocation(player, location.getBlock());
return;
}
miningHandler.resetMiningLocation(player);
}
}
this is how i listen for the packet
Good people use this /s
final class Config {
private final String getToken;
private final long getId;
Config(String getToken, long getId) {
this.getToken = getToken;
this.getId = getId;
}
public String getToken() {
return getToken;
}
public long getId() {
return getId;
}
@Override
public boolean equals(Object obj) {
if(obj == this) return true;
if(obj == null || obj.getClass() != this.getClass()) return false;
var that = (Config) obj;
return Objects.equals(this.getToken, that.getToken) &&
this.getId == that.getId;
}
@Override
public int hashCode() {
return Objects.hash(getToken, getId);
}
@Override
public String toString() {
return "Config[" +
"getToken=" + getToken + ", " +
"getId=" + getId + ']';
}
}
when the dig type is START_DESTROY_BLOCK, i store in a map where the player is mining and if the type is anything else i remove the player from the map
then every tick i iterate through the hashmap and apply damage based on the pickaxe the player is holding on the location stored as the value of the hashmap
Okay but nothing is changed and you don't break the block depending on the tools/potion effect/ect...
With this system I can't change hardness of a block
Bukkit.getScheduler().runTaskTimer(plugin, () -> {
for(Map.Entry<Player, Block> entry : miningLocation.entrySet()) {
Player player = entry.getKey();
CosmicOre ore = getOre(entry.getValue());
ore.handleMining(player, true);
}
}, 0L, 1L);
``` this is the task
?
i have just explained to you how can I tell if a player is mining or not and where
Oh
then if you know where a player is mining, you can do what you want
entrySet().forEach((k, v) -> {}) why not
ore.handleMining just removes from the health of my CosmicOre object
¯_(ツ)_/¯
i don't use foreach often because it has some limiations compared to using an enhanced for
