#help-development
1 messages · Page 1337 of 1
^ You'd have to rewrite the client's entity system to be ECS and compare that to pure vanilla to get a proper comparison and not two completely different implementations lol
They do try to optimize for performance, the issue is there are AFAIK 2m+ lines of code in their engine, it's very difficult to refactor and optimize
they go for low hanging fruit here and there
do you remember the 1.15 "performance update"?
which is irrelevant to using ECS or not using ECS
they put a tick rate limit on villager ai -- that's their performance update
It'd be a fuck ton of LOC regardless lmao
SoA ECS allows the CPU to use 1 cycle to compute multiple data (basically like SIMD)
don't need ecs for that
OOP takes 50-80 cycles
not strictly true
i say this having rewritten the collision algorithm (yes, in oop) using simd
With the latest version of java?
which btw is a much more noticeable performance issue than whatever memory locality of bubble columns
i think j16, i don't remember, it's been a while
Java 16 doesn't have SIMD support I think?
it was a bit ass because the jit is so fragile, but you can get it to emit vectorized instructions
not explicit simd support, no
you can't tell it to use AVX for example
but it's been in jit for a long time
Speaking of ECS. Debating of if i want to use the over bloated flecs or roll my own solution that isn't so feature bloated 🤔
e.g. simple for-loops with predictable bounds have been vectorized since i think j11
myes, not a problem for collisions however
you can algorithm yourself out of almost any hole
entt is also bloat lol
Then I'm not sure, just look it up
I'll just roll my own solution kekw
Yeah most of the time you don't need most of it
i rolled my own ecs system for a custom block type system a while back
and being the type purist i am, i had the system/component/entity type declarations be declared through java generics
ecs is quite convenient in some cases
i didn't quite like it however, i eventually went back to rawdogging it with inheritance and a little bit of composition
only reason i tried ecs is that my blockproperty system lended itself to it quite nicely
Yea, a lot of my own stuff is just inheritance and comp lol
I simply don't need ECS for that stuff because i don't have any specific benefit from using it kekw
Looking at MC and what they're doing, they wouldn't really benefit from ECS either tbh
Sniffer -> Animal -> AgeableMob -> PathfinderMob -> Mob -> LivingEntity -> Entity
This is more or less good enough for their needs tbh
lmao
Would ECS change this much? No, not really.
It'd be the same complexity, just different code lol
ecs excels when you have to put together various properties and behaviors onto a bunch of different mobs that isn't neatly modelable as a type hierarchy
e.g. suppose you have an aging mob that doesn't do pathfinding
Which they don't really do afaik
i don't think so, all the ageable mobs are livestock
something that could benefit from ecs is stuff like monsters catching fire in sunlight
I believe that's just a boolean and literally only used for zombies lol
but that's a very negligible portion of the codebase and is already represented as an inherited boolean
Which makes ECS useless kekw
ECS would benefit plugin & mod devs, but that doesn't matter as much as keeping things more or less stable and just doing what works lol
if they did a rewrite, like they did in bedrock, i could see them going with ecs, but i could also see them sticking to inheritance and composition; there aren't really many benefits to be gained on the server side at least
a lot of stuff just doesn't really make sense as ECS either.
Why make it possible for other mobs to do bee specific mechanics. There really isn't one
most of the things that'd really benefit from ecs are already composed out of Entity itself into MovementController and Pathfinder and similar like Brain
beyond those two, mobs are mostly just state definition and one-off logic
pretty much, yea. not seeing anything major that would benefit more from ECS than the current impl
perhaps blocks, they are already sorta ecs-like with their block properties
which is why i tried ecs for my block system
AI goals do a good chunk of stuff, but those are already easy to deal with lol
i'm not too familiar with brain internals, i see them as very inefficient, perhaps ecs might help within them
@Override
protected void registerGoals() {
this.friendsGoal = new SilverfishWakeUpFriendsGoal(this);
this.goalSelector.addGoal(1, new FloatGoal(this));
this.goalSelector.addGoal(1, new ClimbOnTopOfPowderSnowGoal(this, this.level()));
this.goalSelector.addGoal(3, this.friendsGoal);
this.goalSelector.addGoal(4, new MeleeAttackGoal(this, 1.0, false));
this.goalSelector.addGoal(5, new SilverfishMergeWithStoneGoal(this));
this.targetSelector.addGoal(1, new HurtByTargetGoal(this, (Class<?>[])new Class[0]).setAlertOthers((Class<?>[])new Class[0]));
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<Object>(this, Player.class, true));
}
Silverfish, for example
Just clear goalSelector & targetSelector and add your own goal(s) to the specific mob
if you squint at it and turn your head sideways it's basically already ecs
Yea, but it works so it's not worth rewriting to be proper ECS lol
Maybe for a from-scratch game, but even then ehhh? It works and it's simple to use
extend Goal implement the relevant methods, add to goal selector
good enough, i'd say lol
Is there a way to check if a player is online-mode in Bungeecord, without kicking that player?
I'd probably just do the same thing myself unless there's a better method that's actually objectively better lol
check if their client sends an uuidv4 (not a guarantee of online mode, tlauncher also sends a v4), then query the mojang api with the name or uuid and see if it matches what the client sent
it doesn't tell you whether it's actually that user and is not a login, but it's a very strong indicator that the connecting user is at least trying to log in as that mojang user
so at that point you should be safe to trigger the onlinemode auth process for them
maybe I'll use AI to come up with an AI impl, see what it comes up with kekw
Would tlauncher send a v4 UUID that really match a Mojang UUID?
or would it be a random v4
no, it'll send some random ass mangled uuidv4 used in their skin system or something equivalently stupid
so checking it against the uuid you get from mojang is an almost surefire check
Either way means it's not a guarantee
so from the v4 uuid check mojang api if anything matches then okay of not then count it offline?
without even using the online-mode check?
myes, but you must also do the online mode check if you think it is an online mode user, i.e. if the name+uuid matches what you get from the mojang api
because nothing stops a client from sending that name+uuid
it's just that most launchers choose not to
well AI picked.... something for the AI impl
why check online-mode if we already checked the mojang api to see if they match?
I guess it can never match the fake v4 uuid with the mojang api
because any launcher could send the name+uuid, without really being that player
you still want to confirm it's the actual logged-in user
but won't it be random v4?
oh
and if you don't double-check with the auth system, i will just forcelogin myself into your server
You have 0 guarantees on the legitimacy outside of praying the client plays nice and does what it's supposed to do lol
myes, the auth against mojang part is the only guarantee you get
all of this is just to avoid doing that if the player is in offline mode
so in case it's v3 it will be %100 offline
if v4 check for online-mode
in other words, trust (name+uuid matches) but verify (auth against mojang)
if v4 AND matches the uuid you get from mojang
tlauncher sends a v4 uuid that doesn't match the mojang uuid
Oh yea, thoughts on whatever tf AI came up with here for a game AI impl? @thorn isle
It works... i guess? Seems overkill though
Node attack = new Sequence()
.add(new Condition(ctx -> ctx.get("enemyVisible")))
.add(new Action(ctx -> {
System.out.println("Attacking enemy");
return Status.SUCCESS;
}));
Node heal = new Sequence()
.add(new Condition(ctx -> ctx.get("health") < 50))
.add(new Action(ctx -> {
System.out.println("Healing");
return Status.SUCCESS;
}));
This is basically how it works lol
AIAgent agent = new AIAgent(buildAI());
agent.getContext().set("health", 30);
agent.getContext().set("enemyVisible", true);
agent.update();
buildAI() being the above code blocks
thank you
I was trying for hours to find a way :9
lol one moment I'll see what the AI comes up with
I hope there are no more such of manipulation issues from client side :0
pretty sure fastlogin already does all of this btw
I guess it does using /premium, so I don't even think to check for uuid version
fuck i need to re-do this with a clear chatgpt instance.
either way it's certainly leaning towards data-driven AI lol
i think they do advertise some kind of auto detection, but i've never used it so i don't know for sure
take a look at uh
what the fuck was it called again, i always forget
it's in javascript, but the "skill library" is a pretty good model of ai goals
but they use a llm to decide which goals to start/stop
and the goals themselves are written by the llm, so it can "learn" or invent new behaviors as needed
i don't hate myself enough to go through that lol
this is basically what i intend to do with your botcreator thing, except in java because javascript is for plebeians
Different person for that specifically kekw
who was that other guy
I'd probably just do what minecraft's doing though.
I don't need a goal system that's LLM friendly, but human friendly lol
myes
i took one look at the json file and noped out KEKW
if you un-escape it so it has newlines and shit it becomes much more legible
lot of effort just to see the code kekw
{"mineWoodLog": {"code": "async function mineWoodLog(bot) {
const woodLogNames = ["oak_log", "birch_log", "spruce_log", "jungle_log", "acacia_log", "dark_oak_log", "mangrove_log"];
// Find a wood log block
const woodLogBlock = await exploreUntil(bot, new Vec3(1, 0, 1), 60, () => {
return bot.findBlock({
matching: block => woodLogNames.includes(block.name),
maxDistance: 32
});
});
if (!woodLogBlock) {
bot.chat("Could not find a wood log.");
return;
}
// Mine the wood log block
await mineBlock(bot, woodLogBlock.name, 1);
bot.chat("Wood log mined.");
}", "description": "async function mineWoodLog(bot) {
// The function is about mining a single wood log block. It searches for a wood log block by exploring the environment until it finds one of the seven types of wood logs. If a wood log block is found, it is mined and a success message is sent. If no wood log block is found, a failure message is sent.
}"}
javascript nested in json, because yes
Ah yea. That's sane, but not exactly what I'd want or need lol
what i want to do is not use javascript but java, and hook into the bukkit api
so it can use the built in pathfinders and such
Attempt #2 and it gave more or less what MC is already doing lol
i also ended up modeling my ai goal system after the mc goals system for my npc plugin, but that was mostly because it was the only system i was familiar with
tbf i can't think of anything that's much better
It's basically ECS, so switching fully to ECS doesn't really change anything
This, I guess
if cleaned up anyways
but even then that's only somewhat better, but i think (?) would allow more complexity than MC?
sorta bootleg ecs yeah, you have your entity type which has components (magic strings in a hashmap 🤡 ) and "systems" in the conditions and actions working on each entity of that type
just without any of the benefits of ecs really
i see what assumption you have about ecs, true ecs only uses primitives, not objects, and a singleton per component, where the component has pre-allocated arrays, this is why the cpu can do the work faster, it only needs 1-5 cycles because it is all contiguous and sitting in the l1 or l2 cache
Oh wait. I got another (maybe better) impl out of GPT
You need to understand how the cpu works
relevant bit is only
GameWorld world = new GameWorld();
Enemy goblin = new Enemy("Goblin", 0, 0);
Enemy orc = new Enemy("Orc", 5, 5);
// Behavior tree: flee if threat near, otherwise patrol
SequenceNode fleeSequence = new SequenceNode();
fleeSequence.addChild(new IsThreatNearNode(2));
fleeSequence.addChild(new FleeFromNode(goblin));
SelectorNode root = new SelectorNode();
root.addChild(fleeSequence);
root.addChild(new RepeatNode(new MoveToNode(5,5))); // patrol to (5,5) endlessly
orc.setBehaviorTree(root);
world.addEntity(goblin);
world.addEntity(orc);
for (int i = 0; i < 10; i++) {
System.out.println("=== Tick " + i + " ===");
world.update();
}
this is an implementation detail, and while it does have effects on performance, we aren't talking about performance, but fluency
it is completely irrelevant here whether anything is in arrays or hashmaps or a sql database here
The sequence & selector node thing is p nice imo
i suppose thats why you had the idea that it doesn't provide significant performance improvements, if you use it like that its still just oop written a bit differently
not at all
we know what ecs is, trust me
i've written it in the "backed by contiguous arrays" approach before
but we're not talking about performance here
we're talking about how fluent it is in source code
I think in MC's case you'd have to have an AI goal call a different AI goal to achieve the same thing 🤔
anyhow, you do you
i think mc just has them be stateful
no, like i said, it's backed by contiguous, dense arrays
I'd have to check
trust me brother you're trying to teach your father how to fuck here lmao
wild
Waiting on claude, but it's slow af
This would nice impl though, if improved slightly w/ more node options.
Maybe a mix of this & the previous AI suggestion
.
i did something sort of similar for a quest plugin before
GPT's more or less defaulted to some form of MC-like GOAP AI so i guess it's just a matter of impl if that was what i'd go w/
Claude is uh.. more or less doing the same thing
* AIAgent guard = AIAgent.builder("Guard")
* .withBehavior(BehaviorTree.sequence(
* Conditions.enemyInRange(8.0),
* Actions.chase(),
* Actions.attack()
* ))
* .build();
to be fair there's probably considerable bias towards minecraft source code in the java source sample set
Yea, I'll let this one finish up & try C++ lol
stupidly simple prompt too though, as i don't want to influence the AI massively
yea, even that's doing the same thing. so i guess it's either good enough in general, or GPT just likes it lmfao
just a matter of impl i guess lol
Claude's certainly running with the prompt lol
bruh fucking thing made tic-tac-toe
even went through all the free messages, the fuck
i just use openai with my own harness, i don't like any of the public harnesses like claude code
minimax m2.5 is pretty cheap and its numbers look pretty good
but it's chinese so expect the CCP to steal everything in your workspace
Yea, going through a few more attempts and I'd probably just do exactly what MC's doing lol
ai/
core/
AiContext.java
NodeStatus.java
TickResult.java
Clock.java
memory/
Memory.java
MemoryEntry.java
InMemoryBlackboard.java
MemoryKey.java
events/
AiEvent.java
EventBus.java
DamageTakenEvent.java
TargetLostEvent.java
sensing/
Sensor.java
SensorSuite.java
actions/
AiAction.java
ActionRegistry.java
ActionResult.java
decorators/
CooldownAction.java
TimeoutAction.java
RetryAction.java
InterruptibleAction.java
utility/
Consideration.java
UtilityCurve.java
UtilityOption.java
UtilityReasoner.java
UtilityDebugSnapshot.java
goap/
WorldState.java
Goal.java
GoapAction.java
GoapPlanner.java
Plan.java
GoapAgent.java
brain/
AiController.java
Activity.java
ActivityPolicy.java
InterruptPolicy.java
ReplanPolicy.java
game/
NpcContext.java
NpcSensors.java
NpcActions.java
NpcGoals.java
DemoGameLoop.java
intervening got me this mess though
which is uh
yea
like they say about premature optimization, premature abstraction is also a risk
Yea, I have exactly 0 idea wtf it was thinking but we run with it lol
Does anyone know why this happens? I'm working on a Hide and Seek plugin, if I stand still for 3 seconds my disguise should go invisible and a real block should be placed. But 9 out of 10 times it like bugs out and no block is being placed: https://medal.tv/games/minecraft/clips/mnqCbR5V6dwP-i3M_?invite=cr-MSx4OHosMTk4OTMwNTE5
Watch bug hide and seek by xthry_ and millions of other Minecraft videos on Medal. #minecraft
I'm sending my code 1s
BlockDisguise: https://pastebin.com/C6zpY5it
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
what is "this"
I'm working on a Hide and Seek plugin, if I stand still for 3 seconds my disguise should go invisible and a real block should be placed
But 9 out of 10 times it like bugs out
And no block is being placed
DisguiseManager: https://pastebin.com/ChVXja2w
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
These are the most important classes I think
Thanks for helping ! <3
we probably also need the BlockDisguise class since that's the one that has the impl for checkForStillness
i also don't see you calling the startTask method anywhere
It's over here
package me.vuxaer.hideandseek;
import me.vuxaer.hideandseek.listener.DamageListener;
import me.vuxaer.hideandseek.listener.JoinListener;
import me.vuxaer.hideandseek.listener.MoveListener;
import me.vuxaer.hideandseek.listener.QuitListener;
import me.vuxaer.hideandseek.manager.DisguiseManager;
import me.vuxaer.hideandseek.manager.GameManager;
import me.vuxaer.hideandseek.manager.PlayerManager;
import org.bukkit.plugin.java.JavaPlugin;
public final class HideAndSeekPlugin extends JavaPlugin {
private static HideAndSeekPlugin instance;
private GameManager gameManager;
private PlayerManager playerManager;
private DisguiseManager disguiseManager;
@Override
public void onEnable() {
instance = this;
playerManager = new PlayerManager();
gameManager = new GameManager(playerManager);
disguiseManager = new DisguiseManager();
getServer().getPluginManager().registerEvents(new JoinListener(), this);
getServer().getPluginManager().registerEvents(new QuitListener(), this);
getServer().getPluginManager().registerEvents(new MoveListener(), this);
getServer().getPluginManager().registerEvents(new DamageListener(), this);
disguiseManager.startTask();
}
public static HideAndSeekPlugin getInstance() {
return instance;
}
public GameManager getGameManager() {
return gameManager;
}
public PlayerManager getPlayerManager() {
return playerManager;
}
public DisguiseManager getDisguiseManager() {
return disguiseManager;
}
}
The task is started in here
how do you prevent the block moving the player ?
I don't think you do
you place block, the block moves the player, player moved and the block is then removed
Hmmm that might be the issue indeed!
it does look like the block is being set, and the camera moves
and then the block disappears
How could I prevent that from happening?
i suppose you could mount the player on an armor stand so they're immobile and have to press sneak to dismount
it'd also prevent you from accidentally undisguising by moving slightly
alternatively spectator mode so they don't collide with the block in the first place, but that can get hairy
private static boolean blocksMotion(Block block) {
Material mat = block.getType();
return mat.isSolid() && mat.isOccluding() && mat != Material.COBWEB && mat != Material.BAMBOO_SAPLING;
}
Any idea if Spigot already has this exact thing? If not I'll just keep it lol
I'm bumping some NMS stuff up to a public api kekw
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.fr33styler.botcreator</groupId>
<artifactId>bot-creator-api</artifactId>
<version>v2.0.0</version>
</dependency>
I released it, I might adjust some things tho @orchid gazelle @thorn isle
https://github.com/Fr33styler/BotCreator
it's still very basic
This already uses spigot API, but neither Material or Block have this specific thing afaik
something that'd be useful for my le embodied agent is maybe world storage, as in receiving chunk packets and storing the sections in memory
but since i'll package it into a plugin anyway, i'll probably just use bukkit for world access
Isn’t there isPassable or something
maybe 🤔
I'll have to double check to see how close it is to the NMS functionality if that's the case
that's just collision shape. I'm not entirely sure that 1:1's the functionality
huh neither CraftBlockState or CraftBlock call the relevant method
Does anything in the API make BlockBehavior accessible 🤔
Acually it's BlockBehavior -> BlockStateBase
@Deprecated
public boolean blocksMotion() {
final Block block = this.getBlock();
return block != Blocks.COBWEB && block != Blocks.BAMBOO_SAPLING && this.isSolid();
}
Just realized it's deprecated. TF is replacing it then?!
and why are enderman still using it?!
final boolean flag = blockstate.blocksMotion();
final boolean flag2 = blockstate.getFluidState().is(FluidTags.WATER);
if (flag && !flag2) {
why does LivingEntity#randomTeleport take a PlayerTeleportEvent but isn't public API
wtf bruh
rioting
because they are black
lmao
it's a bit more involved than that, since the chunks contain palette id's
anything, basically
but like i mentioned i will probably end up just using the bukkit api for world state access, as the bot would be packaged in a plugin
it'll be a fit fucked if there are other plugins sending per-player blocks or entities, but for 90% of cases it'll be good enough
for integration testing specifically, however, we do want at least clientside inventory support
the most productive use case i see for this is bundling it into the test runtime of a plugin and running it with runPaper so predictable integration tests can run on what the client sees
step the server tick by tick, assert client state, send client actions, assert server state, rinse and repeat
mockbukkit is pathetic and useless for any realistic testing
okay, let me minify netty
just run a client on the same jvm
why do you need to do that?
idk if you can; the server has many static facilities, so the client might as well
can't use a different classloader?
I have an i5-13500 CPU with 6 efficient cores and 8 performance cores. I have 3 servers: proxy, SMP, and Box1. I'm thinking of doing something like taskset -c 0,2,4 java -jar ... for SMP; then 6, 8, 10 for Box1; then 1, 3, 5 for Velocity. And as I get more players, I'll create Box2, Box3, Box4, etc., which will occupy cores 7, 8, 10, then 11, 13, 15, and so on. From what I've seen, cores 0-11 are the performance cores, where the odd cores from 0 to 11 are hyperthreaded, meaning they are slower than the even cores from 0 to 11. That's why I only use them for Velocity and for the other Box servers as needed. Am I doing this right, or should I let Linux manage this for me and simply use java -jar ... for everything?
I'm even considering using efficient cores instead of performance cores for Velocity, Box2, Box3, etc., because it seems that if the P-Cores are heavily overloaded, their corresponding hyperthreads become worse than an E-Core, and I think that will be the normal case since it's a minecraft server running on a P-Core
I'm saying this based on artificial intelligence, so if anyone with knowledge in this area could give recommendations, I would be grateful
Just let Linux manage it
Why is the material for repeaters DIODE instead of REDSTONE_REPEATER?
hmmm idk how to do inline code
Use two backticks instead of 3
It hasn't been DIODE since it was changed in 1.13, 8 years ago
kekw
Why was it before that?
That was what Bukkit developers decided to call it when it was added
pretty sure that is what mojang called it o.O
That may also be the case
hm interesting
Some items were named differently. Reeds (sugar cane), watch (clock)
Spades instead of shovels I think too
now what bukkit did do was had a habit of not updating names for stuff lol
and kept old names
Yeah Mojang called it Diode for a while
same with shovel and spade
so bukkit would have classes or variables with old names and mapped them to new names except for the classes
Is there any easy was of converting the Bukkit Material to the minecraft names in 1.8.8?
XMaterial
Is that an api?
Yeah
hm ok thanks
or do you mean to display the names?
Speaking of spellings
public int getMoistnessLevel() {
return this.entityData.<Integer>get(Dolphin.MOISTNESS_LEVEL);
}
public void setMoisntessLevel(final int level) {
this.entityData.<Integer>set(Dolphin.MOISTNESS_LEVEL, level);
}
ha
tsk tsk tsk
moist
formatted a la "/give" command and similar
More like Moisnt
ah wait, it's not autocompletable
hell if i remember
they have yes
yea
it had both iirc
until like 1.13 or whenever <the flattening> occurred
Yeah 1.13 ^
Hi from where can i get spigot engine source code
alr got it from buildtools
Now have fun customizing that engine
Named ids were a thing up until 1.13 however not everything had a named id and sometimes when using magic numbers you had to use id. Also ID was popular even when named ids existed because of chat send length being more limited then what it is now and then command blocks as well.
Then mojang fixed those issues so id's are not strictly necessary but i still prefer id's
Why is that? I feel like they're not good
Accually removing mob ai
Because in terms of efficiency/optimizing it is better to have an array of ints than it is strings. They should have made strings purely front side of server and user configurable in terms of mapping. Back end wise it should just be ints as they are easier to manipulate and handle. Thats my opinion anyways.
Also I am great at bitmasks and bitshifting
So with ints i can take advantage of that but not with pure strings
Makes sense
If what you're doing requires that level of optimization then sure, but otherwise I personally feel like the Strings are better because the ids are kinda magic numbers
Sure but not all magic numbers are bad
You can't even really eliminate that completely
What do you mean by this? When would a magic number be preferable to an enum?
Well enums are always loaded and never go away at least not without using some kind of hack, but i suppose for this they would always be loaded anyways.
Loaded as in, they are in RAM?
Is there another kind?
Just wasn't clear to me
I don't know much about how JVM works at a very low level like that
Your class is either loaded or its not. Enums are always loaded
If its a large enum you cant like unload even partial of it
Anyways magic numbers are only bad if you dont have them documented.
Your internet runs off magic numbers
In regards to mc they were only bad because mojang would occasionally change them up lol
Not really suppose to do that lol
Sure but (and this is not an area I know a lot about) isn't that partially because a lot of those protocols are very old and can't be easily changed?
My personal issue with them is that it makes code hard to read, and I usually don't write documentation for code in personal projects as I usually don't share them publically
They can be changed, hence custom protocols existing. The difference is that they are well documented
You can have your internal network use something other than tcp or udp
All you have to do is just tell the systems what that protocol is aka drivers
For example in the internet protocol (IP) it is typically forbidden to have 2 systems with the same IP. But nothing says you can't do it anyways.
As long as both systems dont collide on what they are listening and sending to, you can hide systems this way
As in ports? Makes sense
Ip addresses
Yes
Port sharing is already a thing and has been for decades
But this is referring to different systems with the same IP, but they use different ports?
Nope they can use same ports, just as long they are not listening for the same thing
Would they not both get the request then?
As i said port sharing is already a thing on your system. You can have multiple applications on the same port
Key is what they are looking for packet wise is not the same
Sure but only one should respond
So both applications would get the packets (or a third application would chose which to route them to), but only one would respond, depending on packet contents
Cool
Correct
Is there any reason to run more than one application on the same port?
You might have a logger that you want to be kept separate from the application receiving is an example. Or lets say you run game servers but dont want to configure multiple ports you can just run them all on the same port
In terms of firewall rules its far easier to manage rules for a few ports than many of them
Maybe your isp limits what ports can be open or how many is also another good one
But point is yes the protocols are indeed old but not unchangeable. Maybe for the general public at large but only as long as they dont have the driver to understand your protocol though this includes routers but you can totally have a custom protocol internally and many businesses do indeed run custom protocols
But its all magic numbers. Packet id's, header lengths, data lengths, packet sizes etc. They are not strings just a bunch of numbers and bitmasks and offsets lol
So in a way i agree magic numbers can be bad, but only if you dont document what those numbers are for or what they do lol. And in regards to unreadable code, you dont have to stick with the magic numbers you could just use the mapping or make one on the fly
If mappings were configurable to begin with where a user can name the ID's as they please then it solves that issue. And in regards to clients it would just be sent as a payload like the registries already
Packet ids in Minecraft increase automatically in the addpacket method
Which is super nice
So the devs don't have to work with magic numbers
It's automatic
Well tcp does that too
But that is nice as well
But yeah there are ways to have magic numbers and also not deal with them at the same time lol
you still have a global blockstate palette which is still referenced by every chunk
I don't think it's global
It’s not
There is a global mapping for int -> Blockstate but that’s only used for networking
The palette used by chunk sections depends on the number of different blockstates in the chunk
Linear palette is used for under 8, iirc, and a hashmap based palette until 256 or something fairly large
Larger than that and it will use the global palette
In practice however you probably will never see a section use the global palette since the threshold is so high, except perhaps in a debug world
There’s also a single palette
For single blocks
An indirect palette is used for 2-256 different states
And the global palette is used past 256
public abstract class Strategy<T> {
public static final Palette.Factory SINGLE_VALUE_PALETTE_FACTORY = SingleValuePalette::create; // Paper - Anti-Xray
private static final Palette.Factory LINEAR_PALETTE_FACTORY = LinearPalette::create;
private static final Palette.Factory HASHMAP_PALETTE_FACTORY = HashMapPalette::create;
static final Configuration ZERO_BITS = new Configuration.Simple(SINGLE_VALUE_PALETTE_FACTORY, 0);
static final Configuration ONE_BIT_LINEAR = new Configuration.Simple(LINEAR_PALETTE_FACTORY, 1);
static final Configuration TWO_BITS_LINEAR = new Configuration.Simple(LINEAR_PALETTE_FACTORY, 2);
static final Configuration THREE_BITS_LINEAR = new Configuration.Simple(LINEAR_PALETTE_FACTORY, 3);
static final Configuration FOUR_BITS_LINEAR = new Configuration.Simple(LINEAR_PALETTE_FACTORY, 4);
static final Configuration FIVE_BITS_HASHMAP = new Configuration.Simple(HASHMAP_PALETTE_FACTORY, 5);
static final Configuration SIX_BITS_HASHMAP = new Configuration.Simple(HASHMAP_PALETTE_FACTORY, 6);
static final Configuration SEVEN_BITS_HASHMAP = new Configuration.Simple(HASHMAP_PALETTE_FACTORY, 7);
static final Configuration EIGHT_BITS_HASHMAP = new Configuration.Simple(HASHMAP_PALETTE_FACTORY, 8);
yeah looks like i got the linear palette threshold wrong, it's 16 and not 8
seems about right
return (Configuration)(switch (bits) {
case 0 -> Strategy.ZERO_BITS;
case 1, 2, 3, 4 -> Strategy.FOUR_BITS_LINEAR;
case 5 -> Strategy.FIVE_BITS_HASHMAP;
case 6 -> Strategy.SIX_BITS_HASHMAP;
case 7 -> Strategy.SEVEN_BITS_HASHMAP;
case 8 -> Strategy.EIGHT_BITS_HASHMAP;
default -> new Configuration.Global(this.globalPaletteBitsInMemory, bits);
});
If you have more than 256 different block states in a single 16x16x16 area that’s pretty Wack
though it looks like it uses the 4-bit linear map for bits 1-4
Yeah it doesn’t bother going below 4 bits
yeah i don't think that is going to happen unless someone really tries to make it happen
Free optimization!!!!11
I’m going to make an unoptimized server fork that always uses the global palette when sending chunks >:D
you mean 1.8
or whenever palettes were even introduced
did 1.8 have palettes yet? for the longest time we just had 8 bits per block type and then an extra 8 bits of "damage value"
i remember experimenting with per-bit-width implementations of the strategy
for them magic multiply division things
where instead of dividing by a number you multiply with a big magic number and then right shift
and since the bit width was a constant, jit was free to go ham with whatever magic number substitutions it could come up with
however there were no measurable performance gains
har har har python
tf are you doing on a Minecraft server where Python is involved?
it's like skript but for "programmers"
https://docs.python.org/3/library/audioop.html tuff, probably
no for my bot
Okay, unrelated. That makes more sense
lol yeah easy
oh yeah fixed ty
switched to Python 3.12
CraftArmorStand craftSeat = (CraftArmorStand) seat;
EntityArmorStand nmsSeat = craftSeat.getHandle();
nmsSeat.setGravity(false);
nmsSeat.setPositionRotation(newLoc.getX(), newLoc.getY(), newLoc.getZ(), newLoc.getYaw(), newLoc.getPitch());
guys
why the setGravity(false) is not working??
help pls
the armorstand keeps falling
i dont know sorry
😔
try setting the gravity after setting the position or after its spawned in
They already fixed it
Apparently the NMS setGravity is misnamed and should be setNoGravity
ah, didn't realize it was continued in general lol
is inventory#getholder performance better than in the past?
There’s still no need for custom holders tho
does it matter if you check if the holder is instanceof your custom class in an inventory click event which is common? it'll still create a snapshot
I mean if you are making paper plugins and can use their no snapshot method then I guess it’s fine
Otherwise you are just making bad plugins
Hi there, I'm working on a Hide and Seek plugin. Whenever a Hider is running around, I can hit them. But as soon as they turn into a BlockDisplay, I am not able to hit the block and register a hit. I have tried so many different solutions, but nothing is really making a difference (have been trying for hours straight haha).
Is there anyone that might know a fix for this?
Here are the most important classes, if you need any other classes, feel free to let me know.
DamageListener: https://pastebin.com/f8Bjv0ZQ
BlockHitListener: https://pastebin.com/kjRhU0wW
BlockDisguise: https://pastebin.com/nGqeEwxn
Thanks for your help in advance!
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
i haven't looked at anything, but block displays aren't interactable
if there's no physical block there, you need an Interaction entity for an interactable hitbox
By this, do you mean the BlockDisplay should be replaced by a real block or what do you think would work?
I am working with BlockDisplays indeed.
The player is also being teleported to the blockdisplay position, ive tried looking if the location of the player matches with the location the seeker is trying to hit, but that didn't seem to work
I'm not really a fan of AI, but because I'm pretty lost I have tried asking it anyway, it told me to detect left click in air and ray trace forward, but that did not have any effect either.
BlockDisplays have no hitbox
i mean keep the block display but also spawn a matching Interaction
Add an interaction entity as a passenger so they actually have a hitbox
Oh I have never worked with that, thank you very much I will have a look!
it's basically an invisible hitbox
specifically meant to make things that normally don't have hitboxes interactable
Okay it does seem to work better now! One note: do you know why it's only triggering when I'm hitting the top of the block? If i try to hit the sides of the block it seems to have no effect, but the top does work
turn on hitboxes in the client debug and see if it matches the block display
Ah okay I can tell the hitbox does not match the block indeed! I'm gonna try to fix that right now
Thanks <3
Is there an easy way to match the hitbox with the blockdisplay ?
add a vertical translation to the transformation of the block display
and move the entity itself a bit lower
or ditch the passenger approach and teleport the interaction to the display every tick
that's generally something you want to avoid as it easily looks jittery, but since interaction entities are invisible, it doesn't matter
Ah okay I understand, it works now, I'm very happy! Thank you very much <3
Thanks to you as well! :)
👌
@eager hawk I'm not so sure if Block Displays are great for this
They don't have the same lighting as placed blocks, they have no AO
In some cases it may be rather easy to just see the hider
(I am using perf. mods, they may alter the way the game looks here, do test this yourself)
Ah okay I did not know that, thanks for informing me! I might want to switch over to a way with normal blocks then.
didn't you have it set up so that when the player stops moving, it turns into a regular block? or was that someone else
but yes, block displays are very easy to tell apart from regular blocks if you're looking for them
Atm it turns into a BlockDisplay when the player stops moving, that's why I had to implement the Interaction part
But I might be better off switching to regular blocks then
I don't know how yet, because rn the player stands inside of the blockdisplay, but ofc that's not possible with real blocks since they will push the player out of it
Spectator mode is what comes up in my mind but the player needs to be able to move and jump as well when leaving the solid block position
just change the players size and teleport them right on top of the newly placed block
hahah
I tried, but as a seeker if I walk over the block I push the player away and it removes the disguise
you can disable collisions
with teams I think
Mount them on an armor stand so they have to explicitly dismount and can't accidentally get bumped or hit a key and break their disguise
https://pastes.dev/Jik2S4OhTH If the def is not null, then the getString method will necessarily return a non-null value?
yes* except maybe if the config has specifically a null value for that key, but i'm not sure if that's treated as absent
no, if the path exists and contains nul, then the method might return null too (according to the docs)
hm the Contract annotation says otherwise. so either way the docs are wrong, or the annotation is wrong ah nvm then "the value" would not be "a string"
TL;DR yeah if "def" is not-null, return value is guaranteed to be not-null
I hate java
public boolean isSet(@NotNull String path) {
Configuration root = this.getRoot();
if (root == null) {
return false;
} else if (root.options().copyDefaults()) {
return this.contains(path);
} else {
return this.get(path, (Object)null) != null;
}
}
yeah it looks like MemorySection treats nulls as not present
that whole config api of bukkit is kinda weird
yaml in general is kind of ass and bukkit wrapping it into another poorly thought out abstraction layer didn't help
yea the config format is nice itself in the right place
it's good in some aspects and okay in others, problematic in a few
people need to get introduced to object mapping early in life
thats an example of it
afaik object mapping is quite general where it means u have some isomorphism (one-to-one) mapping between two domains and that is to a large extent/completely structure preserving (might omit certain transient fields for example ^^)
yeah I more so mean automagic object mapping that gson jackson ktx.serial etc do
you know, that thing where you just tell gson "give me a list of this Person class"
oooh yea
guys i need help
?ask
If you have a question, please just ask it. Don't look for staff or topic experts. Don't ask to ask or ask if people are awake or available. Just ask the question to the channel straight out, and wait patiently for a reply. Make sure you use the right channel regarding the topic of your question. Create a thread in case the channel is already in use!
was Base64Coder removed in this latest release?
Thanks I will try that out!
Whenever the seeker tries to hit the top of a block (disguised player), it hits the player on top of it instead. It should only register block hits and somehow be able to hit through the player, because right now the invisible player is covering the top of the block. Do you have an idea how I could make that possible?
mmm you can hide the hider from the seeker. Not sure if this method works for players.
https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/Player.html#hideEntity(org.bukkit.plugin.Plugin,org.bukkit.entity.Entity)
that should make the hider intangible for the seeker and prevent some cheats that show invisible players (I assume that's how you do it now)
declaration: package: org.bukkit.entity, interface: Player
whats the best way to check for a specific custom structure near a specific block? (im assuming that hard coding every single coordinate for every required block relative to said block is not the best method)
context: players need to make a small structure and when they place a player's head on it, a piece of code will run and the structure will dissapear
that seems like a structure bigger than oliver193's mom
in that case I'd use chunk snapshots
💀
I would compare it to an nbt structure loaded with the api
Makes it easy to change the structure
Bro 💀
what's difference between EntitiesUnloadEvent and EntityRemoveFromWorldEvent ?
an entity can be unloaded but still be alive - e.g. persist?
RemoveFromWorld is when it "dies" - is gone forever
oh my bad
due to
- being unloaded
- dying
- going to another world
yeah anyway, javadocs explains it pretty well
unloaded means the chunk it is in was unloaded
isnt that exactly what I said?
you said removefromworld means it's gone forever
in a certain sense unloadedevent is a subtype of removefromworldevent; unloading a mob causes it to stop being in the world
RemovedFromWorld = gone
UnloadedEvent = chunk unloaded but might be back again when the chunk gets loaded again?
no
removefromworldevent also gets fired when it unloads
because it ceases to be in the world
ah ok
once it loads it will appear again with an entityaddtoworldevent
ok makes sense
the remove and add events are especially useful to maintain caches or lists of loaded entities that you might want to e.g. tick
since they by definition mark the start and end of a loaded entity's lifecycle
for example, i used them in villager lobotomizatornator to track lists of lobotomized and alive villagers to check periodically and to restock their trades
it's much cheaper than iterating over all entities in the world, especially when targeting mobs that are relatively rare, like villagers, or in his case "minions"
this is exactly what i said last time btw
It's unfortunate that there's no way to actually save maps into map_#.dat files without them being blank. I think I would have to resort to listening EntitiesLoadEvent and then filter to ItemFrames with maps in them, then hooking up MapRenderer based on ID read from ItemFrame.
Unless there's some API library that does allow that?
I probably didn't understand or I forgot my bad
what're you trying to do
if you're trying to do image maps, several plugins for that already exist
you can check how HuskSync does it, it's on github
I'm trying to save maps into map_#.dat files, so that they can persist across server restarts
for more library/api focused things, there's this https://github.com/MinceraftMC/MapEngine which is quite powerful
i don't remember if it does persistence, but it does image manipulation and protocol nonsense to spawn per-player item frames with maps at least
if you really want to actually write to the file yourself, it's pretty simple as well; it's a 2d array of 128x128 bytes, each representing a palette color
i feel like i'm having deja vus twice a week or something
however i would recommend against doing this if you're trying to do "images on maps"
as all map.dat's are stored permanently in memory
and not very efficiently at that
Bukkit/Spigot already permanently stores them in memory, as 128x128 bitmap with all pixels being transparent. Generating new maps on every restart would waste more memory, not less
yes, so my recommendation is not going through bukkit for them at all
but rather using something like MapEngine to manage them on the protocol layer
i.e. the server is not aware of your custom maps at all, and a plugin sends their data to clients on demand instead
Basically there are two states: "idle" and "active". Active does animations and stuff, bukkit API already allows that. "idle" is just an item frame with a map picture existing in the world, until right-clicked. I don't want to write protocol stuff for all random itemframes with my maps in them, vanilla behaviour is enough.
eyeballing mapengine, it doesn't seem to offer persistence
you can take a look at husksync like mfnalex suggested, or you can write to the .dat manually; the format is simple and you can grab the palette bytes directly from the bukkit canvas
Yeah, I did that for Sponge back then. But I heard that 26.1 changed the map file stuff, so it would be a brittle solution
i'm not aware of any public api or library that'd do the persistence for you, someone else might; nms is also an option
public class WoodCuttingListener implements Listener {
private final Set<UUID> activeCutters = new HashSet<>();
public WoodCuttingListener(JavaPlugin plugin) {
Bukkit.getScheduler().runTaskTimer(plugin, () -> {
for (UUID uuid : new HashSet<>(activeCutters)) {
Player player = Bukkit.getPlayer(uuid);
if (player == null || !player.isOnline()) {
activeCutters.remove(uuid);
continue;
}
Block target = player.getTargetBlockExact(5);
if (target == null || !Tag.LOGS.isTagged(target.getType())) {
stopCutting(player);
continue;
}
player.damage(1.0);
}
}, 5L, 10L);
}
@EventHandler
public void onBlockDamage(BlockDamageEvent event) {
Player player = event.getPlayer();
if (Tag.LOGS.isTagged(event.getBlock().getType()) && !isAxe(player.getInventory().getItemInMainHand().getType())) {
activeCutters.add(player.getUniqueId());
updateBreakSpeed(player, 0.0);
}
}
@EventHandler
public void onBlockDamageAbort(BlockDamageAbortEvent event) {
stopCutting(event.getPlayer());
}
private void stopCutting(Player player) {
if (activeCutters.remove(player.getUniqueId())) {
updateBreakSpeed(player, 1.0);
}
}
private void updateBreakSpeed(Player player, double value) {
AttributeInstance attribute = player.getAttribute(Attribute.BLOCK_BREAK_SPEED);
if (attribute != null) attribute.setBaseValue(value);
}
private boolean isAxe(Material material) {
return material.name().endsWith("_AXE");
}
}``` If you hold down the LMB on the block and look at the air, then back at the block, you can break it with anything. How to fix?
does it fire the events in the order you expect?
it doesn't trigger onBlockDamage because the lmb is still held down
When I look away from the block onBlockDamageAbort is triggered, but when I look back at the block onBlockDamage is not triggered
i wonder if that might be an api bug
you'd assume that if BlockDamageAbort fires when looking away, BlockDamage would fire again when looking back
i suppose you could not use the bukkit api and instead listen to whatever packet gets sent when a player starts mining a block
that's what people used to do before these events
is it being triggered by the event or your tick loop?
by the event
?services
If you wish to request or offer development/art/building/administration services, please do so at https://www.spigotmc.org/forums/services-recruitment-v2.54/
ty
cam anyone help me make a simple minecraft server
maybe, what do you need help with?
hey, can anyone help me with two things? firstly, I want it so it detects any player within 15 blocks, gets their loc and then puts lightning on then, and it also deals five hearts. I also want to make it so when hitting with a specific sword, it will have a 10% or so chance to give the person 3 hearts of tick damage and the person who hits them 3 hearts of "tick damage" back, if possible can you explain how/what the code means since i feel pretty bad if i just copied code especially since im asking for a lot, very new btw, thank you in advance.
when you say, "any player within 15 blocks", what is the player within 15 blocks of?
also, what do you mean by "tick damage"
particularily i want it to be a trident when you left click it does 15 blocks around the player who left clicked it and when you right click 15 blocks wherever the trident lands
and tick damage like when you jump in the void
but ofc less damage but idk if thats possible
So like, just damage? What do you mean by tick
yea kinda but damage over time so like every second it could t ake a heart stopping at 3
sorry if i worded that confusing
Ah I see
So, for detecting when a player left clicks, you're going to want to listen to PlayerInteractEvent. Then, check if the player is holding a trident, and the action was a left click. You can use getNearbyEntities and then filter for players to get a list of nearby players. To check when a trident lands, you can use ProjectileHitEvent. To strike lightning that deals an amount of damage that you choose, use getWorld.strikeLightningEffect(), and then call damage() on the right players
For the sword, you'll want to listen for EntityDamageByEntityEvent. To get a random number you can use Math.random(). To do damage over time, you can use a runnable.
thank you so much 🙏
wlc! if you need me to go into more detail on anything I can.
yep, i will def try that and if i need help with a part ill ask, thank you
It's better to check if it isnt a trident or a right click etc and return early
@EventHandler()
public void OnClick(PlayerInteractEvent event) {
if(event.getPlayer().getInventory().getItemInMainHand().getType().equals(Material.TRIDENT))
if (event.getPlayer().getInventory().getItemInMainHand().getItemMeta().getLore().contains("Lightning")) {
Player player = (Player) event.getPlayer();
// Right Click
if(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
if (!list.contains(player.getName()))
list.add(player.getName());
return;
}
// Left click
if(event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) {
// 15 block stuff
Location tridentleft = player.getLocation();
for (Entity playersnear : tridentleft.getWorld().getNearbyEntities(tridentleft, 15, 15, 15)) {
if (playersnear instanceof Player) {
if (!tridentlist.contains(player.getName()))
tridentlist.add(player.getName());
if (tridentlist.contains(player.getName())) {
Location tridentlightning = player.getLocation();
tridentlightning.getWorld().strikeLightning(tridentlightning);
player.damage(10.0);
}
}
}
}
}
}
@EventHandler
public void onLand(ProjectileHitEvent event) {
if (event.getEntityType() == EntityType.TRIDENT) {
if (event.getEntity().getShooter() instanceof Player) {
Player player = (Player) event.getEntity().getShooter();
if (list.contains(player.getName())) {
// 15 blocks around it
Location tridentthrow = event.getEntity().getLocation();
for (Entity playersnear : tridentthrow.getWorld().getNearbyEntities(tridentthrow, 15, 15, 15)) {
if (playersnear instanceof Player) {
if (!tridentlistthrow.contains(player.getName()))
tridentlistthrow.add(player.getName());
if (tridentlistthrow.contains(player.getName())) {
Location tridentlightning = player.getLocation();
tridentlightning.getWorld().strikeLightning(tridentlightning);
player.damage(10.0);
}
}
}
}
}
}
}
}
this doesnt work, ik there are prolly multipel thigns wrong but nothing obvious bcuz intellj idea hasnt picked up anything
i tried with a friend it didnt do lightning or any damage, so its probably related to the list and picking up them on it to run the lightning, if i had to guess
if there are any obvious mistakes its prolly from me copying it from idea
like really obvious ones
What are you trying to achieve?
so bascially when you left click, it picks up on all players within 15 blocks, and strikes them with lightning and does 5 hearts. and when you right click it does the same but on where the trident ladns
lands*
First of all you should do null checks, like if (playersnear instanceof Player) playersnear may be null, so do if (playersnear == null) continue before checking instanceof
otherwise you would flood the console with NPE's
oh yeah i should check console
Also why do you have a list?
not really but there could be multiple players within 15 blocks
but it probably doesnt matter
you don't need a list, since you are looping through all nearby entities
and then checking if they are instanceof Player
it will apply it to all of them
Can I DM you? better than here
alright
crateId = new NamespacedKey("ExcellentCrates", "crate.id");
keyId = new NamespacedKey("ExcellentCrates", "crate_key.id")
how can I solve this?
tells you right there
a-z not a-zA-Z
oh yea thanks
reading always helps in debugging
TLDR; left part of NamespacedKey must be lowercase
probably because of Windows support, which is the only current OS in use today that can't deal with both FOLDERNAME and foldername being at the same space
I read it, but I'm stupid
what's the replacement for PlayerLoginEvent?
i can't use playerjoinevent bc i need event#getHostname
Maybe this? https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/player/AsyncPlayerPreLoginEvent.html
declaration: package: org.bukkit.event.player, class: AsyncPlayerPreLoginEvent
Why do I need Cloudflare WARP to join Minecraft servers in the newer versions?
And why do I only need it in the newer versions? I don't need it in version 1.20
Well, I'm not the only one reporting this problem
And everyone just happens to be running warp/vpn to fix the issue?
this sounds very much like a not Minecraft problem lol
yes
maybe tlauncher issue. i'll see the original launcher
Why doesn't setSprinting(false) work?
How can I cancel a sprint for a player?
kill them
setSprinting should work for stopping the current sprint
but doesn't prevent them from sprinting again
@EventHandler
public void onSprintToggle(PlayerToggleSprintEvent event) {
event.getPlayer().setSprinting(false);
}``` I don't stop sprinting when I press ctrl
cancel the event?
Same
You probably want to set the hunger to stop spriting
or is there an attribute for that now?
Anyways since there will be latency between the event and the player actually starting to sprint
Then the hunger bar will probably look strange.
Hello guys i have created a plugin and im trying to make a custom texture pack for it but i dont understand how to do it i have created a file with all of the textures and models but i cant get it to work
What part do you need help with
and what have you tried
i have tried putting some override thing i dont really understand in in some .json files and custom id data or smth then put on the recource pack but nothing happened
You're going to have to be a lot more specific than that
What version are you making the resourcepack for. That is important
You say you're trying to use custom model data (probably). Do you need that? If it's just a simple custom model like a very fancy sword then there is a better way in newer versions.
im using 1.21.11 i have created custom swords with custom abilitys and i want custom models for them so far i have created a folder with
assets - minecraft - models - item. then the custom items name.json
pack.mcmeta textures - item. then png of the custom textures
pack.png
thats the stuff i have in the folder i dont know what more i need to explain this is my very first plugin and recource pack
Ok, so you only need simple custom model, great!
I'd recommend just opening up the vanilla resourcepack (or use this github link) and copying stuff from there
Per each custom model you will need the following files
namespace/items - Eg
namespace/models/item Eg
namespace/textures/item Eg
I'd recommend not using the minecraft namespace and instead using your own
then on the plugin side, when creating your custom items you call setItemModel the key is created from the bolded parts: minecraft/items/acacia_boat.json (here you'd use your namespace and your item model definition file name)
lowk make this a wiki post
lol
someone else could always come by and improve it later
Hi, I'm new to plugin development, where should I start?
Do you have any programming experience?
giving me money is always a good way of starting anything
Learn Java basics. After that, start a project and don't use too many tutorials
im trying to make a system where when a player dies, their head is placed nearby at a safe spot
but im facing an issue with if the player dies to the end void and theres no blocks nearby to put the head on, or if they die by drowning in a large ocean where theres no "safe" blocks nearby
have you guys run into this problem before? whats the best compromise for this?
?java
woops
?learnjava
For Beginners:
Codecademy - Learn Java: Interactive Java programming course from basics to more advanced concepts. Perfect for absolute beginners.
https://www.codecademy.com/learn/learn-java
JetBrains Academy - Java Developer Track: Learn by doing with projects and challenges. It covers Java fundamentals to advanced topics.
https://www.jetbrains.com/academy/
Udemy - Java Programming Masterclass for Software Developers: Updated courses that cover Java 8 to Java 17 features. Suitable for those who prefer structured learning.
https://www.udemy.com/course/java-the-complete-java-developer-course/
For Intermediate to Advanced Learners:
Oracle Java Tutorials: The official guides by Oracle for Java programming—great for understanding the depth of Java.
https://docs.oracle.com/javase/tutorial/
Baeldung - Learn Java and Spring: Focus on Spring Framework and modern Java technologies. Best for intermediate learners aiming to expand their knowledge.
https://www.baeldung.com/
Practice and Hands-on Learning:
Exercism - Java Track: Solve exercises and get feedback from mentors. Great for practicing coding skills.
https://exercism.io/tracks/java
LeetCode: Practice your coding skills and prepare for technical interviews with Java.
https://leetcode.com/
Free Resources and Documentation:
Java Programming and Documentation: A comprehensive collection of Java programming guides, tutorials, and API documentation.
https://docs.oracle.com/en/java/
Community and Support:
Stack Overflow: A vast community of developers. Great for getting help with specific problems or understanding concepts.
https://stackoverflow.com/questions/tagged/java
r/learnjava on Reddit: Join the community of Java learners and get advice, share resources, and discuss projects.
https://www.reddit.com/r/learnjava/
Remember: Learning to program takes practice and patience. Don't hesitate to experiment with code and participate in community discussions. Happy coding! 🎉
there we go
You could put it on top of the ocean
Or just track where they last touched solid ground
Hey, I'm looking for an experienced Java developer specialized in high-performance backend systems. Must be proficient with NMS, packet handling, and asynchronous data management (Redis/SQL). If you're interested in building a scalable, custom engine from the ground up, please DM me for a brief technical discussion.
?services
If you wish to request or offer development/art/building/administration services, please do so at https://www.spigotmc.org/forums/services-recruitment-v2.54/
Help on a project
If you wish to request or offer development/art/building/administration services, please do so at https://www.spigotmc.org/forums/services-recruitment-v2.54/
is it possible to somehow for intellij to download javadocs of std lib?
it does that for me when i click the "download sources" button, or do you mean the html javadocs specifically?
Download sources and documentation
also works for any external libraries that have published sources
if on linux, download jdk sources from your package manger
it wasn't automatic for me
only the docs were
then yeah use package manager to dl sources for your jdk version
it was something openjdk-version-sources
then here just add it
/usr/lib/jvm/openjdk-25
for me it's here
probably for you as well
ofc arch puts docs somewhere else
because why wouldnt you
we love fragmentation
does community edition has branch coverage ui available in intellij?
i remember on ultimate edition there was this feature where you can visually see which test reaches what branch
not sure if this is paid feature or not
I have not tried this yet
I believe so
this shit again
choke on a blender
it's unreal how i get locked out of my account any time i DM someone first, but these spambots continue to be a problem year after year with seemingly no checks or balances on them
never have i been banned by discord, and i hope to keep it this way
altho twitter removed my tweet i think because it looked like ai
it was something on the line: "curse boldly with a hint of red"
for a html/css hack
i fucking hate how java doesnt support generics on exception types
meh, you get used to it
it has cool stuff like multiple catches or multiple cases with Exception1 | Exception2
still better than manually checking raised error flags
awesome 😄
trying to teleport a block display chest inside of a slime (constantly every tick) but its inconsistent sometimes it works and sometimes its just off by like a block (as shown)
tried all of these and they do about the same; don't work
display.teleport(slime.getLocation().clone().add(-0.5, 0, -0.5));
display.teleport(slime.getLocation().clone().add(0.5, 0, 0.5));
display.teleport(slime.getLocation());
(first image is what it should always look like, but often it looks like second image instead)
yea, might be easier to wait until sulfur cubes release and check how they do it lol
check how they do it.
is this something they do?
are you using runTaskTimer or runTaskTimerAsynchronously?
Yea, the new sulfur cubes will have blocks inside of em. I think that's what they might be trying to re-create here
@barren peak try Transformation btw
attach the display via a passenger and use Transformation to offset it.
- also, this looks like you're getting the location within the lambda, shouldnt you do it before?
liek:
Location muhammad = slime.getLocation();
Bukkit.getScheduler().runTask(plugin, () -> {
display.teleport(muhammad.clone().subtract(0.5, 0, 0.5));
});
Muhammad the slime
no, it's muhammad the location
what should i use to make a new plugin? i was using Minecraft Development but idk it isn't working rn
you can also just use default maven, define your project, and put the api to your pom
if you just wanna get it running
but we can also help you with fixing your current environment if we get more info
okay ty and i should create the folders and files by myself right?
if you are using IJ, creating with maven does everything for you pretty much
you just define the plugin yml in your resources folder
i tried to build a new project with Minecraft Development but it's giving error importing bukkit in the main file and on the pom it gives error about artifactId
which error?
brb
is there any reason to use protocollib > nms? I just spent 2+ hours trying to solve a protocollib problem and when I switched to nms I solved it in like 30 seconds
I don't use protocollib because when i had my server it was using too much ram and it was crashing my server which made me stay away from it as a developer
And yeah doing it in nms is usually faster which is nice too
But i'm pretty sure it's just because you're not familiar with the wrapper nature of protocollib
I couldn't figure out how to make it stop wrapping everything in a {"name": "value"} structure without remaking some of the stuff
for nbt
I see
i figured out how to do it thanks, but how can i support each time of color like &5 and hex too?
Minimessage or ChatColor translate alternative and for hex you would use one of these 2 https://github.com/Fr33styler/BenchmarkZone/blob/main/src%2Fmain%2Fjava%2Fro%2Ffr33styler%2Fbenchmarkzone%2FMain.java
The java version or regex version
and how should i detect them like how can i detect when i have to use one and when i know i have to use the other?
Just replace the string once when's possible and that's that.
If you get it from config replace & to color char and from #aabbcc to the supported hex format
punctuation
maybe it's because we aren't meant to
?paste
Looking to paste something? Try a code block or one of the following websites:
- https://pastes.dev/
- https://sourceb.in/
- https://mclo.gs/ (best for server logs)
Would patching a vanilla bug be something that spigot would allow? Or does it depend on what the bug is?
Depends on the bug and the patch, but probably
Cool, well I've been looking into these issues.
https://hub.spigotmc.org/jira/browse/SPIGOT-7228
https://bugs.mojang.com/browse/MC/issues/MC-149563/https://bugs.mojang.com/browse/MC/issues/MC-279073
I have multiple would-be patches for this, but wasn't sure which would be best.
One of which specifically targets the enderman, and the other that handles all mobs effected by this
I think all mobs would be ok but you need to be careful it doesn't affect targeting/anger across worlds if that's a thing
vavr seems to be such a nice lib to work with
did spigot do anything with the world format in 26
i see paper tearing their asses apart over it trying to do some new world dir structure of their worn
Spigot uses the same world structure it has since multi world was introduced ~15 years ago. The only difference with 26.1 is the folder names have changed from DIM# to dimension/name
(same change as Vanilla)
makes sense
What's up guys, I'm almost finished with my Hide and Seek plugin, but I'm just struggling on one last issue.
My BlockDisguise class looks like this: https://pastebin.com/WFKfzmTt
As you can see in the clip (, even though the player is invisble, I can still hit their body. https://medal.tv/nl/games/minecraft/clips/mpyj624hllXd1MkdM?invite=cr-MSxQUjQsMTk4OTMwNTE5&v=8
Is there a way to disable this and only be able to hit the block on the armorstand, without the player body being there for the seekers?
I tried stuff like p.setCollidable(false) and others but that didn't seem to work out.
Thanks in advance!
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Bekijk player hit bug van xthry_ en miljoenen andere Minecraft video's op Medal. #minecraft
this won't be effective against hacked clients or people with hitboxes enabled in the debug, but you could scale the player down to be near 0 blocks in size, and make sure they and the armorstand are contained in the hitbox of the interaction entity/block display
to be effective against hacked clients, you'd want to actually remove the player entity or make them appear to be somewhere else
this is easy with the paper player visibility api, but will cause the player to also disappear from the tab player list
Spigot also has visibility api smh
Player#hidePlayer
and player.spigot().setcollidable false
for arrows
i really disliked how paper handled the arrow colliding with armor stand
you can't hit armor stands, they just bounce off them
i should probably try with a size 0 hitbox
Thanks for the info!
But then the player is also removed from tablist, isn't that a bit weird in a hide and seek minigame?
Since I assume it's best to keep alive players in the tablist, but yeah then I have this issue like you can see on my clip, I'm trynna find a way around that works fine, looks good and is effective but I can't seem to find something
What version are you in
1.20.1
Ah shit :') I'm working on it for a specific server which is 1.20.1 so unfortunately I can't upgrade
Do you have an idea how I could work around this?
Hmm
You could put the player into spectator and then have them spectate a tiny entity
But then they won’t be able to move without pressing shift first
Yeahh I thought about that too, but like you say they can't really move then which is not so effective :(
You could disable the damage event and then manually raytrace to check for players hitting the hiders
Yeah that could be an idea, I just feel like, even though the Damage Event is disabled, the players body is like in the way of the armorstand (if you get what I mean)
Like even when I'm trying to hit the Astand im still hitting the body first
bcs its in the way
Oh okay that sounds good, will I still hear the sound of hitting a "body" when the event is disabled?
Like not damaging but the hit sound
I will check it out thanks a lot!
If anyone else has more suggestions let me know, I will look into everything in the meantime :)
yo, how do i check a players main hand then check if it has a specific lore? im using an onclick event rn bit i need to check if the item they are clicking with has a certain lore (a custom weapon), thanks
?jd-s
i believe it is Player.getEquipment()#getItemInMainHand()
and then u can do getLore on that items metadata
u should probably be using a PDC instead of lore for custom item tracking though, imo
?pdc
alright thanks, will try
hi, may I send a picture here?
I would like to present my idea
No-one is stopping you, either verify your account to get attachment perms or use imgur.
Hey, some time ago I started working on a survival plugin where the main idea was to have a 3D interactive UI inside the Minecraft world, something similar to the floating interfaces you see in movies or anime.
The reason I started this was because commands can sometimes be hard to use for players, especially when there are a lot of them or when they require explanation. So I thought about replacing commands with a visual screen that players can interact with directly.
The project eventually turned into an API.
It’s still in development, but it’s close to being finished. The main things left are adding scrolling for long content and providing more ready-to-use components so developers can build and customize their own interfaces more easily.
The system allows you to create multiple screens per player, each with its own independent content. For example, you could have a notification screen, an inventory-like screen, or anything else you want.
In short, the idea is to let developers build any kind of system and connect it to a visual UI inside the world.
I’m mainly curious about one thing:
Would anyone actually be interested in using something like this?
damn so this is with resourcpeacks right?
no. this is Text_Display entity. and Item_Display
shoula started with that , makes it wayy more impressive
Yes, so far the result is impressive, and I’m considering releasing it later as a system once it’s ready. However, I wanted to know if anyone would actually be interested in using this system in the first place.
What’s the point of the sulfur cube?
I don’t get it
I think anything they could do could be done with display entities as well
.sorry
i dont think he was talking to you.
i think hes mentioning the thing hes replying to
I hate Google Translate
😭
yo so i need to find the itemmeta for a projectile (trident) to find the pdc of it, is there a way to get the item's meta still? thanks
Trident, the entity?
idk what you mean "projectile", once they are thrown, they transition from an ItemStack to a Trident entity... it is no longer an "item", so im not sure what you mean "item's meta". accessing an entity's PDC does not require accessing any other data
(... instanceof Trident trident) PersistentDataContainer pdc = trident.getPersistentDataContainer();
oh, I didnt know that mb im pretty new to this, thank you this is what i meant
Nah all good mate, best of luck
I doubt the items pdc will transfer to the projectile entity
You can use trident.getItem and then get the items pdc from there
just saying this in case the guy wants something else
pretty sure it does
just tried and it doesnt
because for this it returns null:
NamespacedKey key = new NamespacedKey(JavaPlugin.getPlugin(Main.class), "tridentkey");
PersistentDataContainer pdc = trident.getPersistentDataContainer();
String value = pdc.getOrDefault(key, PersistentDataType.STRING, "<null>");
player.sendPlainMessage(value);
nah all good
well yeah then
ItemStack item = trident.getItemStack();
ItemMeta meta = item.getItemMeta();
item meta doesnt work for projectiles though right?
getItem() not itemStack
?main and you should either use dependency injection or static private variable with a getter to get the plugins instance scratch this, apparently bad practice?
my bad g
thank you it worked (i think atleast so far)!
That Main post is BS, dude just doesn't like naming it Main.
All other projects need a main class as an entry point, so does your plugin specified in plugin.yml.
I don't see anything wrong with using Main, and that post does nothing to change my mind.
yes, but it's not the Main class or entry point of the application
you can call it MyPluginMain, but Main alone is unspecific and not ideal
suppose for example you depend on 3 different plugins and have to interact with their main classes
now you have 3 ambiguous Main's that you have to reference via fully qualified name
^
:chatting:
All my plugins are named SomethingPlugin
gotta be rage bait
blue checkmark xitter account levels of engagement bait
lol, ill name my next listener class just 'Listener' as well.
And my next manager just 'Manager'.
I like this. Keeps things simple.
if less same, why more?
As of right now I am working on a Java plugin for geofenci g. Anyone have better idea than maxmind considering maxmind only does country? I am trying to restrict a regional for compliance
import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.record.Subdivision;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
public class JurisdictionalGuard implements Listener {
private DatabaseReader reader;
public JurisdictionalGuard(File databaseFile) {
try {
this.reader = new DatabaseReader.Builder(databaseFile).build();
} catch (IOException e) {
e.printStackTrace();
}
}
@EventHandler
public void onPreLogin(AsyncPlayerPreLoginEvent event) {
InetAddress ip = event.getAddress();
try {
CityResponse response = reader.city(ip);
Subdivision subdivision = response.getMostSpecificSubdivision();
if (subdivision.getIsoCode() != null && subdivision.getIsoCode().equalsIgnoreCase("CA")) {
String kickMessage = "§c[SECURITY NOTICE]\n" +
"§fAccess from your jurisdiction is restricted.\n" +
"§7Reason: §fCompliance with CA AB 1043 / AADC.\n" +
"§7Infrastructure: §ePrivate / Non-Commercial\n" +
"§cUnauthorized access is a violation of 18 U.S.C. § 1030.";
event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_BANNED, kickMessage);
}
} catch (Exception e) {
// Log or ignore lookup failures
}
}
}
what do you need? state?
Yes.
After some more research I realized the issue was using the MaxMind Country DB, which doesn't contain subdivision data. Swapping to the GeoLite2-City database allows the getMostSpecificSubdivision() call to correctly return ISO codes like 'CA'.
I am now implementing a "Double-Check" redundancy logic using IP2Location as a secondary provider. If either database flags the IP as a restricted jurisdiction, the connection is dropped. Here is the updated null-safe logic for those implementing this:
@EventHandler
public void onPreLogin(AsyncPlayerPreLoginEvent event) {
InetAddress ip = event.getAddress();
try {
CityResponse response = reader.city(ip);
// Ensure subdivision data exists before checking ISO code
if (response.getMostSpecificSubdivision() != null) {
String isoCode = response.getMostSpecificSubdivision().getIsoCode();
if (isoCode != null && isoCode.equalsIgnoreCase("CA")) {
String kickMessage = "§c[SECURITY NOTICE]\n" +
"§fAccess from your jurisdiction is restricted.\n" +
"§7Reason: §fJurisdictional Compliance (AADC).\n" +
"§7Infrastructure: §ePrivate / Non-Commercial\n" +
"§cUnauthorized access is a violation of 18 U.S.C. § 1030.";
event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_BANNED, kickMessage);
}
}
} catch (Exception e) {
}
}
Sorry to have bothered you all.
Spigot convention, from what I've seen, is to name your entrypoint class the same as your plugin name
Is it possible to get information about right-clicking on air/water without an item in hands?
you can workaround the fact that interact event isn't called in that scenario by placing an interaction entity at the player's line of sight at all times
good option
or fill all the empty slots with invisible items or something
we got age gated minecraft before gta 6
so basically I have a custom bow setup which uses a PDC to check if its that custom bow, what I am doing rn is checking if the bow is in their mainhand, i do a get inventory then item in mainhand then getitemmeta AFTER the arrow has landed, the problem is they can switch before the arrow lands which makes it not work, I wanna make it so it basically goes through their entire inventory till they find the bow, and if it does it works but if it doesnt it returns. thanks in advance
And whats the question? Did you get any errors in your code?
no, im just asking if anyone has a doc or like idea of how to do it
Honestly, 26.1 is completly unobfuscated just check both the server and client until you see how vanilla handles bow & crossbow enchantments and rewrite it for your situation @wraith spade
https://mcsrc.dev/ if you're too lazy to setup a local repo
Hey everyone,
I am facing a very strange issue on Purpur 1.21.11 (Java 21) regarding programmatic chest manipulation.
The Goal:
I am spawning a chest block via code (after a falling block animation lands). I then want to fill this chest with items inside a runTaskLater task.
The Problem:
The chest is placed correctly, but the inventory modifications do not persist.
addItem()returns an empty map (indicating success).setContents()executes without errors.chest.update(true, false)returns true.- BUT: Immediately checking
inv.getContents()shows the items are gone (Air/Null). - The client sees an empty chest (both Java and Bedrock via Geyser).
It feels like I am modifying a detached snapshot, even though I fetch the Chest state fresh inside the delayed task.
What I tried:
- Increased delay (tried 1 tick up to 20 ticks/1 second).
- Used
addItem(),setItem(), andsetContents(). - Called
chest.update(true, false)andb.getState().update(true, false). - Ensured chunk is loaded (
chunk.isLoaded()check).
Environment:
- Server: Purpur 1.21.11
- Java: OpenJDK 21
- Minimal plugins: Geyser, Floodgate, LuckPerms (no inventory protection plugins active).
Code Snippet:
// Inside runTaskLater (20 ticks delay)
Block b = loc.getBlock(); // Block is Material.CHEST
if (!(b.getState() instanceof Chest chest)) return;
Inventory inv = chest.getBlockInventory();
// DEBUG: Items exist
plugin.getLogger().info("Items to add: " + items.size()); // Output: 5
// Attempt
HashMap<Integer, ItemStack> failed = inv.addItem(items.toArray(new ItemStack[0]));
plugin.getLogger().info("Failed items: " + failed.size()); // Output: 0
// Update
boolean success = chest.update(true, false);
plugin.getLogger().info("Update success: " + success); // Output: true
// IMMEDIATE CHECK
int check = 0;
for (ItemStack i : inv.getContents()) {
if (i != null) check += i.getAmount();
}
plugin.getLogger().info("Items in inventory: " + check); // Output: 0 (!!!)
Debug Logs:
[INFO] Items to add: 5
[INFO] Failed items: 0
[INFO] Update success: true
[INFO] Items in inventory: 0
Has anyone experienced this on 1.21+? Is there a new mechanism for TileEntity updates that I am missing, or is this a potential server bug? Any help is appreciated!
try getState(false)
iirc the default even on paper is to get a snapshot of the state
i don't 100% remember how that works with inventories, but presumably the state snapshot would also have a snapshot of the inventory, which, being separate, would remain empty even after you put items in it
it's generally better to avoid the whole state::update nonsense altogether and just directly modify the live state rather than a snapshot
i'm 99% sure that getState(false) really only works for read-only ops, and it gets weird on write ops, vaguely remember you'd still need to call getState(true) and BlockState#update
Hey @thorn isle,
Thank you very much for the suggestion! I tried using getState(false) to access the live state directly, but unfortunately, the issue persists. The inventory still reports as empty immediately after adding items.
It seems like there might be a deeper issue with how the TileEntity is handled in this specific build.
I have opened a GitHub Issue with the full details and code examples.
I really appreciate your help!
Thanks @slender elbow ! I actually started with that approach. I used getState(true) (snapshot) and called update(), but it had the exact same result: addItem succeeds, but checking getContents() immediately shows 0 items. It seems both the snapshot and the live state are broken for inventory modification in this build.
add more emojis to your responses and use a more enthusiastic tone
Hey @slender elbow, I'm sorry, I'm from Germany and I'm trying my best to translate it so that it isn't completely misunderstood.
development aside, i encourage you to learn english
🦅🦅🦅
You are absolutely right! 😅🙌 Thank you for the honest advice!
It is definitely on my to-do list! 📚✍️ I know using a translator isn't a long-term solution, but I'm trying my best to improve every day! 💪🧠
Thanks for your patience with my messages! You guys are the best! 🚀✨
WHAT THE FUCK
You filthy walking bag of microchips
ich übersetze: du schmutzige gehende tasche von mikrochips
IIoiiieJl Haxyu uHblMu CjloBaMu
if you listen to the bow fire event you can do your check there and add pdc for the bow's identifier on the arrow, then check damage and whatnot on hit instead
that's how my pvp plugin manages projectiles
How do you get custom craft recepies show in crafting book?
The client has to be aware of them, so you'll have to discover them
(you can also pass a Collection of keys, so use that if you want to discover multiple)
can anyone help me find a working unstable map
this is the help development channel ;/
hi
from iran
yes that part of my dev for my server
I mean actual development
making plugins etc
use #help-server
this is supposed to be a cube, the coordinates of the edges are all correct for a cube, the offset is due to the scaling of the individual blockdisplay, with which math function do i translate all edges accordingly?
Hey there. I trying to add IRC to my server for the chat bridge and admin management, could you help me with what library to use?
I tried to use: <dependency> <groupId>org.pircbotx</groupId> <artifactId>pircbotx</artifactId> <version>2.3</version> </dependency>But it does not exist
how can i change entity drops?
Discover pircbotx in the org.pircbotx namespace. Explore metadata, contributors, the Maven POM file, and more.
Latest on maven is 2.1
hile executing task 10
java.lang.NoClassDefFoundError: org/pircbotx/Configuration$Builder
at com.mrnategeek.irc.Bot.startBot(Bot.java:11) ~[?:?]
at com.mrnategeek.irc.Main.lambda$0(Main.java:12) ~[?:?]
at org.bukkit.craftbukkit.v1_21_R1.scheduler.CraftTask.run(CraftTask.java:82) ~[spigot-1.21.
1-R0.1-SNAPSHOT.jar:4344-Spigot-a759b62-19bf846]
at org.bukkit.craftbukkit.v1_21_R1.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:54) ~[sp
igot-1.21.1-R0.1-SNAPSHOT.jar:4344-Spigot-a759b62-19bf846]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
~[?:?]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
~[?:?]
at java.base/java.lang.Thread.run(Thread.java:1575) [?:?]
Caused by: java.lang.ClassNotFoundException: org.pircbotx.Configuration$Builder```
are you shading
I tried and it does not work
what "doesnt work"
idk what to tell you, Configuration$Builder exists, you're just building wrong
Maybe I not doing it right because I add the proper shading code, it does not add what you call the libraries needed like in this case pircbotx. It just has my code "org.mrnategeek.irc"
Where do I post it?
preferably in this server?
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
where is the shading
you just said you add the proper shading code, I dont see the shading code
I added it some point but let me add it again and send it to you
There it is: https://pastebin.com/seeiY7e8
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
With the pom.xml like that, this is the error:
hile executing task 10
java.lang.NoClassDefFoundError: org/pircbotx/Configuration$Builder
at com.mrnategeek.irc.Bot.startBot(Bot.java:11) ~[?:?]
at com.mrnategeek.irc.Main.lambda$0(Main.java:12) ~[?:?]
at org.bukkit.craftbukkit.v1_21_R1.scheduler.CraftTask.run(CraftTask.java:82) ~[spigot-1.21.
1-R0.1-SNAPSHOT.jar:4344-Spigot-a759b62-19bf846]
at org.bukkit.craftbukkit.v1_21_R1.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:54) ~[sp
igot-1.21.1-R0.1-SNAPSHOT.jar:4344-Spigot-a759b62-19bf846]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
~[?:?]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
~[?:?]
at java.base/java.lang.Thread.run(Thread.java:1575) [?:?]
Caused by: java.lang.ClassNotFoundException: org.pircbotx.Configuration$Builder
at org.bukkit.plugin.java.PluginClassLoader.loadClass0(PluginClassLoader.java:160) ~[spigot-
api-1.21.1-R0.1-SNAPSHOT.jar:?]
at org.bukkit.plugin.java.PluginClassLoader.loadClass(PluginClassLoader.java:112) ~[spigot-a
pi-1.21.1-R0.1-SNAPSHOT.jar:?]
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:528) ~[?:?]
... 7 more```
Not now
LOL OMG THIS GUY
How are you building your plugin?
mvn clean install? mvn package?
ur not even using the right dependency here
<groupId>com.github.pircbotx</groupId>
<artifactId>pircbotx</artifactId>
<version>2.2</version>
Which one should I use. Remember the Ellipse Platform? That is what I using. No mvn
Also im confused homeboy
you sent this code, the artifact here is:
<artifactId>MG-Staging</artifactId>
that isnt the same as the error you gave me
are you sending the wrong code or something
i think he's saying he's building it through eclipse or something, without maven
if he's building it through eclipse why does he have a pom file
maybe he's running maven through eclipse, god knows
oh right yeah
No, I did not look at the pom.xml file. I copied it from my MG-Staging project. That is why its there
riiight
Eclipse in the big 26? you arent my 60 year old Systems Programming teacher right?
is that you Phil?
i blame uh