#help-development

1 messages · Page 1991 of 1

lavish hemlock
#

Referring to the feature creep?

rough drift
#

well i got asked alot of stuff lmfao

opal juniper
#

and how things work lol

lavish hemlock
#

Oh that is also me

wooden fable
#

Ye

#

The leaves are not close enough

lavish hemlock
#

My brain starts to slowly deteriorate if I realize I left some uncleanliness inside of my code.

#

"Shit this is completely unmaintainable," it goes.

rough drift
#

same

viral crag
rough drift
#

my internet be dying

viral crag
# wooden fable The leaves are not close enough

the quick look says: Leaves from trees spontaneously decay (disappear) when they receive a block tick if they are not connected to any block with the logs tag (log or wood blocks), either directly or via other leaf block, with a maximum distance of 6 blocks‌[Java Edition only] or 4 blocks‌[Bedrock Edition only]. Player-placed leaf blocks never decay.

#

the max distance is 7, so if you want to go farther than that you would need a block with the log tag within your range - i couldn't remember what the max distance was and why we cheated

desert tinsel
#

How i can replace a variable from a .yml file with anything else?

viral crag
#

text editor ?

desert tinsel
#

i mean spigot

misty current
#

would a cached thread pool be appropriate to load user data from a database? every time a player logs in i submit some code to the pool grab from the database

viral crag
#

read and write to the yaml file

desert tinsel
#

but getConfig.getString("asdasd"); and replace {player} with player.getName

tardy delta
#

FileConfiguration#set

misty current
#

im learning a bit of stuff from java's concurrent package and i wanted some feedback on my thoughts

waxen plinth
lavish hemlock
#

Well, an async player join event does exist.

waxen plinth
#

Unless there is a really slow connection or a huge amount of data to query one db thread keeps things simple

misty current
#

yeah most probably a query would take half a second in worst cases

waxen plinth
#

Maow lol

lavish hemlock
#

Half a second is important to you? :p

waxen plinth
#

I know where that pfp is from

#

Dirty

viral crag
#

would just need to check to avoid transaction requirements

misty current
rough drift
lavish hemlock
misty current
#

but yes most probably theres no need for more than a thread

lavish hemlock
#

Either way both apply to that description.

rough drift
viral crag
#

as long as a bad connection does not try to connect multiple time in that time

waxen plinth
#

So are you talking about e6

lavish hemlock
#

Pffft good guess

#

Listen it's really easy to find specific things on e6

#

I could've scrolled through the game creator's Twitter for like 5 hours but the other option was way easier

subtle folio
#

are there any good general spigot libs to make plugin development easier?

lavish hemlock
#

RedLib

waxen plinth
#

RedLib

#

Lol

subtle folio
#

alright redlib it is

#

thanks

lavish hemlock
#

There's also Lamp for commands if you don't like how RedLib does them

waxen plinth
#

DM me if you need help using it

rough drift
lost matrix
lavish hemlock
#

I personally really like Lamp

subtle folio
waxen plinth
lost matrix
lavish hemlock
#

Based

waxen plinth
#

Ouch

lost matrix
#

mine included

lavish hemlock
#

I made one once

#

It's gone now

lost matrix
lavish hemlock
#

Yeah it taught me that having 50 services in the plugin class is fuckin' annoying and there's a reason why people use dependency injection frameworks.

subtle folio
#

oh my lord @waxen plinth you made redlib?

waxen plinth
#

Yes

subtle folio
#

woah cool

lavish hemlock
#

Although it took me having to make my own DI lib before I understood DI frameworks.

lost matrix
#

"list" 😄

lavish hemlock
#

tbf a set is kind of a list?

rough drift
#

ah yes

#

list

waxen plinth
#

I bet that could have been computeIfAbsent

lavish hemlock
#

Yep

#

map.computeIfAbsent(coord, ignored -> new HashSet<>()).add(object);

waxen plinth
#

computeIfAbsent is the love of my life

lavish hemlock
#

one-liners are beautiful

lost matrix
#

its from RedLib btw

lavish hemlock
#

HAHAHA

waxen plinth
#

It could have been computeIfAbsent

lost matrix
#

Yes this looks like it could use some computeIfAbsent

waxen plinth
#

I must have written that code before I knew about it

#

RegionMap

lavish hemlock
#

Actually computeIfAbsent has the potential to be faster than the individual method calls since it does everything in a single method

waxen plinth
#

Yeah

#

I'll go fix that lol

lavish hemlock
#

So it truly is a beautiful method

waxen plinth
#

Yeah I guess one problem with RedLib is that I have been working on it for three years

#

Which means that some of the code is three years old

rough drift
#

which is why you "scrap and rewrite"

waxen plinth
#

I've been making an effort to rip out and replace the parts that were old and I didn't feel like I could be proud of

#

Yeah

#

I scrapped and rewrote the config manager and block data manager recently

hasty prawn
#

That's an endless cycle

waxen plinth
#

But there's still gonna be bits and pieces lying around like what 7smile found

vocal cloud
#

Learn something new -> rewrite old code
rinse repeat

waxen plinth
#

I mean, not that what he found is particularly egregious lol

vocal cloud
#

I bet you don't use enough HashMaps. That's probably the issue

waxen plinth
#

I would never use too few hashmaps

rough drift
#

hashmap

viral crag
#

reminds me, need to read linked hashmaps

rough drift
#

my inventory lib is almost done :D

waxen plinth
#

They just keep insertion order

grim ice
#

whats the different between

#

Map<Object, Object> map = new HashMap<>();
and
HashMap<Object, Object> hashMap = new HashMap<>();

lost matrix
#

Nothing really. The first one is just more abstract.

grim ice
#

so literally nothing?

lavish hemlock
#

Well it's different down the line, sure.

#

People recommend the first because of uhh one of the SOLID principles one sec

lost matrix
#

If you program against the first interface then you can change the underlying implementation without breaking your contract.
For example if you have a HashMap in there then you can very simply just change it to a LinkedHashMap without having to worry that
some methods of one implementation are not present in the other.

