#help-development
1 messages ยท Page 335 of 1
how to i turn on piston duping? in my server
so do you also have like all those other things in there?
please go to #help-server
yeah but like what does "this type of inventory" mean
No, I think those are something from another tutorial
okay so what made you assume ItemManager.init() wasnt?
He was just typing inside of it, so I assumed i needed to add it
oh well I guess so
did you also add the give command?
there he also uses the ItemManager
Maybe the client handles these differently: https://wiki.vg/Inventory
I'd actually have to give it a shot myself
oh whats this secret minecraft wiki
No, I have a recipe for the item instead of a give command, but I could try adding the command
It's actually a trusty companion of every protocol tinkerer, xD
its more like if you watched the whole video you would've seen that he added the pickaxe item to the ItemManager
bookmarked
even though I dont do packets , seems like usefull information to know the background a lil more of some of this stuff
I only skipped the part with adding the command but ig I'll rewatch it
wel I can spoil it for you right now, all he does it creating like an itemstack that represents the pickaxe
you can get away with just omitting ItemManager im pretty sure
Okay thx
since you just care about the rest of the code anyways
What could cause this error?
Maybe like how certain inventories can only take a stack size of 1
oh like enchant table slots?
i guess that makes sense
you would think that wouldnt apply to just the 9x6 inv though
What are you doing with packets
which is what im tryna use
Yh
me nothing, this is a player
I am but I fear it might be a server side issue due to the type of error
Are they using mods?
Nah
Wait
Is it reproducible?
It should be
Someone didn't reset the readerIndex
@livid dove
reset the readerindex?
I don't know if its related to that thing, but its giving an error saying that this line needs to be a listener:
Is ot reproducible?
And does it happen with no plugins
It's likely a plugin reading packets prior to them being decoded to packet objects
However, they don't reset the readerindex
That kinda sounds like somebody provoked a buffer pointer overrun, like tried to deserialize yet another value after the end of the packet had been reached.
So mc tries to decode the packet from the end of the data
Or that
The point is, someone os readong packets
And they shouldn't
Which again could be due to unresolved version differences between client and server.
Well, the server is constantly doing so, lol. I guess it also doesn't catch everything in the pipe and will throw if there's an error, as these errors should be detectable in production rather than be silenced to any spammy log files.
well yeah, it needs to implement Listener
Ik the server constantly does so
But it does so under the assumption that nothing will intercept the packets
Sure, but that's just not how the world works with modding. I don't even wanna know how many interceptors got their hands in the packet stream, xD. Could also be some viaversion issue, or a malformed packet, or whatever... Maybe a cosmic ray hit multiple ram cells of the router transmitting the packet and the CRC didn't catch that (LOL).
What does this mean in terms of my kicked player
Is it reproducible
You still haven't answered that
No other player?
Plugin that modifies chunk packets
no not at all as far as i know
When there's an error, the connection is terminated
So player is kicked
How can I tell what plugin a command is handled by?
If you can reproduce on another player, try without plugins
Get command map, get command check of its instanceof PluginCommand, and use PluginCommand#getPlugin
okay got there not kicking me
not weird
when you don't specify a repo maven will look in two places
first maven central
then your local maven repo
is your server in online mode?
its er.... online lol
i mean is it cracked?
This should look up the command in the central command map and respond with a non-null return value if the command exists, from which you can then retrieve the owning plugin reference.
for some reason i cant get this cmd to work
wait
why cant i send images i verified
try now
imma restart discord wait
just add the repo
Thank you, I had that idea but the wrong type of command ๐คฆโโ๏ธ I have it as PluginCommand and it works now, also big thanks to you minion325 as well for helping me ๐ appreciate you both
yea ig
uhhh
<repositories>
...
<!-- CodeMC -->
<repository>
<id>codemc-repo</id>
<url>https://repo.codemc.io/repository/maven-public/</url>
<layout>default</layout>
</repository>
...
</repositories>
oh
First local, then central, then remote.
that's jda?
its interprocess between spigot and jda
this is spigot lol
the bot is run off of a spigot plugin
LEVEL_1(1, "MinerZombie", "Troll"),
LEVEL_2(2, "Samurai", "Troll"),
LEVEL_3(3, "ToxicZombie", "Troll"),
LEVEL_4(4, "FrozenInhabitant", "Troll");
Currently I can get the String values from this enum using:
for (MobName mobName : MobName.values()) {
if (mobName.level == level) {
return mobName; <------------------- how can I return a random value between all Strings in each line
Example:
LEVEL_1 either returns "MinerZombie" or "Troll"
yeah but i wont go to jda discord for spigot help because the bot runs on a spigot plugin
I can't help u sry
well the part thats not working is the spigot part
Happy to help! :) I never needed this and was about to over-engineer a solution, until I remembered that the bukkit server had to have a way to access the central command map, xD.
not the jda
i do not understand
wdym?
the command works, reply works just not the stuff in minecraft
you want a random level?
No, I want a random value from each level
I think enum is becomming short for this
show your constructor
But I still wanna try
MobName(int level, String name, String name2) {
this.level = level;
this.name = name;
this.name2 = name2;
}
Oh... good point
OR String name, String... otherNames
I'd also use a String[] and then just return a random entry in bounds of [0;len-1]
and combine both into 1 array
MobName(int level, String... name) {
this.level = level;
this.name = name;
}
Fixed
That part
String[] name = new String[]{""};
huh?
wtf is this?
Why assign a value to it if you already assign it in the constructor? Make it final and initialize it only once.
True, alright removed that
And added final
Now you think I just return name[Math.randomblabla]?
yes
Thats kinda dope
Thread local random! ;)
to guarantee that you have atleast one name
nextInt(names.length), basically
MobName(int level, String name, String... otherNames)
Well the values are actually hardcoded
ThreadLocalRandom.current().nextInt(names.length + 1);
User can never add any
ThreadLocalRandom.current().nextInt(names.length);
Just don't instantiate a new random for each generation, that would be insanity. This is a pretty good solution which keeps you from managing your own Random instance.
Oh sure I'll do the change anyways
if the random int == names.length, return the primary name
else return the array index
Gotcha
You'd then need to accumulate those into a new array, I'd much rather use a names length check and throw an illegal state exception if it's zero. That way, the plugin cannot even enable and the developer is notified right away
no
cuz of this
then this
That seems dirty, not gonna lie, xD
public static String getMobName(int level) {
for (MobName mobName : MobName.values()) {
if (mobName.level == level) {
return mobName.name[ThreadLocalRandom.current().nextInt(mobName.name.length)];
}
}
return null;
}
lol
Technically that works without the default values
I just prefer the straight up simplicity of this
That's pretty cool thought wouldn't have thought of it
OR
Hey update my player said it was one of their mods
Im curious tho
Should i be concerned considering the kick error
Would then enum EVER be null?
Like why
I'd call it names, plural, as it's an array.
not but the compiler can't be sure
I see
Huh? I kinda missed the context of this question :-:
I was wondering you you even need the .length == 0
well in this example the length refers to the amount of names the developer has typed in the enum declaration
so yeah, it can be 0
since String... is 0 or more
Fair
Yes you do, because the variadic argument String... names can be left completely empty and still be valid. To not run into any runtime surprises, I'd catch that at the moment the class is loaded, which is when enum constants are initialized (something like that, geol don't beat me up).
You know when you load your plugin, instead of after you shipped it. Big difference.
public class Level {
public static final Level ONE = new Level("One", "1", "First");
private String[] names;
public Level(String name, String... otherNames) {
List<String> namesList = Arrays.asList(otherNames);
namesList.add(0, name);
this.names = namesList.toArray(new String[0]);
}
}
buckling up
can also use a class for that
What if for each level not only do I want random strings of mobs but I also want a % for each. And then the random actually gets called using that %
ah
lmao
weighted randomness
MY EYES
lmao i couldn't think of a better way to increase array size by 1 but have the previous items copied to the tail end
You probably want this stuff configurable as well
No I don't
So dw about that
I don't mind recompiling the plugin once a change. It's still in development
You generate a number between 0 and 1 and assign a name to a range within that number for each range, where all ranges need to add up to 100%.
not really
it doesnt have to add to 100
if you assign 1 to Steve and 1 to alex, it is a 50/50% chance
Bro can you guys like agree on something, plz
That's why I think throwing there is the most elegant solution possible
if you want percent, it must add to 100 but checking that it adds to 100 is hard
great
But I don't think enums gonna cut it anymore
It has, if it's done the way I wrote about it. Like have A take 20% and B 30% and C 50% would be
A [0;0.2] B [0.2;0.5] and C [0.5;1]. Maybe I also screwed this up, it has been a long time since I needed it and I haven't thought about it ever since.
WeightedRandomGenerator class
no
Just throw something together, it'll be random enough.
LMAO
I mean yeah
I just don't know where to really start
First i gotta switch out of enums
What are you doing?
What's up with you and not having trust in your enum, xDD. You just extend the name getter method and that's it. The enum is still completely fine.
you want to store mob names?
So I'm thinking each level needs a map
Well yeah
I want to store a mobname / weight
As many per level
And then getRandom() uses the weight per random
right so each level needs a weightedrandomgenerator
the only change you'll have to make is you can no longer accept String...
Isn't this too much just to get a randomthing
What if I make a map and just if lmao
well sure
what works isnt what's best
If you feel like guiding me through the steps I'll give it a try
lemme just have a look
why ""?
MobName.getMobName(currentLevel).toString()
Cause I was editing stuff
They'll be full,
toString() uncesseary
ye
Before it was returning MobName
ok anyhow
yeah?
Gonna cause issues
getRandomName doing all the stuff about random and that
Alright
i'm thinking 1 sec
Yeah no issue I got time lol
You can have a class like this
public class Weighted<E> {
private final E object;
private final double weight;
public Weighted(E object, double weight) {
this.object = object;
this.weight = weight;
}
public double getWeight() {
return weight;
}
public E getObject() {
return object;
}
}
public class WeightedString extends Weighted<String> {
public WeightedString(String object, double weight) {
super(object, weight);
}
}
and this
so now, you can replace String with WeightedString
ooooooooooooooooooooooo
in your Enum Cnostructor
I see what you're doing
Holy sht
Ok yeah, so far so good
Am I still doing array of WeightedString?
According to what I see, I say no
Why not just only use this, instead of WeightedString
cuz <> is ugly lol
No lol
you can just use that tho
So then I am doing array of Weighted
u can do either but it'll be Weighted<String>[]
WeightedString or this
it's the same
WeightedString[]?
Cause unless I'm full lost WeightedString isn't actually a collection of any sort
What would you do then
final Weighted<String>[] names;
MobName(int level, Weighted<String>... names) {
this.level = level;
this.names = names;
}
yeah
now we need to load the weights into the WeightedRandomGenerator
private WeightedRandomGenerator<String> randomGenerator = new WeightedRandomGenerator<>();
Oh I actually need that entire class, alright
yes
Alright
Does anyone have a good way or util to shrink/expand world borders smoothly?
private final int level;
private WeightedRandomGenerator<String> randomGenerator = new WeightedRandomGenerator<>();
@SafeVarargs
MobName(int level, Weighted<String>... names) {
this.level = level;
for (Weighted<String> name : names) {
randomGenerator.addItem(name.getObject(), name.getWeight());
}
}
public String getRandomName() {
return randomGenerator.generateRandom();
}
public static String getMobName(int level) {
for (MobName mobName : MobName.values()) {
if (mobName.level == level) {
mobName.getRandomName();
}
}
return null;
}
Ok great
Does anyone have a good way or util to shrink/expand world borders smoothly?
You can already do this in vanilla. No need for a util
WorldBorder#setSize(size, seconds)
And then in each level how should I be adding it exactly
LEVEL_1(1, new Weighted<>("MinerZombie",3)),
Support 1.8.8?
yes
If world borders exist in 1.8 then yes
like that
Thta's sick
but you should really update. 1.8 is like 8 years old
Now the weights I assume is with the total of each level
Alright, thank you
If both are 50/50 then it'll be 50%
weights are like fractions ye
add all the wights that's the denominator
and the individual weight / total weights is the probability
Thanks a lot for the lesson
Now I'm a bit worried about running all this in a tasktimer so I'm just gonna add some period to it and should be safe
https://imgur.com/a/fXVbu9a i found the error. it logs the player fine, so the problem isnt the player, and i check for the exception
"asynchronous entity add"
running what?
add the entity sync
entity sync?
if you're async(another thread) you need to schdule the entity to be added on the main thread
?scheduling
new BukkitRunnable() {
@Override
public void run() {
mythicMob = MythicBukkit.inst().getMobManager().getMythicMob(MobName.getMobName(currentLevel)).orElse(null); <------ enum
Location location = locations.getRandomLocation();
mythicMob.spawn(BukkitAdapter.adapt(location), 1);
}.runTaskTimer(plugin, 1, 10);
}
oh
I wonder if it's an issue doing so many calls so quickly
Hey I Need a Developer for Mods and Plugins pls let me know DM
?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/
just try it and if the TPS stay at 20, it's no problem lol
if it works, don't worry about it
Two entities per second is not an issue, but that'll be a lot of entities, xD
I have a limit
60 at any given time
Oh, okay, that wasn't obvious from the excerpt alone.
Yeah for sure lol I did actually infinitely spawn entities once
Then I fixed the limit hehehe
I was confused when my frames went to 20
@tender shard The cirrus dev still hasn't answered my messages in his cord about his stuff not working
that's sad lol
maybe use another lib then
Yeah unlucky I really wanted that intelliJ plugin
@tender shard When is jefflib getting a intelliJ plugin O.o
for what lol
I tried to write an intelliJ plugin, but it was so complicated that I nearly died and then I never touched it again
lmaoooo
What language is that on
kotlin iirc
I also wanted to write a string syntax highlighter for my expression parser and didn't even attempt to do it, because it looked that complicated and badly documented, xD
yeah exactly lol
Screw IntelliJ, maybe gonna write a vim plugin instead some day, haha
rather for the lsp, I guess
@dry yacht Have you seen the resource we're talking about?
Haven't followed the chat closely, why?
Cause the dev has a shitton in his repos and it's not even usable
But the plugin looks cool
Nah prob but the intelliJ plugin is what made it look interesting
Show. I'm still deciding wtf to do regtarding guis
Oh, wait, gonna go to the laptop real quick to check the repo out
show bob
I actually have something laying around, xD
I
I'll be waiting
btw his github repo doesn't seem to have his final version. that is here
Nexus Repository Manager
Even alex tried helping me try to build it. impossible
Not trying to be mean, but that's the single most useless thing I've ever seen, haha
It's kinda hard to show you, because I don't know where to start telling you about it, xD.
wtf really? lol
I mean I assume he his framework converts that config file into a gui to edit in code
I understand, I'm just trying to find either a decent enough framework or an implementation
I don't think I'm at the level yet wher emy implementation is better than mostframeworks tho. No amtter how bad those cna be
That is the definition of a Rube-Goldberg machine, lmao
most people use IF
(InventoryFramework)
i never used it, so no clue whether its good or not
My personal approach is to have a very slim GUI library which I wrote myself, which builds on top of my expression parser, where I can outsource all of the item description and appearance behaviour logic to the config, while the java code only focuses on the actual control logic. But I'm far from having a proper GUI lib at this time, as I do not at all work with GUIs at the moment.
I mean what you have is technically the definition of a lib just maybe you're missing elements
I could show you how it works in one of my projects with just two pastes, if you're interested. You could maybe take some inspiration off of that.
It's definitely a lib, just not production-ready, is what I'm saying.
Yes, expression parser! :)
Man everyone here uses their own thing
what kinda expressions though
Guess why, because what's out there is not good enough
I don't think I have the knowledge to make my own lib just yet
well because there are a billion options of what to do/preferences/etc
I've only been coding java for like 2 weeks now
If you're actually interested in it, here you go.
Config: https://paste.md-5.net/iziluqayar.coffeescript
well I dont know how to make a "lib" I just write code based on what spigot lets me do with inventories using google xD
Well then I'd just take it easy and either build the GUI from first principles or just use another lib, no matter if it's good or not - just to get comfortable with the working principle of GUIs.
wtf are you opening pandora's box or something
just looking at your example
looks pretty nice
I mostly have some base gui , an a few things like some banner based keyboard menu, paginated item picker, stuff like that
but its all inside of 9x6's for now haha
One day
and submenuUI which I recently did, which is basically just a node in a gui tree
ill remember that
I'm just immensely disappointed by how most plugins are written so that I came up with a way I'm hoping to one day make the new standard, to elevate the average level of code quality. Big goals tho, gotta take it one step at a time.
You got no idea how picky I actually am, xD.
yeah same for me
You got no idea how committed I am to something when i set my mind onto it
I put 20 hours a day until I master it
also now that I have already started putting time in my guis,I see less reason to switch to anything else
because of how limited minecraft plugin guis can get, I feel like every sort of menu is a few lines of code away at this point
Guess how I made my libs come to life, ;)
Btw, don't know if that's obvious, but I'm also no longer interacting with a plain config. I'm automatically mapping these sections to objects, with automatic expression support.
I'm working my ass off whenever I'm not currently depressed, xD. You got no idea how much I actually tinker.
Like it might not sound very good to you guys and the code is definately not refined but in a week I made a chunk collector which works as an infinite chest better than all the options rn at elast on spigot forums. In 2 days I made and finished my first game
Like I said it's defo not refined code, it's honestly pretty bad, but that's from a week of doing stuff
Sounds like you're making great progress, happy to hear that! :)
yes thats cool
I am. Today someone tought me about like, idk what they're called exactly like MyClass<>
You gotta build a pice of shit before you can refine it, that's how it's always gonna be if you're trying to get into a new problem-domain, no matter how experienced you are.
So now need to use that more and more
Generics
If you compare my inf storage to my game it looks like it's built by someone else
It's still bad but not as bad lol
And as I cope my hate for cmi and songoda grow so
I don't even know what that is tbh, xD
"298+ Commands/Insane Kits/Portals/Essentials/Economy/MySQL & SqLite/Much More!" ๐คฎ
And the songoda team also make terrible massive massive plugins
Jack of all traits but master of none, huh, xD
I don't think a single dev likes CMI
Support is ass
Compatibility is ass
Performance is ass
If it was free I still wouldn't use it
I actually don't understand how people can work on such giant projects, that just has to be immensely cumbersome.
It's not bad if you do it right
Make it modular and then you shouldn't get overwhelmed too bad since you focus on sections at a time
can gradle init meanwhile properly handle maven plugins like maven-shade-plugin and also submodules? or do I have to rewrite this shit again D:
just checked, unfortunately no. it does create submodules but all the config options for maven-shade etc are lost D:
But if it would be truly modular, then why would you stuff it all into a final jar so the user has to take all or nothing again? Why not make a module system? Kinda feels like they don't build it that modular... Just closing packages or folders in the folder tree may help with minimizing overwhelming numbers of files, but it's still far from something I'd like to work on.
someone should ping this
pin*
angelchest is such a feature creep, not even the translations fit onto one screenshot D:
It especially sucks that these are all top level keys and you literally have no grouping to make any sense of this ratsnest other than searching for known keywords.
they are all top-level things because my config updater would otherwise die
I'm wondering right
at least I respond within a year lol
depends I guess
What's the job of that updater? Patch in new keys on updates?
yeah or handle the renaming of existing keys
I'd say "a few hundred hours"
How would that get more complicated for nested keys? Well, yeah, it's a bit more work, but I just think it's funny that it would actually die, xD
well how'd you do it?
Depends on how much they could steal and how much they had to write themselves
remember it has to keep comments and stuff
Probably diffs from each version, some sort of migration scheme. No idea tbh, haven't had to think about it. But if your logic works well, you should be able to extrapolate that to nested keys as well, I think. Maybe I'm overlooking something.
The new snakeyaml does a banger job on that, haha
yeah unfortunately it's only in 1.17+ IIRC D:
I still gotta support 1.16 for all these shitty hybrid forks
Is the way that viaversion works complicated?
Like I don't see any other similar ones
Via is nice, why don't you just use that?
Oh what for? lol
the general idea is not very complicated
but it's a lot of effort mapping all these different versions
e.g. saying "oh, a 1.8 user sees netherite, hm let's show them diamond ore instead"
That's why I'd just shade it in tbh, it's not worth dealing with the snakeyaml of older versions.
also true
Ummm sorry 1 question, What's the bar that shows above the hotbar with text? Can one customize it? What's it called
but then I'd be at 4MB and poeple would then give 1 star ratings "when I bought this plugin it was 1MB, now it's 4MB, I am upset ugh ugh ugh" lol
action bar
Thankss
somePlayer.spigot().sendMessage(ChatMessageType.ACTION_BAR, yourText);
Great!
it requires component though IIRC
...
e.g. TextComponent.of("My text")
or sth similar
There has to be a way to load those 4MB at startup and pass it to the classpath, just so that these people shut up
Or finally ditch yaml all together and use json
yeah 1.16.5 added that ofc but most of these shitty hybrid forks use an outdated bukkit version ๐ฅฒ
So Iโm working on a plugin and I want to make an armorstand that is constantly moving and posing, creating an animation. There is one armorstand per player. Iโm pretty new to spigot, and so I was wondering what is more efficient. Should I create a new runnable instance per player and animate each armorstand in that, or should I have one central runnable and iterate through all armorstands in a list?
if EVERY player has their own armorstand anyway, just use one "central" runnable
I actually think that more known devs need to do this. Yaml needs to die.
and then I'd use a Map<UUID,ArmorStand> or sth like that
YAML is nice
JSON is a bad joke
...
json was never made to be human cofigurable
forget one comma? whole file "dies"
json = nice for internal storage. YAML = nice for human editable things
that's at least my opinion
I don't even know what to say rn, :-:
two options: you could say "I agree", or you could start to explain about which things you disagree ๐
Thanks
I can only speak for myself, but if docker-compose would use .json files instead of .yml, then I'd sure as hell be quite annoyed
however tbh it doesnt really matter unless you got like 1000 players
still, no reason to have 1000 runnables if you could just use one
Like, I respect your opinion, but I don't know if you're actually aware of how bad yaml is. If you actually forget such a stupid comma, you at least get the exact parser cursor location of where an unexpected token occurred, while yaml can fuck your whole config over and maybe even pass parsing. Look at the yaml parser. It's an immensely complicated state machine which is only so complicated because the spec has been written by maniacs with feature-creep syndrome and because the language is indentation-based. I can write a proper json parser in like a few Ks. Yaml brings nothing to the table and makes debugging way way worse. Json is so easy that I can explain it to a five year old, while Yaml has so many stupid possible ways to mess it up...
hm okay I havent checked SnakeYAML's source or anything, but imho at least yamllint does a good job in printing the location of the "error"
a few seconds
Remember that problem somebody had with the unexpected anchor interpretation on color-codes lately? Just one of the thousand ways to mess yaml up.
sorry can't say anything about that, I haven't seen that message
oh I get what you mean
they probably did message: &cRED TEXT
instead of using quotes
What if I had thousands of armor stands creating animations. If these armor stands worked together to create multiple custom creatures and animations, I take it iterating through each armorstand in a single runnable or task is still more efficient, than one runnable instance per creature correct?
one could say that in json, this wouldnt exactly be easier, since you need quotes there too though
I would just think about it like this:
- Do I need to loop over ALL my custom armor stands every tick?
-> If yes, one runnable - Do I need to loop over ALL my custom armor stands that I madfe for this one entity, but not care about how long ago it was that I spawned them?
-> If yes, one runnable - Otherwise, one runnable per player
It was about an extra quote in the line above which then turned the whole next key into a string and the first ' of that line terminated the string, so the first & after that was an anchor.
the server doesnt really care about having to run 1000 runnables every tick, however it'd still be a nice idea not to spam the scheduler with a shit ton of new runnables
Probably doesn't matter anyways, as most people think about yaml the way you do and would never migrate to json. We're stuck with yaml.
I don't really see why that's any reason to hate YAML. People are ofc excpected to check how YAML works before simply using special chars in their configs
Alright, well thanks
JSON doesnt even support anchors
just do not add random " or ' or & chars into your configs without escaping them, and you're fine
Because you gain a bit of readability for the disadvantage of a far more complex parsing algorithm as well as far less bullet-proof grammar. It's not at all worth the tradeoff, judged from an objective standpoint.
I think you just don't care about that because it "just works" for you. You never had these horrible parser failures, and you never tried to write a yaml parser. It's not even closely comparable to a json parser, and again - it doesn't bring enough to the table to justify that.
I mean tbh pls be honest, which is easier to read and edit for humans?
{
"name": "mfnalex",
"age": 27,
"friends": [
{
"uuid": 1234
},
{
"uuid": 3456
}
],
"address": {
"street": "Junkerstraรe 17",
"city": "Mรผnster",
"zip": 48165,
"country": "DE"
}
}
or
name: mfnalex
age: 27
friends:
- uuid: 1234
- uuid: 3456
address:
street: Junkerstraรe 17
city: Mรผnster
zip: 48165
country: DE
I think YAML is way easier to edit
yeah but who cares about how hard it is to parse it, if you don't have to do it yourself
Nobody argues that it's easier to read and edit, that's not my point
I know exactly that if plugins would use json instead of yaml, I'd get like 100 support tickets per day
that I could avoid by making people using YAML instead
Well, that's why you cannot afford to shade the latest snakeyaml, because it's so much more complex because of those tiny improvements that it completely blows the jar footprint out of proportion.
I call that being disconnected from what actually happens behind the curtains, it's just not good that devs drift towards that attitude with lightspeed.
Because that's just what was there and socially accepted first. That's it.
50% of my support tickets are like "ugh why does the disabled-world options not work" and then they send a config that looks like this:
disabled-worlds:
- world1
- world2
disabled-worlds:
if people don't even understand why this doesn't work, then I highly doubt that they would be smart enough to edit json files without breaking everything
We're just coming at this from two completely different angles. You're about use and how it's going to be accepted on the market while I'm about the implementation details and about how obscure it's specification actually is.
I guess that's fine tho, but when users are just too stupid to learn json, then they shouldn't be cocky about you shading the latest snakeyaml into your plugins to make it even easier for them (because size was the initial concern, iirc).
yeah but I dont understand why I should care about the implementation, when snakeyaml already does it in a way that works well for everyone
I guess that's fine tho, but when users are just too stupid to learn json, then they shouldn't be cocky about you shading the latest snakeyaml into your plugins to make it even easier for them (because size was the initial concern, iirc).
I 100% do support this statement though
As I've said, you just don't care about technology in a way that I do, and I respect that! :). People have different motivations to be in this field, that's just how diversity works.
yeah I just wanna sell my stuff and stop having to answer tickets because people do not understand how to edit the config files
as long as SnakeYAML works, I dont see any reason not to use it
I get that. And I just want the world of computing to become a better place where we don't write immensely complex parsers to compensate for the ignorance and straight up disinterest of bukkit server owners against technology. JSON is more than easy enough to read and understand. It has a few more control characters, but it's not like I make them write assembly, populate system registers and perform syscalls. It's json, my lord.
can someone help me shade my own classes into a jar file (also edit one of the .class files to actually run the shaded in classes)
Are you talking about shading another project of yours into your current project? You'd just have to install it into your local maven repository and include it into your dependency list as always, while making sure the maven-shade-plugin is set-up properly.
hi
okay relatable. I still think that YAML is a nice thing to have as it eliminates the "it's the human who broke this config" factor
hello
try {
ResultSet resultSet = chunksTable.getChunk(chunkCoordX, chunkCoordZ);
if (resultSet.next()) {
this.owner_uuid = resultSet.getString("owner_uuid");
}
else {
this.owner_uuid = null;
}
} catch (Exception e) {
ChunkClaimsPlugin.logWarn(e.getMessage());
}```
are you using maven?
so, i am storing chunk data in a sqlite database
what kinda chunk data?
then whenever a chunk gets loaded the ChunkLoadEvent gets fired, i load the chunkdata from my sqlite database into server memory
No, I have a plugin .jar file. It's obfuscated and I want to add my own features to it. I can easily add my own classes by just unzipping the jar, adding them, and rezipping it, but I need to call them. To do that, I have to edit the main file, and all attempts at editing the bytecode don't work. I even created a clone of the decompiled version of it, and then added stubs until I was able to get it to compile, but that threw errors in console and didn't actually make the function run
Yeah
but it seems incosistent
so owner uuid is null
That's not what I'm trying to do
even though i see the owner uuid in database
I'm trying to edit the jar file
huh
So I guess "shading" isn't the best terminology
I want to edit the main class of a jar file
Damn, that sounds like a hell of a hack you're trying to perform there, xD
Yeah
Ik
I've tried this for days on end
nothing seems to work
I was able to get my injected code to work, but the downside is the actual plugin itself didn't load properly
wtf
Imagine still using SQL ๐
i am using sqlite
verano you on crack cocaine again?
i just need the single file convinience
Json >>> SQL
otherwise i would use a nosql database like mongodb but that aside
he is on crack again
Json?
๐ wtf
do you even know what json is?
verano you should go to sleep
Could you give me an example of what you're actually trying to achieve? Is it just to add function calls to methods or do you actually want to patch out methods? Wouldn't it be easier to just change the main entry point of the obfuscated plugin's yaml file and then bootstrap the obfuscated code yourself rather than having to do it the other way around? You could just inherit and override some methods then, I guess.
your name's Alex
Oh, I thought you're the yamler
ok i have an actual problem that i am trying to solve please dont make awful jokes.
welcome to spigotmc discord
this problem is causing me a headache
Okay. I pretty much want to add my own functionality to the jar file.
So, I created my own class that does this for me.
However, I need to call the load function in my custom class in the actual plugin's onEnable method.
this.executeStatement("CREATE TABLE IF NOT EXISTS Chunkclaims (" +
"owner_uuid text NOT NULL," +
"coordX int NOT NULL," +
"coordZ int NOT NULL," +
"FOREIGN KEY (owner_uuid) REFERENCES Players(uuid)" +
");" +
"");```
this is the sqlite database table.
makes me want to kms
every time
what data do you need to store? @quaint mantle
because you could usually just use the chunk's PDC
i am storing chunk claims
usually there is no reason to use an external DB
i know i can use the spigot persistent data api
but i wanna be able to use this elsewhere as well
yeah okay
so i am storing this in a separate file
Then just inherit the obfuscated main class, override it's onEnable (as they cannot obfuscate that), call super.onEnable and then launch your own stuff. Don't forget to change the FQN of the entrypoint (main class) in the plugin.yml. I guess that's it?
how am I supposed to inherit a class that isn't abstract or an interface?
a player claims a chunk and if a chunk is claimed, it cannot be claimed again
extends <classname>? xD
or implements depend what you have
this.executeStatement("CREATE TABLE IF NOT EXISTS Chunkclaims (" +
"owner_uuid text NOT NULL," +
"coordX int NOT NULL," +
"coordZ int NOT NULL," +
"FOREIGN KEY (owner_uuid) REFERENCES Players(uuid)" +
");" +
"");```
oh I forgot you can do that
class. bonk.
getChunk = db.createPreparedStatement("SELECT * FROM Chunkclaims WHERE (coordX=? AND coordZ=?);");```
"executeStatement" i dont find that on SQLite docs, what version are u using?
You can DM me if you'd like. I'm all in on hacky patches, lol
public ResultSet getChunk (int chunkCoordX, int chunkCoordZ) throws SQLException {
getChunk.setInt(1, chunkCoordX);
getChunk.setInt(2, chunkCoordZ);
return getChunk.executeQuery();
}```
try {
ResultSet resultSet = chunksTable.getChunk(chunkCoordX, chunkCoordZ);
if (resultSet.next()) {
this.owner_uuid = resultSet.getString("owner_uuid");
}
else {
this.owner_uuid = null;
}
} catch (Exception e) {
ChunkClaimsPlugin.logWarn(e.getMessage());
}
if (this.owner_uuid != null) {
this.chunkOwner = Bukkit.getPlayer(UUID.fromString(this.owner_uuid));
}```
i am using jdbc to do this.
and here is how i get the result set
private String owner_uuid = "loading";
owner_uuid is "loading"
once it loads
okay, so you are asigining each player a chunk?
it is null if the database row was not found
yep
but it has been inconsistent
i keep going to a chunk
and i have been able to claim it several times
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) {
return false;
}
Player player = (Player) sender;
Bukkit.getScheduler().runTaskAsynchronously(ChunkClaimsPlugin.getThisPlugin(), () -> {
try {
ChunkData.claimChunk(player, player.getLocation().getChunk());
player.sendMessage("You have now claimed this chunk.");
} catch (Exception e) {
player.sendMessage(e.getMessage());
}
});
return true;
}```
Are you doing a claim system?
So what your issue?
i do /claim on a chunk that is already claimed
You are not finding the player?
has a row in the database table
but i keep being able to do /claim and claim it over and over
right, please i want to see your user and your claims table strucutre
here is what the database structure looks like
and that is the chunk claims database table.
Oh the uri is not allowed in my country
So youri ssue is that your players can claim many chunks?
no, the same chunk over and over
oh ok
Tbh i also never am able to see imgur content in germany
Yall want the images?
Cant hurt
Pasted in order.
Thx
Well the db obv contains your data, the issue must be how youre reading it
Looks like a typical problem where you forgot to do next() on the resultset
there should only be one row
with a certain combination of chunkCoordX and chunkCoordZ
You still gotta call next() to get the first result
private static HashMap<Chunk, ChunkData> chunkDataStore = new HashMap<Chunk, ChunkData>();
public ChunkData (Chunk chunk) {
this.initialisations(chunk);
}
private void initialisations (Chunk chunk) {
chunkDataStore.put(chunk, this);
try {
if (!initialised) {
chunksTable = new ChunksTable();
initialised = true;
}
} catch (Exception e) {
ChunkClaimsPlugin.logWarn(e.getMessage());
}
this.chunk = chunk;
int chunkCoordX = chunk.getX();
int chunkCoordZ = chunk.getZ();
try {
ResultSet resultSet = chunksTable.getChunk(chunkCoordX, chunkCoordZ);
if (resultSet.next()) {
this.owner_uuid = resultSet.getString("owner_uuid");
}
else {
this.owner_uuid = null;
}
} catch (Exception e) {
ChunkClaimsPlugin.logWarn(e.getMessage());
}
if (this.owner_uuid != null) {
this.chunkOwner = Bukkit.getPlayer(UUID.fromString(this.owner_uuid));
}
}```
This sounds like something composite keys might fix.
public class ChunkLoadEventHandler implements Listener {
@EventHandler
public void onChunkLoadEvent (ChunkLoadEvent event) {
Chunk chunk = event.getChunk();
Bukkit.getScheduler().runTaskAsynchronously(ChunkClaimsPlugin.getThisPlugin(), () -> {
new ChunkData(chunk);
});
}
}
public static void claimChunk (Player player, Chunk chunk) throws Exception {
ChunkData chunkData = chunkDataStore.get(chunk);
if (chunkData.owner_uuid != null && chunkData.owner_uuid.equals("loading")) {
throw new Exception("Chunk is still loading.");
}
if (chunkData.owner_uuid != null) {
throw new Exception("This chunk is already claimed by " + chunkData.chunkOwner.getName() + ".");
}
chunkData.chunkOwner = player;
chunkData.owner_uuid = player.getUniqueId().toString();
chunksTable.addChunk(chunkData.owner_uuid, chunk.getX(), chunk.getZ());
}```
ResultSets start at eermโฆ like -1. next() is always required
i think the problem is resultset.next().
do i have to call resultset.next() to get the first result? if that is it, then i am doing that here.
but it still sets owner_uuid to null
which means
resultset.next() is not returning anything
There is also ResultSet#first()
Havent seen that part, sorry, im only on the phone. If you do call next() and its still null, then the issue is sth else
oh
Wtf
i mean it is returning false
Then your query is wrong
then it is the query
but what is wrong with this query
i dont see it
getChunk = db.createPreparedStatement("SELECT * FROM Chunkclaims WHERE (coordX=? AND coordZ=?);");```
Print our your SELECT
this.executeStatement("CREATE TABLE IF NOT EXISTS Chunkclaims (" +
"owner_uuid text NOT NULL," +
"coordX int NOT NULL," +
"coordZ int NOT NULL," +
"FOREIGN KEY (owner_uuid) REFERENCES Players(uuid)" +
");" +
"");```
Probably coordX or Z isnt correct
Otherwise itโd work. So yeah i guess your query is just wrong
Print it out
print what out?
The query statement
Print out the result of the query.
ok
Probably you check for โwhere x=0.000โwhile db says x is 0 instead of 0.000 or sth
i am using ints
not sure where decimal digits come from.
As said, im only on the phone, im in the bathtub rn. All i can do is to suggest what iโd do, thereโs no guarantee that any of this will help lol
try {
ResultSet resultSet = chunksTable.getChunk(chunkCoordX, chunkCoordZ);
if (resultSet.next()) {
this.owner_uuid = resultSet.getString("owner_uuid");
System.out.println(resultSet);
}
else {
this.owner_uuid = null;
}
} catch (Exception e) {
ChunkClaimsPlugin.logWarn(e.getMessage());
}```
Just do sth like โSystem.out.println(myQuery)โ where myQuery is sth like โSELECT * FROM โฆโ
Then check what it says
do you want me to print the PreparedStatement or ResultSet?
ok i am tired for now
[11:00:02 INFO]: PulseSapphire joined the game
[11:00:02 INFO]: PulseSapphire[/127.0.0.1:56747] logged in with entity id 91 at ([world]4987.539328703592, 80.0, 5040.021875761163)
[11:00:02 INFO]: org.sqlite.jdbc4.JDBC4ResultSet@7338d078
[11:00:02 WARN]: [Chunkclaimsplugin] ResultSet closed
[11:00:02 INFO]: org.sqlite.jdbc4.JDBC4ResultSet@7338d078
[11:00:02 WARN]: [Chunkclaimsplugin] ResultSet already requested
[11:00:02 WARN]: [Chunkclaimsplugin] [SQLITE_MISUSE] Library used incorrectly (bad parameter or other API misuse)
[11:00:02 WARN]: [Chunkclaimsplugin] ResultSet already requested
[11:00:02 WARN]: [Chunkclaimsplugin] ResultSet already requested
[11:00:02 WARN]: [Chunkclaimsplugin] ResultSet already requested
[11:00:02 WARN]: [Chunkclaimsplugin] ResultSet already requested
[11:00:02 INFO]: org.sqlite.jdbc4.JDBC4ResultSet@7338d078
[11:00:02 WARN]: [Chunkclaimsplugin] Plugin Chunkclaimsplugin v1.0-SNAPSHOT generated an exception while executing task 1615```
now it starts printing this error.
Oh please do getAsSting() or however its called on the prepared statement before printing it
My bad
I want to see the exact query
The string thats like โSELECT * from whatever etc etcโ
getChunk = db.createPreparedStatement("SELECT * FROM Chunkclaims WHERE (coordX=? AND coordZ=?);");```
Nooo
this is the exact query.
He wants to see the query with the values filled in.
Print out what the โfilled outโ statement is
oh
Exactly
how do i get that?
Tbh not sure, just google โjava print out prepared statementโ
As said im in the bathtub and using the phone is a pain lol
You should just be able to print out the query. System.out.println(query);
I think they did that earlier
no i printed the resultset
^
Oooh ok
System.out.println(getChunk.toString());
i am printing the preparedstatement here
public ResultSet getChunk (int chunkCoordX, int chunkCoordZ) throws SQLException {
getChunk.setInt(1, chunkCoordX);
getChunk.setInt(2, chunkCoordZ);
System.out.println(getChunk.toString());
return getChunk.executeQuery();
}```
Yeah do that. Then afterwards, do a manual query on your sql server and youโll probably see that it indeed doesnt return anything
parameters=[11, 3]
[11:08:58 INFO]: [Chunkclaimsplugin] [STDOUT] SELECT * FROM Chunkclaims WHERE (coordX=? AND coordZ=?);
parameters=[-11, 2]
[11:08:58 INFO]: [Chunkclaimsplugin] [STDOUT] SELECT * FROM Chunkclaims WHERE (coordX=? AND coordZ=?);
parameters=[11, 4]
[11:08:58 INFO]: [Chunkclaimsplugin] [STDOUT] SELECT * FROM Chunkclaims WHERE (coordX=? AND coordZ=?);
parameters=[11, 4]
[11:08:58 INFO]: [Chunkclaimsplugin] [STDOUT] SELECT * FROM Chunkclaims WHERE (coordX=? AND coordZ=?);
parameters=[-11, 4]
[11:08:58 INFO]: [Chunkclaimsplugin] [STDOUT] SELECT * FROM Chunkclaims WHERE (coordX=? AND coordZ=?);
parameters=[-11, 7]
[11:08:58 INFO]: [Chunkclaimsplugin] [STDOUT] SELECT * FROM Chunkclaims WHERE (coordX=? AND coordZ=?);
parameters=[11, 7]
[11:08:58 INFO]: [Chunkclaimsplugin] [STDOUT] SELECT * FROM Chunkclaims WHERE (coordX=? AND coordZ=?);
parameters=[-11, 8]
[11:08:58 INFO]: [Chunkclaimsplugin] [STDOUT] SELECT * FROM Chunkclaims WHERE (coordX=? AND coordZ=?);
parameters=[11, 8]```
this is probably the plugin loading the spawn chunks.
after server start
Do a manual โSELECT * from Chunkclaims where coordX = -11 and coordZ=4โ
WTF
Does that return anything?
parameters=[320, 339]
[11:10:52 INFO]: [Chunkclaimsplugin] [STDOUT] SELECT * FROM Chunkclaims WHERE (coordX=? AND coordZ=?);
parameters=[320, 339]
[11:10:52 INFO]: [Chunkclaimsplugin] [STDOUT] SELECT * FROM Chunkclaims WHERE (coordX=? AND coordZ=?);
parameters=[321, 339]
[11:10:52 INFO]: [Chunkclaimsplugin] [STDOUT] SELECT * FROM Chunkclaims WHERE (coordX=? AND coordZ=?);
parameters=[304, 339]
[11:10:52 INFO]: [Chunkclaimsplugin] [STDOUT] SELECT * FROM Chunkclaims WHERE (coordX=? AND coordZ=?);
parameters=[299, 339]
[11:10:52 INFO]: [Chunkclaimsplugin] [STDOUT] SELECT * FROM Chunkclaims WHERE (coordX=? AND coordZ=?);
parameters=[304, 339]
[11:10:52 INFO]: [Chunkclaimsplugin] [STDOUT] SELECT * FROM Chunkclaims WHERE (coordX=? AND coordZ=?);
parameters=[304, 339]
[11:10:52 INFO]: [Chunkclaimsplugin] [STDOUT] SELECT * FROM Chunkclaims WHERE (coordX=? AND coordZ=?);```
i am around (0, 0)
and i was flying around
my chunk coords in f3 are (0, 0) to (20, 20)
why is this as high as 300
WTF
WHAT THE HECK
THIS HAS BEEN THE ISSUE THIS ENTIRE TIME
java.lang.NullPointerException: Cannot invoke "Object.hashCode()" because "key" is null
?paste
?stacktrace
We cannot help without the full stacktrace; Please paste it here: https://paste.md-5.net
He knew
Of course lol
Here help me out with this bro :git-Paper-
How to fix bro!>!?!?!?!
great lol
so you found the problem? because then I can finally go to sleep ahaha
Now I know this has to do with what I did with....i can't remember his name rn
We did this
explain, I know everyone here lol
public enum MobName {
LEVEL_1(1, new Weighted<>("MinerZombie",1)),
LEVEL_2(2, new Weighted<>("Samurai", 1)),
LEVEL_3(3, new Weighted<>("ToxicZombie", 1)),
LEVEL_4(4, new Weighted<>("FrozenInhabitant", 1));
private final int level;
private WeightedRandomGenerator<String> randomGenerator = new WeightedRandomGenerator<>();
@SafeVarargs
MobName(int level, Weighted<String>... names) {
this.level = level;
for (Weighted<String> name : names) {
randomGenerator.addItem(name.getObject(), name.getWeight());
}
}
public String getRandomName() {
return randomGenerator.generateRandom();
}
public static String getMobName(int level) {
for (MobName mobName : MobName.values()) {
if (mobName.level == level) {
mobName.getRandomName();
}
}
return null;
}
}
Whats dungeon game ln 183
this is why I asked you 20 times to print the SELECT query ๐
We made a weighted mob enum thing
public class Weighted<E> {
private final E object;
private final double weight;
public Weighted(E object, double weight) {
this.object = object;
this.weight = weight;
}
public double getWeight() {
return weight;
}
public E getObject() {
return object;
}
}
I made a weighted YOUR MOM enum thing
I can't remember his name
Im gonna get up for this, ill be on my pc in like 5-10 minutes
scnr
lets also not forget that imajin sucks
minion325
who's that
oh
Huh, not all that different from my weighted system. lol
MobName.getMobName(currentLevel) That's what gave the error
Well unless your weighted system gives you big errors lol
I'm ngl he had to help me understand it so not even sure wtf Object.hashCode() could mean
Like in my brain I understand how it works
wtf even is that, on a side note
wdym
"record" but I just looked it up
okay im on pc
records are the most useless invention to java ever
lol
time to turn my brain on
they are like immutable @Data classes
ebic you want context on what we're trying to do?
sure
LEVEL_1(1, new Weighted<>("MinerZombie",1)),
LEVEL_2(2, new Weighted<>("Samurai", 1)),
LEVEL_3(3, new Weighted<>("ToxicZombie", 1)),
LEVEL_4(4, new Weighted<>("FrozenInhabitant", 1));
Each one of the enum entries corresponds to a String of a mobname that is for that level. Levels are in numbers (1, 2, 3, 4) not the "level_1" etc
I wanted a system that I could add multiple strings (mobnames) and a weight and with that information doing MobName.getRandom(level) it would return a random mobname for that level
You know how weights work so yeah
And according to the error and when it happened something went wrong from #getRandom to return
fix it @remote swallow
LEVEL_1(1, new Weighted<>("MinerZombie",1), new Weighted<>("Mob2",1)) would do 50% random between both. for example
There's a difference between weighted systems and percent based ones.
add a sys out on the getMobName and getRandomName
Yes yes I know I didn't mean % directly
wait...
Am I looking at the right thing getMobName()
Is it never returning the correct thing?
oh god
Idk, it's hard to tell by the stacktrace. What's line 183 of DungeonGame?
LOL
I just did too
You could blame me
But I blame minion
Technically you did fix it
If you didn't ask for a sysout in there
i looked at it
and didnt see anything off
you said its never returning the right thing
then i saw it
im trying to connect a database to an external server and its refusing to connect?
first time doing this
so
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
Caused by: java.net.ConnectException: Connection refused```
code
public Connection connection;
public Connection getConnection() throws SQLException {
String url = "jdbc:mysql://localhost:3306/embarkkmines";
String user = "root";
String password = "";
Connection connection = DriverManager.getConnection(url, user, password);
this.connection = connection;
Bukkit.getLogger().log(Level.INFO, "Connected to database!");
return connection;
}```
Do you have jdbc?
No worries
The home of Spigot a high performance, no lag customized CraftBukkit Minecraft server API, and BungeeCord, the cloud server proxy.
Plugin
thanks
i'll try the dependency rq
np. I would give you more detailed steps but I actually haven't done that in years
I'm sure someone else will if you can't do it
Caused by: java.lang.SecurityException: Invalid signature file digest for Manifest main attributes ๐ค
that's the only error now
Ok out of my area now
Just wait until someone helps you
Post the full error
oop
at sun.nio.ch.Net.pollConnect(Native Method) ~[?:?]
at sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[?:?]
at sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:542) ~[?:?]
at sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:597) ~[?:?]
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[?:?]
at java.net.Socket.connect(Socket.java:633) ~[?:?]
at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:153) ~[mysql-connector-java-8.0.29.jar:8.0.29]
at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:63) ~[mysql-connector-java-8.0.29.jar:8.0.29]
at com.mysql.cj.NativeSession.connect(NativeSession.java:120) ~[mysql-connector-java-8.0.29.jar:8.0.29]
at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:948) ~[mysql-connector-java-8.0.29.jar:8.0.29]
at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:818) ~[mysql-connector-java-8.0.29.jar:8.0.29]
at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:448) ~[mysql-connector-java-8.0.29.jar:8.0.29]
at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) ~[mysql-connector-java-8.0.29.jar:8.0.29]
at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198) ~[mysql-connector-java-8.0.29.jar:8.0.29]
at java.sql.DriverManager.getConnection(DriverManager.java:681) ~[java.sql:?]
at java.sql.DriverManager.getConnection(DriverManager.java:229) ~[java.sql:?]
at me.outspending.embarkkmines.API.Database.Database.getConnection(Database.java:20) ~[EmbarkkMines-0.0.1.jar:?]
at me.outspending.embarkkmines.EmbarkkMines.onEnable(EmbarkkMines.java:15) ~[EmbarkkMines-0.0.1.jar:?]
... 26 more```
sorry for ghost ping ๐
I believe connection refused means you put your login information incorrectly
localhost:(server's port)?
Minehut
Then no
I assume the server and sql server are on the same, correct?
yeah
minehut should give you login credentials when you make a datbase
Yes it would, are you making your own plugin or trying to connect another plugin?
Let me know if you keep getting issues
Search how to start with sqlite and spigot
i doubt minehut provides mysql
This looks like a pain to add things to. Also, is this supposed to be a list of mob names specific to one mob or all mobs of that level?
Nah just all mobs for 1 level. and it's not configurable
Hey alright so I just had a major issue here. I thought I had failsafes for mob spawning but I was wrong
@kind hatch Wanna give it a look?
I suppose
private void generateLevel() {
new BukkitRunnable() {
@Override
public void run() {
mythicMob = MythicBukkit.inst().getMobManager().getMythicMob(MobName.getMobName(currentLevel)).orElse(null);
if (mythicMob == null) {
cancel();
return;
}
if (state == State.BOSS_FIGHT) {
cancel();
return;
}
if (spawnedCount >= 40) {
return;
}
for (int i = 0; i < 5; i++) {
Location location = locations.getRandomLocation();
mythicMob.spawn(BukkitAdapter.adapt(location), 1);
}
}
}.runTaskTimer(plugin, 1, 10);
}
Not even configurable internally? It might just be me, but if I can edit this stuff via a file, I will.
It could be internally but currently no need for it but yeah
So what I think is happening here is that #generateLevel() is getting called from
another taskTimer() and I think it's creating infinite instances of itself
Cause at the start it's all g but the longer it goes the more it spams and then 1k mobs
But I can't really think of others ways to do this
Well, as long as this isn't called multiple times you should be fine. This looks like state management to me and I'm not that great at it. lol
This is the structure
new BukkitRunnable() {
@Override
public void run() {
if (!isEnabled()) {
return;
}
activateDungeon(); <----------- state manager which then calls generateLevel()
------- Then generatelevel calls it's own task
}
}.runTaskTimer(plugin, 0, 40);
Oh, I guess the one thing I would check is the spawnedCount variable. Shouldn't you be incrementing that everytime you spawn the mob?
Well I'm doing that here
@EventHandler
public void preventMobSpawn(MythicMobSpawnEvent event) {
if (event.getLocation().getWorld() != world)
return;
if (state == State.IN_PROGRESS || state == State.BOSS_FIGHT) {
event.setCancelled(false);
spawnedCount++;
return;
}
if (spawnedCount <= 40) {
event.setCancelled(false);
return;
}
event.setCancelled(true);
}
And then the opposite on DeathEvent
But since like I said, starts perfectly then after a bit it floods hard
I assume I have a inf loop somewhere
Like look at these logs
[00:55:01] [Server thread/INFO]: [Dungeonmaster] [STDOUT] MinerZombie
[00:55:01] [Server thread/INFO]: [Dungeonmaster] [STDOUT] MinerZombie
[00:55:01] [Server thread/INFO]: [Dungeonmaster] [STDOUT] MinerZombie
[00:55:01] [Server thread/INFO]: [Dungeonmaster] [STDOUT] MinerZombie
4 in one second
And if I fast foward
lol
In the same time
@remote swallow you still awake? This gonna make up for the thing before hehe
You should attach the taskId to the debug messages if possible.
Sure I'll crash the server again 3 mins
maybe
Indeed @kind hatch
I was right? I think?
Ignore the cooldown
Starts off with 1 task
Then more
I thought this shit was synced
Why is it duping itself
Looks like you've got some tasks that aren't being killed off. :p
Well ok maybe I'm wrong on how I'm doing this
The thing I'm doing which I believe is not the best that my gamestate manager is always running. in a task itself
And when the moment comes I'm trying to loop through that generate level until the gatestate changes
are those debug messages starting instantly as the server starts or do you trigger it with an event/command
.
As soon as that thing gets activated #generateLevel()
[01:13:00 INFO]: [Dungeonmaster] [STDOUT] taskid: 3387 coolDown: 10
[01:13:00 INFO]: [Dungeonmaster] [STDOUT] taskid: 3387 coolDown: 10
[01:13:01 INFO]: [Dungeonmaster] [STDOUT] taskid: 3387 coolDown: 10
[01:13:01 INFO]: [Dungeonmaster] [STDOUT] taskid: 3457 coolDown: 10
[01:13:01 INFO]: [Dungeonmaster] [STDOUT] taskid: 3387 coolDown: 10
[01:13:01 INFO]: [Dungeonmaster] [STDOUT] taskid: 3457 coolDown: 10
[01:13:02 INFO]: [Dungeonmaster] [STDOUT] taskid: 3387 coolDown: 10
[01:13:02 INFO]: [Dungeonmaster] [STDOUT] taskid: 3457 coolDown: 10
[01:13:02 INFO]: [Dungeonmaster] [STDOUT] taskid: 3387 coolDown: 10
[01:13:02 INFO]: [Dungeonmaster] [STDOUT] taskid: 3457 coolDown: 10
See how first 4 tasks are the right one
I assume it does that after 4 tics because
How many times is that method getting called?
What's the other task?
@Override
public void run() {
if (!isEnabled()) {
return;
}
activateDungeon(); <----------- state manager which then calls generateLevel()
------- Then generatelevel calls it's own task
}
}.runTaskTimer(plugin, 0, 40);
This
Ok, that's why.
Because it runs a task on a timer. Meaning repeat the code inside this block every X ticks.
and sometimes it would go outside of scope