lavish hemlock
#

objects of a superclass shall be replaceable with objects of its subclasses without breaking the application

lost matrix
#

Liskov substitution principle. Explains it in a more general sense.

grim ice
#

but liskov substitution i understand

#

oh then ok

lavish hemlock
#

Maow wins by ✨ using Google ✨

grim ice
#

but is there a performance gain

lavish hemlock
#

SOLID is a decent set of principles

lost matrix
#

Use Map so you can quickly switch the implementation without issues.

lavish hemlock
#

I mean it's like

#

Performance for the developer

lost matrix
lavish hemlock
#

Since you will be able to maintain the program more easily

#

But it's not runtime performance

grim ice
#

oh yeah

#

but

#

what is this called

#

a sec

grim ice
#

this part

#

its the variable type

#

right?

lavish hemlock
#

Yeah

#

I'd call it the left-hand type, personally.

grim ice
#

so it is possible for the variable type to be different than the variable content lel

#

well a hashmap is a map

#

so ig not

grim ice
#

it must have a super-child relationship

lavish hemlock
#

Well an object in Java is just a reference to some memory which contains a few pointers like the type, fields, etc.

#

At runtime, the type is used for polymorphism.

lost matrix
#

For HashMap the following types are valid:
Object (like for every other class in java)
Serializable
Cloneable
Map<K, V>
HashMap<K, V>

lavish hemlock
#

Fun fact: Variable types effectively do not exist in the bytecode either.

grim ice
#

and itself

grim ice
#

btw how to perform a benchmark

lavish hemlock
#

It produces the most accurate results

grim ice
#

benchmarking is analysing performance of something, right?

#

or is that the wrong thing

lavish hemlock
#

Well it depends on the kind of benchmark

#

You can benchmark execution time or memory usage.

#

(or both)

grim ice
#

o

#

that sounds cool i wanna learn that

lavish hemlock
#

I'm pretty sure JMH doesn't give you the ability to benchmark memory usage?

#

But you could just use a profiler.

#

Anyway so yeah

#

Execution time is kinda the same thing as performance?

sage dragon
#
for (int xPlus = -16; xPlus < 17; xPlus++)
    for (int zPlus = -16; zPlus < 17; zPlus++)
        for (int yPlus = -16; yPlus < 17; yPlus++) {
            Location location = new Location(playerLocation.getWorld(), playerLocation.getX() + xPlus, playerLocation.getY() + yPlus, playerLocation.getZ() + zPlus);
            }
        }

Am I an idiot, or does this code go through all locations in a 16 blocks radius?

Because it doesn't seem to work quite right

lavish hemlock
#

Well... you're going from -16 to 17

#

So, that would actually be... 32 or 33 blocks I believe?

grim ice
#

that many times

lavish hemlock
#

Oh yeah

grim ice
#

and getY and theses tuff

lavish hemlock
#

Well nah that's fine

grim ice
#

make a variable for them

#

o

#

even if its fine its mad ugly

lavish hemlock
#

Well I personally find it uglier to define 3 variables

#

What he really needs is a newline

grim ice
#

but why is it fine

sage dragon
lavish hemlock
#

There's a good chance the JIT compiler will inline that method call anyway.

grim ice
#

so it wont call the method again

#

it will store it and just use it

#

but wait

#

the location can change

#

so that wouldnt work

lavish hemlock
#

Nah it'll still probably locate the field some other way

#

The JIT compiler produces native code

#

So it can actually avoid a lot of access checks

grim ice
#

idk how jit works

lavish hemlock
#

Likelihood is that it just dereferences the underlying field's pointer every time

#

Which is preferable

lavish hemlock
#

That's a simplification

grim ice
#

attack on titan!

#

jk ik its ahead of time

lavish hemlock
#

Basically there's:

  • AOT = Ahead Of Time, javac
  • JIT = Just In Time, the HotSpot VM
#

The JIT compiler acts "just in time," as it is started at runtime when a class is used often

#

There's actually a threshold for HotSpot to run JIT

#

But what it does is take the bytecode produced by the AOT and turn it into native machine code

#

Which is much faster, as the machine's hardware (CPU) can run operations faster than a VM

#

I mean, a VM is just an emulation of a CPU after all.

grim ice
#

i dont get how both of them work

#

lmoa

#

i understand what u said

lavish hemlock
#

Oh well I've literally looked at Javac's code before so I can kinda explain it

grim ice
#

but how do they make stuff fast

lavish hemlock
#

Math.

grim ice
#

fuck

lavish hemlock
#

Except Javac is a pussy ass bitch and isn't really that smart.

grim ice
#

good

#

since im not either

lavish hemlock
#

But you've got shit like static code analysis.

#

Dead code elimination, etc.

grim ice
#

so what it does is making code into native code

#

then storing the result of the code

#

and just using that

#

instead of c alling the method

#

every time

#

or what

lavish hemlock
#

Well it turns the whole class into native code

#

Good question

#

My ideas are dry too so I can't really help you

grim ice
#

it stores the return value

#

and just take it

lavish hemlock
#

I mean I can't explain exactly how the JIT works

grim ice
#

but what if the return value changes???

lavish hemlock
#

I haven't peered into it since I'm not too knowledgeable on C++

lavish hemlock
grim ice
#

i dont even know cpp lol

lavish hemlock
#

Like if it's a mutable variable, then it dereferences from a pointer every time

#

If it's not, then it would probably just store a value

grim ice
#

reading this

#

it looks easy if u use jmh

lavish hemlock
#

It is

grim ice
#

poggo

lavish hemlock
#

I've been using JMH for all my projects (that I care enough to benchmark)

#

You can literally just annotate shit

grim ice
#

ic

#

so what u do in ur projects that u care enough to benchmark

#

is clone the project

#

add the annotations

#

and try out different ways

#

right?

lavish hemlock
#

Well no you write a separate class

#

It's like with unit tests

grim ice
#

i dont unit test

#

it seems pointless to me atm

lavish hemlock
#

I don't either

rough drift
lavish hemlock
#

Unit testing is a great way to verify that your projects stay working across changes

rough drift
#

unit tests are a god sent

grim ice
#

i dont get how they work or how to use them and i never needed them

#

i mean i kinda do

vocal cloud
#

You don't you need them until you use them

lavish hemlock
#

It also:

  • Enforces good coding practices
  • Allows you to work iteratively (TDD/test-driven development)
  • Verifies to other people that your code works
grim ice
#

looks like a headache

lavish hemlock
#

It's pretty easy tbh

#
public final class Test {
    @Test
    public void oh_god_what_have_I_done() {
        assertTrue(programIsNotBroken());
    }
}
grim ice
#

that looks ugly

#

even uglier than me

lavish hemlock
#

Well you don't have to use snakecase

grim ice
#

and how do i know my code works

#

lmao

lavish hemlock
#

But it is conventional for tests

grim ice
#

its not a boolean or shit

#

or does assertTrue throw an exception

lavish hemlock
#

Well yeah that's why you test a bunch of cases

grim ice
#

or smth

lavish hemlock
#

I believe JUnit's assertions throw an AssertionError (like the JVM's assert statement)

grim ice
#

and where do i call my test methods

lavish hemlock
#

Your IDE

grim ice
#

what

#

how

lavish hemlock
#

You specify the class and it runs all @Test methods

grim ice
#

oh

lavish hemlock
#

The IDE'll also show you their status

grim ice
#

and if generates an exception then ur dumb

#

right?

lavish hemlock
#

e.g. it'll go through the methods and literally show you

#

(checkmark here) My test

lavish hemlock
#

So basically to write tests

#

You have to follow a couple of principles

grim ice
#

yo thats kinda cool

lavish hemlock
#

Hopefully:

  • You don't abuse static
  • You don't make your code overly reliant on a framework like Bukkit (since it's hard to test)
grim ice
#

similar to Preconditions.checkArgument

#

right

lavish hemlock
#

Yeah pretty much

#

JUnit uses uhh

#

Assertions

#

But it's conventional to static import its methods

grim ice
#

bukkit is a framework?

#

wasnt it an api

lavish hemlock
#

I define it as a plugin framework

grim ice
#

but the software is bukkit

#

ur just interacting with the software

lavish hemlock
#

The implementation is CraftBukkit

#

Bukkit is a layer over it and other projects that support Bukkit

#

But I call it a framework since it provides a large foundation for plugins

#

Actually it would be more fair to say uhh

#

Bukkit is basically the interface for Minecraft, but also provides a framework for plugins (org.bukkit.plugin)

lavish hemlock
grim ice
#

wdym

lavish hemlock
#

If you have code that has some static mutable value

#

Then you have the risk of a situation like:

#
  • value's default value is "Fuck you, World!"
  • Test 1: Set value to "Hello, World!"
  • Test 2: assertEquals(value, "Fuck you, World!") (this test fails bc we didn't expect test 1 to modify the value)
#

That's just a single example btw

#

The situation mainly arises from having a bunch of static mutable state

#

Since it becomes effectively impossible to track those values

viral crag
lavish hemlock
#

Ah good the more intelligent person is here

#

7smile7 explain it better for me ;w;

lost matrix
lavish hemlock
grim ice
#

ic

#

anyways how to get started with JMH

lavish hemlock
#

Well you probably need a buildsystem plugin for JMH first

lost matrix
#

Oh we are talking about JMH. What do you guys want to benchmark?

grim ice
viral crag
lavish hemlock
#

And why do you care about insertion order for that?

#

Unless

#

Oh I see

#

You mean the lines in the file?

viral crag
#

yaml is inherently unordered

#

also unsure how yaml and treemaps play together, so linked seems like a usable option

quaint mantle
#

Wonder if while false will compile?

#

Coz while false wont ever run

waxen plinth
#

It'll compile

quaint mantle
#

Will it even compile

waxen plinth
#

It's just dumb though

quaint mantle
#

Okay

viral crag
#

depends on the precompiler

waxen plinth
#

You can do if (false) as well

lavish hemlock
waxen plinth
#

Yeah I've done if false before lol

quaint mantle
lavish hemlock
#

I swear I've compiled stuff like if (false) and it resulted in nothingness

#

...although actually

#

maybe I'm misremembering uhh

#

It could've been that the compiler unwraps if (true)

viral crag
#

sensei would probably warn you about it if you use it

waxen plinth
#

I'd guess so

lavish hemlock
viral crag
#

...

lavish hemlock
#

I am my own boss.

#

SOURCE CODE OBFUSCATION A C T I V A T E !

lavish hemlock
#

if (true) if (true) if (true)

quaint mantle
lavish hemlock
quaint mantle
viral crag
#

you can not make someone else think - so it does not matter what you do

grim ice
#

what im doing

#

<build>
<plugins>
<plugin>
that shit
</plugin>
</plugins>
</build>

viral crag
grim ice
#

use jmh

viral crag
#

in gradle or maven?

grim ice
#

maven

lavish hemlock
#

...because I am

#

At least I'm honest with them and myself :p

viral crag
grim ice
#

ok it works now

viral crag
#

aside from it missing the opening plugin tag

lavish hemlock
#

gg

grim ice
#

where should the opening plugin tag

#

be

viral crag
#

for that example at the top ...

grim ice
#

ye

#

ohh

viral crag
#

i think someone just missed it in the copy-paste

grim ice
#

readme

#

ok

#

Plugin 'org.springframework.boot:spring-boot-maven-plugin:' not found

#

tho

#

i can remove that right

lavish hemlock
#

Yeah I don't think you need Spring Boot...

viral crag
#

isnt that one of the maven plugin libraries? (i switched to gradle a bit ago)

quaint mantle
quiet ice
#

it is possible to have recpies that only work if the itemstack has a PDC entry with a certain value but disregards other values? For a plugin of mine I have a self-destructive item which contains a timer on the PDC but I want to disregard the timer for the crafting recipe

grim ice
#

isnt there a button in intellij for mvn clean test btw

cursive crow
#

is there a way to check if a mob is focused on the player?

cursive crow
#

yeah i usually just google it and if it doesn't show up after like 5 different prompts i assume it needs a hacky solution with NMS lol, i should start doing that

#

thank you

lost matrix
grim ice
#

Failed to execute goal com.baidu.maven:jmh-maven-plugin:1.0.1:jmh (default) on project JMHTest: Execution default of goal com.baidu.maven:jmh-maven-plugin:1.0.1:jmh failed.

lost matrix
#

This is a simple arithmetic expression. The used numeric values wont affect the performance of it.

kind hatch
#

Unless you are loading chunks, no.

lost matrix
#

You should still check if sqrt overflows with those values. Should be a quick setup.

ornate patio
#

is there a premade library out there that handles fetching offline players using mojang's API with caching?

quiet ice
ornate patio
#

and if not, how should I go about making API calls without halting the whole server?

lost matrix
lavish hemlock
hasty prawn
#

what the hell is goin on here

torn vale
#

Is there a way to register and unregister events while the server is running?

waxen plinth
#

Yes

#

Of course you can

#

You can do registerEvents at any time

waxen plinth
#

And you can use HandlerList.unregisterAll(listener) to unregister a listener

waxen plinth
lost matrix
waxen plinth
#

What does bake do exactly?

lavish hemlock
#

creates cookies

#

nom

quiet ice
#

Compiled a bunch of classes and registers them via the unsafe class

lavish hemlock
#

Wow

quiet ice
waxen plinth
#

Wait what

lost matrix
waxen plinth
#

Why does it work that way

lavish hemlock
#

That's a bit dramatic I did this exact thing for my serialization lib

quiet ice
#

At least that is what paper does, spigot is a bit less optimized

lavish hemlock
#

Oh okay

lost matrix
#

spigot does a bunch of reflection stuff every time iirc

quiet ice
#

But at the core, it does the same thing

lavish hemlock
#

Cuz I was like "That doesn't sound very CraftBukkit"

waxen plinth
#

I don't get why that's necessary at all

lost matrix
lavish hemlock
#

I personally think method handles would've worked just fine

waxen plinth
#

Like I get they probably don't want to use reflective invocation for every event listener every time an event is invoked

#

Yeah exactly

#

That's what MethodHandle is for

ornate patio
#

is there a premade library out there that handles fetching offline players (by name) using mojang's API and handles caching?

and if not, how should I go about making API calls without halting the whole server?

quiet ice
#

Legacy versions!

waxen plinth
#

It's just as fast as native invocation

grim ice
#

how to run benchmarks

torn vale
waxen plinth
lavish hemlock
#

MethodHandle has existed since Java 1.7 iirc

quiet ice
#

Bukkit has also been there forever

torn vale
waxen plinth
#

Yeah and what's stopping them from rewriting how events are handled

#

It's all internals so nothing about the api would need to change

#

Like that's so bad

lost matrix
#
if(!game.isRunning()) {
  return;
}

...

grim ice
#

Benchmarking

lost matrix
lavish hemlock
#

I was actually considering a PR to Spigot a while back that would replace the reflective invocations with method handles

quiet ice
#

Also, method handles are a bit less performant than direct calls - and if you have events that are called very often like PlayerMoveEvent every inch of performance might help.

quiet ice
waxen plinth
#

Method handles are comparable

#

Like there's gonna be the overhead of the one additional call to the method handle itself

#

But I'm pretty sure other than that method handles are almost exactly as fast as native invocation

lavish hemlock
#

I mean, it wouldn't make much difference in later versions of Java because they're gonna use method handles in reflection in said later versions, but y'know...

waxen plinth
#

Also reflection is going to use method handles soon

lost matrix
#

Reflective invocations and method handle calls get jit compiled quite fast to the point
where they are indistinguishable from normal method calls.

waxen plinth
#

Yeah lol

#

And on top of that

#

I'm pretty sure hotspot switches from reflective invocation to method handles after a certain number of calls

#

So reflection is nowhere near as slow as people expect it to be

quiet ice
waxen plinth
#

Is java 18 out yet

lavish hemlock
#

Nope lol

waxen plinth
#

Hence soon

lavish hemlock
#

but you can compile it yourself

quiet ice
#

Probably not, but you can always compile it yourself

hasty prawn
#

Does anyone know a reason why I would have to specifically add spigot-api as a dependency to use Player#spigot and the normal spigot depend doesn't have it Thonk

quiet ice
#

And it isn't valhalla soon

hasty prawn
waxen plinth
#

valhalla :(

#

when

#

It's been sitting there untouched for so long smh

lost matrix
#

probably gonna have 20 incubations like the foreign memory api or the vector api

lavish hemlock
#

direction and magnitude

waxen plinth
#

Right, that makes sense

#

But we still haven't seen much of anything other than talk of value types

quiet ice
#

"These things, they take time"

lavish hemlock
#

"value-based types" exist in the JDK, technically

#

But they're basically an internal optimization on standard lib classes

waxen plinth
lost matrix
#
  @EventHandler
  public void onPrepare(PrepareItemCraftEvent event) {
    recipeManager.handlePrepareEvent(event);
  }

Woops should be this instead.

quiet ice
#

Ah

lost matrix
torn vale
#

Is there smth like GameProfile in the Spigot 1.8.8 API?

quiet ice
#

Yeah, the player profile API exists

lavish hemlock
#

Pathetic.

ornate patio
#

where

torn vale
#

okay, than a other question:
How to create a ItemStack (PLAYER_HEAD) with a custom texture in Spigot 1.8.8?

lost matrix
torn vale
#

wait a min

#

i am using 1.16.5

lost matrix
lavish hemlock
#

Thank god I have the pleasure of coding for 1.18.1

torn vale
#

completely forgot about it lol

ornate patio
lost matrix
lost matrix
# ornate patio ..?

Bukkit#getOfflinePlayer(String)
I think it has an offline player cache of the last 10k users that have been online

lavish hemlock
#

Nope

#

Or well

lost matrix
quiet ice
#

It may be, but it is safe to discard

ornate patio
lavish hemlock
#

...why would you need more than the last 10k?

ornate patio
#

i'm trying to create my own moderation plugin

lavish hemlock
#

How many people do you expect to join a single server?

quiet ice
#

It is probably safe to call async

ornate patio
#

and for /pardon command

#

yk

quiet ice
#

At worst you can write your own caching DB

lost matrix
ornate patio
lavish hemlock
#

It's not a big deal :p

grim ice
#

wat tis mean

quiet ice
#

Then just write a huge DB

grim ice
#

Benchmark Mode Cnt Score Error Units
Classing.loop avgt 5 309.725 ± 144.846 ms/op

manic delta
#

How can I compress my plugin? To upload it to spigot it must be less than 10mb and I literally only have 53 lines of code and a config.yml

ornate patio
grim ice
#

does this mean that the benchmark took 309ms to 144ms?>

ornate patio
#

thing is, I'm wondering whats the best way to fetch data from an API

lavish hemlock
grim ice
#

ooo

lavish hemlock
#

Or

#

No wait

grim ice
#

that sounds like a lie it took way more

ornate patio
#

without stopping the whole server

lavish hemlock
#

It was called 5 times

lost matrix
lavish hemlock
#

And uhh

grim ice
#

o

lavish hemlock
#

It took 309 ms per operation possibly

grim ice
lavish hemlock
#

Since it has a 144 ms error

grim ice
quiet ice
#

Just know that 50 million cached players will probably be around 1.6 GB of memory used 24/7

grim ice
#

or wait nvm

lost matrix
waxen plinth
#

50 million cached players lol

#

1.6gb is nothing

quiet ice
#

And that is a VERY conservative guess

ornate patio
lavish hemlock
#

Welcome to:
"I don't know how performance works but I want to make something fast."

waxen plinth
#

Ok but what server is going to have 50 million fucking cached players

ornate patio
#

if it runs out of space, it'll write over the old data

grim ice
#

what

#

i dont get it

lavish hemlock
#

SO WAIT

#

YOU WANT TO CACHE LESS PLAYERS WITH A DB NOW?

ornate patio
#

bruh okay listen

lavish hemlock
#

BECAUSE THE SERVER CACHES 10K ORIGINALLY

quiet ice
#

It will probably be twice of that as soemone will just add a lot of very long usernames and thus you will have around 4-6 GB of memory used up 2477

ornate patio
#

500 players in cache, correct?

quaint mantle
ornate patio
#

if someone wants to get a new player that's already not in the cache

#

it'll use mojang's API to fetch that data

lost matrix
quaint mantle
#

If maven then set scope provided, if gradle ask other users

ornate patio
manic delta
quiet ice
#

Then a cache will not help

lost matrix
#

It will only call mojangs api if the player has never played before

quiet ice
#

You will need to fetch the data either way

lost matrix
#

otherwise it will read the offline player from disk

quiet ice
#

Paper has a method to only read from disk afaik

manic delta
#

wdym with set scope provided

#

is my first time doing public plugin lol

quiet ice
#

<scope>provided</scope>

lavish hemlock
#

?learn-maven

#

lol

quiet ice
#

or compileOnly "org.spigotmc:spigot-api:RELEASE"

lost matrix
lavish hemlock
#

Scopes are

#

:p

lost matrix
#

meh

lean gull
#

what is the event for when a block is broken? (not neccessarily by a player)

ornate patio
quaint mantle
#

Yep, by default scope, they will compile the dependency into the jar so

quiet ice
ornate patio
#

yes ik

lean gull
quiet ice
#

So uncaching might be usefull there

lost matrix
quiet ice
#

As you would just re-fetch the user

#

If you do it async there is no performance concern

lost matrix
ornate patio
#

hold up lemme type a whole essay to explain this then lmao

quiet ice
#

Also usually you only unban users shortly after they got banned

#

After 30+ days it is usually fair to assume that they won't attempt to get unbanned

ornate patio
#

wait wait wait a minute

ornate patio
#

longer than 30+ days

quiet ice
#

Then you just need an UUID?

lavish hemlock
#

lmao

ornate patio
quiet ice
#

Do not use bukkit's ban api

kind hatch
#

Probably not, but you can always get the player name from the uuid.

quiet ice
#

Perhaps do, idk. But I'd not

#

BanList as far as I have heard only stores player names and is just not up to date with 1.6+ world

lost matrix
#

Imagine using bukkits ban api with more than 10k unique users in 30 days

quiet ice
#

Also, Bukkit's ban API has integrated support for tempbans, so that isn't an issue either

lean gull
#

how do i check when a dead horn coral wall fan is broken? not just by a player tho

ornate patio
#

here's how my whole architecture works:

when a moderator uses a command such as /ban some_player, the plugin will add that player to Bukkit's BanList and also save that player in it's own database.

Then i have an onAsyncPlayerPreLoginEvent that checks if the player is in the BanList. If so, check to see if the player's ban expired or not. If it has, then unban them and allow them in the server

just lmk if you see a problem with this lmao

kind hatch
#

You should just use your own database at that point.

kind hatch
#

Go the checks at least

#

For*

ornate patio
#

and completely screw BanList?

grim ice
lost matrix
grim ice
#

so if i change my name my ban is expired

ornate patio
lavish hemlock
kind hatch
#

Also, isn’t there a ban and unban method in the player object? Or maybe the offline player object?

viral crag
quiet ice
#

every 15 days?

lavish hemlock
#

30 days, iirc

quiet ice
#

Yeah, I thought so too

buoyant viper
#

better be checking case insensitive to make sure people cant bypass with name modifiers

ornate patio
#

i did that so that banned players still can't join in case, for some reason, the moderation plugin is disabled for a moment

#

however maybe it isn't worth using it then

quiet ice
#

For such critical infrastructure I usually invoke System#exit when the plugin fails to load

ornate patio
#

well that is a good point but not what i was addressing

#

I'm saying if the server owner removes the plugin from the plugins folder

#

or something

lavish hemlock
#

Inject security code into the server jar 😎 (don't do this, MCAM will flag you as a virus)

quiet ice
#

Then the server administrator usually does it knowing that there are consequences

ornate patio
#

hmm okay

lavish hemlock
#

You could allow exporting the ban list

next stratus
#

I wanna scream, people don't understand updating my plugin isn't my full time job ;-;

ornate patio
lost matrix
next stratus
ornate patio
#

okay so I'm going to remove this BanList thing then...

grim ice
#

oh its paid then

ornate patio
#

now another thing

next stratus
#

ye

ornate patio
#

my database will only store player UUIDs (along with other info about the ban)

grim ice
#

well they paid money for it i understand the frustration

next stratus
#

but still to ping me for every single message?

grim ice
#

Warn them

#

do it 3 times, kick them

quaint mantle
#

Scanm them

grim ice
#

5 times, ban them

lavish hemlock
next stratus
#

I try my absolute hardest to reply as fast as I can and I have been updating the plugin so much just today

ornate patio
#

so.. is it plausible for a moderator to use the player's UUID in the pardon command? Or should I do this whole Mojang API thing where I fetch the UUID by player name..

next stratus
#

I can't wait for when they find out i'll be starting long hour work soon lol

quaint mantle
#

Mute the server

grim ice
#

Benchmark Mode Cnt Score Error Units
MappingStuff.tryHashMap avgt 5 ≈ 10⁻⁵ ms/op
MappingStuff.tryMap avgt 5 ≈ 10⁻⁵ ms/op

grim ice
#

what does this mean btw

next stratus
lavish hemlock
grim ice
#

i still dont get benchmarks syntax

ornate patio
lost matrix
lavish hemlock
#

Bans

ornate patio
#

how would that work

#

I'm still only storing the player's UUID

lavish hemlock
#

List the players or smthn idk it was sarcastic

grim ice
lavish hemlock
#

I should make a moderation plugin... that'd be cool.

lost matrix
lavish hemlock
#

Stealing your ideas, okay1204 ✨

ornate patio
#

mmm

#

well mines not just a moderation plugin

lavish hemlock
#

True rivalry

ornate patio
#

but thats the first part

grim ice
#

oh mine is @State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Fork(value = 1, jvmArgs = {"-Xms2G", "-Xmx2G"})

ornate patio
#

and it's not for the public (kind of)

grim ice
#

ok ill try that

next stratus
lost matrix
lavish hemlock
#

7smile7, although a dick, is very smart 👍

grim ice
#

btw

#

why do benchmarks take some time

next stratus
#

i've always found 7smile to be polite

grim ice
#

i expected them to be blazing fast

lavish hemlock
#

Because it has to execute the code a lot.

grim ice
#

ig

viral crag
#

the same reason you have to show your work on a math test

lavish hemlock
#

Literally proved to his teacher he could just do the math in his head.

grim ice
next stratus
#

I swear I've 100% improved with coding so that's good right?

lost matrix
viral crag
#

you are averaging, thats not a single run

lost matrix
#

Unless you do Mode.SingleShotTime
This is kind of a "cold start" mode

grim ice
#

is a cold start bad

#

i assume so

#

idk

viral crag
#

nascar vs drag strip - GO!

lavish hemlock
grim ice
#

Benchmark Mode Cnt Score Error Units
MappingStuff.tryHashMap avgt 5 0.011 ± 0.005 us/op
MappingStuff.tryMap avgt 5 0.011 ± 0.002 us/op

#

so uh

#

w a t does this mean

viral crag
#

5 runs with result average and error

grim ice
#

what is error

lost matrix
#

This means exactly what we told you 😄
No diff between storing a HashMap in a Map or HashMap variable

grim ice
#

yeah

#

i know but

viral crag
#

you know what +- means?

sterile token
grim ice
#

im just testing jmh this isnt the purpose

#

lol

lavish hemlock
#

Also

#

use


#

please

#

use

a codeblock
viral crag
#

+- is the error

sterile token
#

I didnt know before

grim ice
#

whats Score, error

#

cnt is runs, avgt is average, units is obvious

#

but whats those two

lavish hemlock
#
codeblocks are monospaced
meaning all spaces take up the same width
and therefore, it is easier to read things that are centered in some way

so please...

```
do this
```

lost matrix
#

error != uncertainty

grim ice
#

oh so what is error

viral crag
#

0.011 ± 0.005 means 0.0115 to 0.0109 us the time clock jitter or variance is most likely the source of the error

lost matrix
#

analog to Accuracy vs. Precision

grim ice
#

oh it means

#

error means variance

sterile token
grim ice
#

i see

#

but how does it obtain the 0.005

lavish hemlock
#

Computers are imprecise machines

grim ice
#

does it mean it varied 0.005

viral crag
#

precision confidence rather than varriance

grim ice
#

so e.g one was 0.011 and one 0.016

viral crag
#

no

grim ice
#

so

viral crag
#

it "could be" that, they system clock is possibly just not capable of ensuring exactly what it is in that time range

lavish hemlock
eternal oxide
#

Computers are very precise. Its simply that so many different things can be happening at once

#

your one task can have so many different timings as other things also happen

#

so you time many passes and average them out

viral crag
#

you can depend that your operation took 0.01us but it could be slightly higher or lower than that

#

aka it took 10ns it might be as slow at 12ns or as fast as 10.9 ns the result was averaged to 11ns

grim ice
#

how about this

#
MappingStuff.tryHashMap    avgt    5  0.012 ± 0.002  us/op
MappingStuff.tryLinkedMap  avgt    5  0.014 ± 0.006  us/op
MappingStuff.tryMap        avgt    5  0.015 ± 0.013  us/op
molten hearth
#

bumping my issue from earlier, I'm using PlaceholderAPI and after running /papi reload my placeholders dont work until I re-load my plugin again

viral crag
ornate patio
#

how do i show parameter names in a command like this:

eternal oxide
lost matrix
molten hearth
#

Will try, tyvm

grim ice
viral crag
grim ice
#

tryMap

grim ice
#

wat

lost matrix
#

code please

grim ice
#
    @Benchmark
    public HashMap<Integer, String> tryHashMap(){
        return new HashMap<>();
    }

    @Benchmark
    public Map<Integer, String> tryMap(){
        return new HashMap<>();
    }

    @Benchmark
    public Map<Integer, String> tryLinkedMap(){
        return new LinkedHashMap<>();
    }```
river oracle
lost matrix
#
  @Benchmark
  public void hashMapConstructor(Blackhole blackhole) {
    HashMap<Integer, String> map = new HashMap<>();
    blackhole.consume(map);
  }

  @Benchmark
  public void linkedHashMapConstructor(Blackhole blackhole) {
    LinkedHashMap<Integer, String> map = new LinkedHashMap<>();
    blackhole.consume(map);
  }
molten hearth
#

im not caching placeholderapi though

#
    @EventHandler(priority = EventPriority.HIGH)
    public void onEnable(PluginEnableEvent event) {
        MarriagePlugin plugin = this.core.getPlugin();
        if(Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
            new MarryExpansion(plugin, core).register();
        }
    }
``` ```java
public class MarryExpansion extends PlaceholderExpansion {

    private final MarriagePlugin plugin;
    private final MarriageCore core;

    public MarryExpansion(MarriagePlugin plugin, MarriageCore core) {
        this.plugin = plugin;
        this.core = core;
    }

    @Override
    public String getAuthor() {
        return "paradise";
    }

    public String getPartnerCustom(MPlayer player) {
        return "abc";
    }

    @Override
    public String getIdentifier() {
        return "marriage";
    }

    @Override
    public String getVersion() {
        return "1.0.0";
    }

    @Override
    public boolean persist() {
        return true;
    }

    @Override
    public String onRequest(OfflinePlayer player, String params) {
        MPlayer mp = core.getMPlayer(player.getPlayer());

        if(params.equalsIgnoreCase("partner")) {
            String returnplaceholder = getPartnerCustom(mp);
            return returnplaceholder;
        }

        return null;
    }
}```
viral crag
ornate patio
#

"This will return an object even if the player does not exist"

Then.. what does it even return?

viral crag
#

doesnt say that the offline player is/was from your server

ornate patio
#

yeah but

#

if i type a random UUID

#

what will it return

#

what if the UUID doesn't even match any offline player

ivory sleet
#

An OfflinePlayer which encapsulates said uuid

ornate patio
#

oh ok

viral crag
ornate patio
#

okay thanks

ivory sleet
#

Well Server::getOfflinePlayer which takes UUID doesnt involve mojang api whatsoever

viral crag
#

Actually they must be since you pad XUID with zeros at the front to match UUID

viral crag
#

wonders what kind of player 00000000-0000-0000-0000-000000000000 is

lost matrix
#

You could guess a million UUIDs every day from today on and not hit a single minecraft user id in years. So the chance
of this id even existing is basically 0

viral crag
#

the XUID start from the bottom end

#

probably a MS dev/testing user

grim ice
#

Give me a library idea

lost matrix
young knoll
#

Persistent block data is a fairly easy one

#

If that’s what you’re after

lost matrix
#

Really depends on your approach

grim ice
#

all of these are milked

lost matrix
#

Ah you want something new?

grim ice
#

yeah

#

like the last one i made

#

afaik there isnt anything like it without nms

lost matrix
#

Custom recipe api with more control over ingredients, results and conditions

young knoll
#

Make me a random tick API :p

grim ice
#

a really good idea

#

ill do that

#

ty

lost matrix
#

fk im writing a resource post about that right now..

grim ice
#

oh about custom recipe api?

lost matrix
#

yes

grim ice
#

oh then i wont do it

#

u can finish

lost matrix
#

I dont mind

grim ice
#

Oh okay

#

but more control over ingredients, what do you mean?

#

like have custom items as an ingredient?

lost matrix
#

Actually there is one thing i was thinking about that needs a lot of packet handling.
An observation API. With methods like:

  public static Set<Chunk> getChunkView(Player player) {
    
  }

  public static Set<Entity> getEntityView(Player player) {

  }
#

You basically track which chunk and entity is in a players view by tracking the sent packets.

grim ice
#

that sounds like a pain tbh

lost matrix
#

With events:
PlayerReceivesChunkEvent and so on

grim ice
#

but the recipes thing needs nms right

lost matrix
marsh burrow
#

Would anyone know of a way to check if a worlds lowest block is 0 or -64?

lost matrix
grim ice
#

how about doing that recipes learning thing

marsh burrow
#

lowest build depth actually yeah

lost matrix
sterile token
#

https://paste.md-5.net/ziliceqodu.java - Im getting NPE on JsonFile line 38

And im testing with:

FileHandler json = new JsonFile("C:\\Users\\Usuario\\Desktop\\Pruebas\\test.json");
json.set("messages", "Hi");
marsh burrow
torn oyster
#

is it possible to generate just a singular chunk

lost matrix
sterile token
#

Map can generate NullPointerException when setting values?

torn oyster
young knoll
#

1.8 worlds are always 0

marsh burrow
sterile token
lost matrix
midnight shore
#

Hi, how could i get the ip of MongoDB in order to connect to it from Minecraft Plugin?

young knoll
#

I think the big issue is a lot of those 1.8 servers are large

sterile token
marsh burrow
#

It might be time to upgrade huh

lost matrix
marsh burrow
#

how can I check when that WorldInfo was introduced?

lost matrix
sterile token
midnight shore
sterile token
# lost matrix show the stack trace pls
Exception in thread "main" java.lang.NullPointerException
    at dev.alex.net.utilities.file.json.JsonFile.set(JsonFile.java:38)
    at dev.alex.net.utilities.file.testing.Main.main(Main.java:10)
midnight shore
#

@*****.****.mongodb.net is it this?

lost matrix
#

what is "this.object"

sterile token
#

I will check prob i didnt sent it

lost matrix
#

Ah i see the paste

sterile token
#

Ah allright

lost matrix
#

ah ok. this.object is null.

sterile token
#

But how?

#

Hmn

lost matrix
#

If you would use a newer java version then the stack trace would have told you

lost matrix
sterile token
#

Doesnt assign?

grim ice
#

7s but adding a recipe to a player knowledge book

#

needs nms

#

since u dont have a ShapedRecipe or smth

lost matrix
lost matrix
lost matrix
grim ice
#

like that how is the library any use if u use shaped recipes

sterile token
#

Hmn i cannot understand

lost matrix
midnight shore
lost matrix
sterile token
#

😕

lost matrix
midnight shore
#

the point is that i don't know the server's ip

rough drift
#

just know it

lost matrix
#

Oh you got an atlas one

marsh burrow
#

What if I do a world.getBlockAt(x, -1, y), in a 1.16 server, would I get an error or a air block?

midnight shore
rough drift
#

air

#

iirc

#

or null

#

?try

lost matrix
grim ice
#

o

midnight shore
#

i wanted to start using this databases but i don't really know much, sorry for my ignorance

rough drift
lost matrix
midnight shore
#

is it the ip the one i cancelled out lastly?

rough drift
#

iirc yes

lost matrix
midnight shore
#

okay i'll try

marsh burrow
rough drift
#

oh thats a thing?

#

oh wait yes

marsh burrow
#

void air is basically like, it dont exists right

rough drift
#

its void air

#

like cave air

#

but void

lost matrix
#

Its a normal material. There are 3 types of air in minecraft

rough drift
#

cave air, void air and air

woeful crescent
#

hey, is there a way to just, check if a player can SEE another player?

#

like not having a direct line of sight

#

but maybe just facing the right direction

#

like the other player is on the side that the player is facing?

marsh burrow
rough drift
#

raycast forward from the player's direction, and just do a simple line of sight with that

woeful crescent
#

i dont mean livingentity.haslineofsight

lost matrix
rough drift
#

no, just use a blockiterator

woeful crescent
#

nahg

rough drift
#

in the direction the player is facing

woeful crescent
#

like im not talking about that is the thing

rough drift
#

and if it lands on the block the other player is in

#

done

woeful crescent
#

no

grim ice
#

isnt there player.canSee(player)

woeful crescent
#

i dont mean to be rude but just read the messages haha

woeful crescent
sterile token
#

Someonelse is confused between documents and objects?

woeful crescent
#

like completely hidden with player.hidePlayer

rough drift
#

OHHHHHHHHHH

woeful crescent
#

no not you

#

lol

woeful crescent
rough drift
#

yes

sterile token
#

Im confuse because i dont know if mongo when saving an object create another document or save it in the same

rough drift
#

thread 2

lost matrix
# woeful crescent this is to check if the other player is literally hidden

Something like this:

  public boolean hasViewAngleTowards(Player other, Player viewer, double minAngle) {
    return hasViewAngleTowards(other.getEyeLocation(), viewer, minAngle);
  }

  public boolean hasViewAngleTowards(Location location, Player viewer, double minAngle) {
    Vector line = viewer.getEyeLocation().toVector().subtract(location.toVector());
    double angle = viewer.getEyeLocation().getDirection().angle(line);
    return angle < minAngle;
  }

You just need to play around with the angle. It also depends on the players FOV if he is actually on the screen or not.

woeful crescent
#

true, think ill just stick to 180˚ for now

#

just to be safe

rough drift
#

oh you wanted that

lost matrix
#

Yes 180° is a safe bet

rough drift
#

don't use fixed

#

use the player's fov, but make sure to cap it serverside

#

otherwise a mod can spoof that iirc

woeful crescent
#

??

rough drift
#

if a player has a fov of 120 and you check say 70, that player can see another player but the check says no

lost matrix
woeful crescent
#

im checking 180˚, you cant see past that

woeful crescent
rough drift
viral crag
#

thats a client setting - you can have a 360 FOV on the client and teh server will never know

woeful crescent
#

ohh shoot

lost matrix
woeful crescent
#

lmao ur right

woeful crescent
#

eh who cares

viral crag
woeful crescent
#

yea but

#

it's just context

#

idrc in the context i mean

#

@lost matrix would this work?

public static final double MIN_FOV = 90;

    public static boolean canSeeTarget(LivingEntity looking, Location target){
        return canSeeTarget(looking.getEyeLocation(), target);
    }

    public static boolean canSeeTarget(Location eyeLocation, Location targetInQuestion){
        Vector line = eyeLocation.toVector().subtract(targetInQuestion.toVector());
        double angle = eyeLocation.getDirection().angle(line);
        return angle < MIN_FOV;
    }
marsh burrow
#

Ah, step one again, VOID_AIR doesn't exist before 1.15...

smoky oak
#

why not ray trace in that direction with the distance between the players

smoky oak
#

*entities

#

and then just

#

block.isAir()

woeful crescent
#

MIN_FOV is 90 btw

lost matrix
#

Or you just do MIN_ANGLE = Math.PI / 2

#

Also if you ever think about lowering this from 90° then you need to take the distance into account

viral crag
#

you are also missing obstructions

smoky oak
#

ray trace

#

do angle check then try ray tracing

#

if its just one ray its not an issue

lost matrix
#

Its not about direct line of sight. There is a method for that already.

woeful crescent
#

i dont understand

#

ahahaha lmao

#

so funny

#

dude's spamming lol

#

but he's using the word SPAM

#

🤣

smoky oak
#

meat

sterile token
#

@ancient plank please ban - Spam

woeful crescent
#

🤣 🤣

smoky oak
#

hah

#

the bots screwing him over

#

anyways

#

different question, for writing an api the only thing i need to do is a) set it as requirement in the plugin.yml and b) flag the methods i want to use public