#help-development

1 messages · Page 276 of 1

gilded knot
#

Not inside Project Structure

#

as I said

#

go here

#

click here

#

It's under BuildTools

#

I'm using Maven rn so I can't show you

#

go into InteilJ Preferences

#

Select Gradle

#

you should be able to change it there

#

@frail gale

frail gale
gilded knot
#

Strange

frail gale
#

in the site there's something for a gradle-properties file but I don't where I'll need to put this file

gilded knot
#

No idea

#

You'll have to ask somewhere else Im afraid

frail gale
#

that's why I hate Gradle

gilded knot
frail gale
#

Thanks I'll ask right now

gilded knot
#

Tried my best ¯_(ツ)_/¯

frail gale
#

bruh I'll need to wait 10 minutes

#

I still have nightmares when I was setting the Gradle in my Forge mod

gilded knot
#

Rip

frail gale
gilded knot
#

😂

frail gale
#

also I saw you're using Mac

gilded knot
#

Yup

frail gale
#

I have Notepad-- on my Mac xD

gilded knot
#

sucks sometimes

gilded knot
frail gale
#

yes haha

gilded knot
#

Use VScode or Atom

frail gale
#

I have VSCode but I don't use

#

it

gilded knot
#

fair

frail gale
#

My macOS is Hackintosh

gilded knot
#

I use normal mac

#

¯_(ツ)_/¯

frail gale
#

I have IntelliJ Idea on my Windows and on my Mac

tardy delta
#

imagine not using linux

gilded knot
#

I have a linux VPS

#

and an ubuntu VM lol

frail gale
#

But I have been thinking on triple booting my computer

tardy delta
#

triple booting lol

gilded knot
#

I have Windows, MacOS and Ubuntu on my computer

#

lol

hardy garnet
#

What version of registerNewObjective is not depreciated? I am using the one that seems to not be depreciated in the docs, but I am still being told its depreciated

tender shard
keen basin
tardy delta
#

start from the chunk youre standing in

#

World#getChunk ig

echo basalt
#

Pretty sure that's just the chunks around your own

tardy delta
#

bruh moment

echo basalt
#

You can't use fn because the || would never cast it

tardy delta
#

ye ik

#

me going from a recursive design to a loop

#

im already regretting

#

scope is also sad

tender shard
tender shard
subtle folio
tender shard
#

because "instanceof" could be false, but the second term could be true

keen basin
tender shard
#

so you cannot be sure that "crawl" is instanceof FunctionNode

tender shard
keen basin
#

yes

tender shard
#

You could easily calculate that with some tiny math

chrome beacon
#

Just loop a 1 chunk radius around the player

subtle folio
#

get all blocks in a 32x32 area, no?

tender shard
#

exactly

#

getChunk().getX()-1

#

then +1

#

and same for Z

#

then turn it into a boundingbox

keen basin
#

Ok thanks, I will try to do it

mighty pier
#

?runnables

#

i need runnables

#

give

#

ktxh

tender shard
#

`scheduling

#

?scheduling

undone axleBOT
mighty pier
#

ty

tender shard
#

@mighty pier

quaint mantle
#

Can anyone help me with POM?

chrome beacon
#

?ask

undone axleBOT
#

If you have a question, please just ask it. Don't look for staff or topic experts. Don't ask to ask or ask if people are awake or available. Just ask the question to the channel straight out, and wait patiently for a reply. Make sure you use the right channel regarding the topic of your question. Create a thread in case the channel is already in use!

gilded knot
#

math isn't mathing

mighty pier
#

update intellij

gilded knot
#

aight

#

but wait

#

how would that fix the issue

lilac dagger
#

this drives me crazy, not sure how the other guy sees himself as invisible

#

is this packet sent to multiple players via sendPacket?

#

cause i'm out of things

gilded knot
#

Moment of truth

chrome beacon
mighty pier
#

im ashamed

lilac dagger
#

i'm working on it lol @mighty pier

mighty pier
#

nothing to work on

lilac dagger
#

it's fine

mighty pier
#

no

#

its not

lilac dagger
#

if you wanna have multiple methods for doing this go ahead

mighty pier
#

?

gilded knot
midnight shore
#

how the heck is this possible?

daring lark
#

is there any way to serialize itemstack into byte array?

gilded knot
gilded knot
# gilded knot

For some reason it's not catching the exception though

midnight shore
tardy delta
#

is there a TeamColor.RED?

gilded knot
#

Yes

gilded knot
#

Which I did on purpose

tardy delta
#

did you enter RE or RED

gilded knot
gilded knot
#

Instead of it spitting an error, It's meant to say Invalid team specified

midnight shore
tardy delta
#

why are you doing unnessecary stuff?

midnight shore
#

valueOf() takes the exact id not abbreviations

gilded knot
#

Nvm found out the error anyway

tardy delta
#

looks like tabcompletion

gilded knot
midnight shore
gilded knot
#

the assignTeam() was originally embedded inside the command

#

but instead I want to make it as a public method

#

so when the gamemode starts

#

it will check if any players do not currently have a team

#

and if they don't, assign them a random one

#

which I have written here

gilded knot
#

Soz, I'm a little stupid sometimes

#

and my Main class is clustered

#

I'm trying to split everything into different classes

#
public PacketPlayOutEntityDestroy(int var0) {
    this.a = var0;
}
#

hm

midnight shore
#

it says that the constructor is wrong while its actually as true as it could be

gilded knot
#

Right

#

No idea, It puzzles me too

midnight shore
#

whats wrong here?

chrome beacon
#

The artifact id

#

It should be spigot

midnight shore
#

i fixed it

#

ty all

onyx fjord
#

I think i did an oopsie when setting up NMS

I get shit like java.lang.NoClassDefFoundError: net/minecraft/network/chat/Component

#

what mightve went wrong?

glossy venture
#

if you use maven use specialsource

onyx fjord
#

im on gradle

glossy venture
#

if you use gradle move to paperweight userdev

glossy venture
onyx fjord
#

ah okay

#

thanks

daring elm
#

@chrome beacon i have now the host announced with the virus, i hope. this server will removed from system 🙂

young belfry
#

PLEASE SOME HELP ME. IM STUCK FOR THIS

gilded knot
gilded knot
eternal oxide
#

read the error

gilded knot
#

ah nvm, I can only run teleport on the main thread

#

got it

#
Bukkit.getScheduler().runTask(plugin, new Runnable() {
        public void run() {
            player.teleport(location);
        }
    });
tardy delta
#

why new runnable and not a lambda

gilded knot
#

hm

tardy delta
#

thats not an answer

gilded knot
#

fair enough

gilded knot
#

thanks :P

#

Right

#

Small issue

#

I get teleported to the correct world, wrong coordinates

#

Output:

humble tulip
#

Lol

gilded knot
#

yes.

humble tulip
#

You're probably reading the config wrong

gilded knot
humble tulip
#

Oh

#

Those are strings

#

Not numbers

sonic goblet
#

those arent doubles, it looks like you''re storing them as strings

humble tulip
#

Remove the ""

gilded knot
#

OH

#

shit

#

right

#

Thanks

#

small typo then

#

Thanks

#

Didn't realise that

tardy delta
#

ig TeamManager#hasTeam and #getTeam are both checking a map?

daring elm
#

Any known better plugin /sethome, warps. i hate Essentials xD

gilded knot
#

I'll simplify the plugin before releasing

#

for the time being I'm doing deadass basic things

#

check if player has team

#

if yes

#

get players' team

tardy delta
#

just call getTeam null check it and decide

gilded knot
#

aight

tardy delta
#

its calling get twice internally now

sterile token
gilded knot
#

and I want to just simply add it in the config

#

Also

#

Each map has a different spawn

sterile token
#

Smth like:

Words: # Section name
  world-1: # Key 1
    x: -100
    y: 20
    z: 100
  world-2: # Key 2
    x: 100
    y: 20
    z: -100
gilded knot
#

Ohhh you mean like that

#

I mean yeah I could

#

I have nothing else in my config so I don't need to, but in future I definitely will

sterile token
#

So then you can just get the section "Worlds", loop over each key

#

You can also, make a custom object for them, using ConfigurationSerializable

gilded knot
#

Hm

#

strange

#

still teleports me to 0 0 0

humble tulip
#

Send the config

#

Well a pic

gilded knot
#
# Maps:
Canyon:
  RedSpawn: # 242 75 -100
    X: 242
    Y: 75
    Z: -100
  YellowSpawn:
    X: 0
    Y: 64
    Z: 0
  GreenSpawn:
    X: 0
    Y: 64
    Z: 0
  BlueSpawn:
    X: 0
    Y: 64
    Z: 0

#

I've joined Red Team

#

Attempts to teleport me

humble tulip
#

Print SelectedWorld

gilded knot
#

aight

#

Wait

#

No

#

I'm certain it selectedWorld is correct

humble tulip
#

You're making an anni plugin?

gilded knot
#

It teleports me to the correct world

gilded knot
humble tulip
#

Haha

gilded knot
gilded knot
humble tulip
#

I worked on an anni plugin on my first server

#

Well just made updates

gilded knot
#

It's not that hard in theory though, is it?

humble tulip
#

Nope

gilded knot
#

Load world

humble tulip
#

Minigames aren't hard

gilded knot
#

create teams

#

yeah

#

For me it is, since I'm a beginner xD

humble tulip
#

What's hard is creating a configurable minigame

gilded knot
#

Yup

humble tulip
#

Not hard but tedious

cosmic light
#

Hey, how can i create a Book, that isn't signed but has text prewritten in it?

humble tulip
#

Since you need to make sure the user doesn't do anything stupid

gilded knot
#

welp thank god im not releasing this plugin to the public

#

💀

humble tulip
gilded knot
#

I'll print out the coordinates

humble tulip
#

Also ever played guildcraft anni?

gilded knot
gilded knot
#

It was such a fun gamemode

#

thought I'd recreate it and put it on my own server

humble tulip
#

How profitable is a mc server

gilded knot
#

An old server I developed on earned 1000$ in 1 month

#

It's not really profitable ig, but it's a decent side-hustle if you have the skills already

humble tulip
#

You currently have a server?

gilded knot
#

In the midst of making one

#

The old one I worked in shutdown due to staff inactivity and the owner having a busy life

#

Recently I've revisited the idea

#

got a VPS from Oracle for free, 24GB RAM and 4 Cores

#

thought why not do it again

#

¯_(ツ)_/¯

gilded knot
#

As of now, Im making a Towny && Anni server

gilded knot
#

It's not a scam

#

I'll show you wait

keen basin
#

guys how can i sort string like this
max,john,jack,emily
to array String like this
max
john
jack
emily

gilded knot
tardy delta
#

buy a pi

#

and run ubuntu server on it

gilded knot
gilded knot
#

I'd imagine you'd do something like array.split(",")

keen basin
tardy delta
#

Arrays.stream(input.split("/s*,/s*")).collect(Collectors.joinin("\n")) or smth

onyx fjord
#

is anyone aware why IJ doesnt respect org.gradle.jvmargs of gradle?

#

it just fills my entire ram

humble tulip
#

Code delet

gilded knot
#

Ah

gilded knot
#

Outputs this

#

right.

#

ill try this

tardy delta
gilded knot
#

still no

#

what the fuck?

humble tulip
#

Did you print selectedworld?

gilded knot
#

As I said, it was Canyon

#

It was correct since it teleports me to the right world

#

I'll try it anyway

humble tulip
#

Aaaaannnnnnd?

gilded knot
#

aight its loading

#

1 sec

#

countdown heh lol

verbal copper
#

How can i get all item icons as png as they appear in the gui?
Including blocks.

gilded knot
tardy delta
#

i believe its client sided and you cant

gilded knot
tardy delta
#

bruh

gilded knot
tardy delta
#

use the scheduler to delay a task

#

#runTaskLater

gilded knot
#

¯_(ツ)_/¯

#

That's not my primary issue

gilded knot
humble tulip
#

?paste your code

undone axleBOT
humble tulip
#

Lemme see it all

gilded knot
#

kk

#

Sorry if it's a mess

#

Im in the middle of splitting it into classes

tardy delta
#

oh god

#

dont do threading stuff if you dont know what youre doing

gilded knot
#

bruh

rotund ravine
#

@gilded knot Don’t get the config values before onEnable

gilded knot
#

ah

chrome beacon
#

package names should be lowercase

#

?conventions

gilded knot
tardy delta
#

and use a logger instead of the consolesender

gilded knot
tardy delta
#

mismatched api/ server version?

rotund ravine
#

Update the x,y,z each time you choos ea new world @gilded knot

rotund ravine
#

I’ve seen wrose

gilded knot
#

I'm a great example

#

Yup, works

humble tulip
#

@gilded knot that's gonna get very messy very fast

gilded knot
humble tulip
gilded knot
#

works 👌

humble tulip
#

Problem was loading the x, y, z outside any methods

gilded knot
#

before the plugin was enabled

humble tulip
#

Meaning it loaded it as the plugin instance was constructed

gilded knot
#

mhm

iron glade
#

What would be the easiest way to detect if the server version my plugin is running on is > 1.18.3 ?

#

So 1.19 and above

humble tulip
#

Here's how i do it

#

Oh wait

tardy delta
#

some string splitting and parsing

humble tulip
#

public static final int MC_VERSION = Integer.parseInt(Bukkit.getServer().getClass().getPackage().getName().split("\.")[3].split("_")[1]);

#

Check if MC_VERSION is >= 19

iron glade
#

thanks!

humble tulip
#

That's just for the major version not the minor

iron glade
#

Yeah that's fine, I only need to know if it's at least 1.19

onyx fjord
#

smh now i get java.lang.NoClassDefFoundError: org/bukkit/craftbukkit/v1_19_R2/entity/CraftPlayer

#

oh shit

#

nvm im on 1.19.2 😂

heady iris
#

how do I fix the Cannot get plugin for class from a static initializer error?

dusk flicker
#

holy shit

#

use a paste

#

?paste

undone axleBOT
heady iris
humble tulip
#

Just use this

#

Are you in the main class

heady iris
#

yes

humble tulip
#

Just use the keyword this

#

you shouldn't be doing stuff outside onLoad or onEnable in your main class

chrome beacon
#

attack, right-click, right-click at block I assume

#

interact could also be left click

gilded knot
#

How do I get the dropped items after a Blockbreak event

#

Like if a user breaks an iron ore

#

How would I get the iron ore entity

river oracle
#

afaik you can't, if you want to edit the drop you need to do BlockBreakEvent#getBlock#getDrops(ItemStack item)

#

the itemstack pass through keeps fortune and other modifiers

gilded knot
#

this is what I have(in theory)

river oracle
#

than you'd need to cancel the actual drop and drop your modified version

#

you can do this with
World#dropItemNaturally

gilded knot
#

Wait

#

does it keep fortune into consideration

river oracle
#

yes

#

if you pass in the itemstack

#

otherwise no

gilded knot
#

so the itemstack would be the tool the player used?

river oracle
#

yes

#

I think he wants dropped items from block break? I'm assuming

#

can you get a cause with BlockDropItem Event?

#

Its always pretty accurate for me

#

it does a good job taking into account fortune etc

#

then NMS is the other option :P for editing block drops

manic furnace
#

Im reading data from a zipfile in to ways, while one works and the other doesn't but I dont know why:
1(doesnt work): ```java
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream("./file.zip")));
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
ZipEntry zipEntry = null;
while ((zipEntry=zis.getNextEntry()) != null){
byte[] buffer = new byte[1024];
for (int read = 0; (read = zis.read(buffer, 0, buffer.length)) > 0;){
bOut.write(buffer, 0, buffer.length);
}
zis.closeEntry();
System.out.println(bOut.toString(StandardCharsets.UTF_8));
}
zis.close();

2(works): ```java
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream("./file.zip")));
        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        ZipEntry zipEntry = null;
        while ((zipEntry=zis.getNextEntry()) != null){
            byte[] buffer = new byte[1024];
            for (int read = 0; (read = zis.read(buffer, 0, buffer.length)) > 0;){
                bOut.write(buffer, 0, read);
            }
            zis.closeEntry();
            System.out.println(bOut.toString(StandardCharsets.UTF_8));
        }
        zis.close();

I use the actual read length in the 2. one, but that shouldnt affect it. I also tried just using Strings, but completely messes up everything. I think that there is a problem with the length, but I dont know why

river oracle
#

or you could reimplment fortune yourself

#

with silk touch etc than do the calculations yourself

#

I think the bukkit method does a good job and save a lot of time

gilded knot
#

Right

#

so this

#

basically

river oracle
#

^

gilded knot
#

Aight

#

got it

#

Wait how do I get the ItemStack

#

I assume I just make another ItemStack

river oracle
#

getDrops returns a collection

gilded knot
#

getMetaData

#

Right

#

It's only specific block types with guaranteed drops

humble tulip
#

@gilded knot

gilded knot
#

aight

#

cheerio

#

Yep that's much better

daring lark
#
        NamespacedKey dataKey = new NamespacedKey(plugin, "backpackData");
        Player player = (Player) event.getPlayer();
        ItemStack hand = player.getInventory().getItemInMainHand();

        if(hand.getType() == Material.AIR) {
            return;
        }

        String id = hand.getItemMeta().getPersistentDataContainer().get(dataKey, PersistentDataType.STRING);

        if(id == null) {
            return;
        }

        plugin.getBackpackManager().saveBackpackData(id, event.getInventory().getContents());
        log(event.getInventory().getContents());
        log("Zapisano");
    }```
daring lark
hazy parrot
#

What is line 36

daring lark
#

log(event.getInventory().getContents());

#

i'm checking stuff

#

why contnet of my closed inventory is null?

hazy parrot
#

getsContents is null ig

tall dragon
#

does any1 here know how i can hide a players nametag only to specific players in a way that does not stop me from using the "ghost" functionality from scoreboard teams

#

probably gonna have to be with packets somehow

hazy parrot
daring lark
#
        if(backpackData.getConfig().get(id) == null) {
            return new ItemStack[0];
        }
        return ((ArrayList<ItemStack>) backpackData.getConfig().get(id)).toArray(new ItemStack[0]);
    }```
So now here's the next one
#
        at me.placek.backpacks.backpack.BackpackManager.getBackpackData(BackpackManager.java:35) ~[backpacks.jar:?]
        at me.placek.backpacks.listener.PlayerInteractListener.onEvent(PlayerInteractListener.java:45) ~[backpacks.jar:?]
        at com.destroystokyo.paper.event.executor.MethodHandleEventExecutor.execute(MethodHandleEventExecutor.java:37) ~[paper-api-1.19.2-R0.1-SNAPSHOT.jar:?]
        at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:80) ~[paper-api-1.19.2-R0.1-SNAPSHOT.jar:git-Paper-260]```
How can i get list of itemStacks?
hazy parrot
#

?whereami

daring lark
#
- null
- ==: org.bukkit.inventory.ItemStack
  v: 3120
  type: SPRUCE_LEAVES
- null
- null
- null
- null
- null
- null
- null```

is this an itemStack or list?
#

so...

#

and that's good

hazy parrot
#

Google about spigot serialization

#

And see how to get custom serialization from config

daring lark
#

i literally just did that

hazy parrot
daring lark
#

so how could i do that thing?

tardy delta
#

Collections.emptyList() if you dont intend to mutate it

daring lark
#

guys...

#

Thank you all for helping me

#

Thank you very much. You all changed my life prespecitve

#

?

hazy parrot
#

Trough you are serb nvm

tardy delta
#

or save it async and lock it

#

Map<UUID, ItemStack[]> tho

#

this whole code smells like the whole codedred tutorial i once did

rotund ravine
#

What about crashes 😬 /s

tardy delta
#

wondering if the os actually synchronizes write access to a file

rotund ravine
#

It’s sarcastic

buoyant viper
#

tone indicators

rotund ravine
#

I’ve used /s and jk

tall dragon
#

are there any tools that can be used to inspect packets that clients receive?

rotund ravine
#

Protocollib comes to mind

tall dragon
#

kinda want something that displays packets as the client is processing them

#

cuz im not sure its receiving packets im sending

humble tulip
#

Get a mod

tall dragon
#

ya. which 😄

humble tulip
#

Are you sure you're sending it in thebright format?

humble tulip
#

Client might ignore bad packets

tall dragon
#

i mean im using protocol lib plus a wrapper class for that packet

humble tulip
#

What packet are you sending?

tall dragon
#

PacketType.Play.Server.SCOREBOARD_TEAM

gleaming grove
rotund ravine
tall dragon
#

but had no luck in the last 6 hours of trying -.-

humble tulip
#

Heres what to do

#

Do it with spigot

tardy delta
humble tulip
#

Then intercept the packet

#

And see what's normal

#

And how the packet is supposed to look

#

Understand @tall dragon ?

tall dragon
#

yea kinda let me go try that.

gleaming grove
# gleaming grove I've seen a video long time ago where guy make some kind of proxy in netty so he...

https://youtu.be/zDj3IBaIY7w this is the video i talk about but propably minecrsft-packet-debbuger would be better

● Visit my website: http://www.CosmosMC.net
● Join my server: playmc.cc

● Checkout Netty here: http://netty.io/
● Netty Examples and Documentation: https://github.com/netty/netty
● Download the code here: https://github.com/sgtcaze/Tutorial/blob/master/Resources/PacketAccessor.java

Connect with my social media:
● Twitter: http://www.twitter.co...

▶ Play video
humble tulip
# tall dragon yea kinda let me go try that.

Basically to figure what the the packet is supposed to look like. Eg. Lets say you wanna see how to remove an entity for a single player only but don't know what the packet is supposed to look like, what you can do is call entity.remove() using spigot and listen for the packet to remove entities being sent to players and look at how they're written

tall dragon
#

right.

gilded knot
#

Question

#

do I need the try catch here?

#

Just in-case the player leaves or smth

buoyant viper
#

well, does anything happen that would throw an exception?

gilded knot
#

player does not exist

#

?

#

Like the server gets the map full of players

#

1 of them decides to leave

gilded knot
buoyant viper
#

not unless u try to access a field or method from Player id imagine

#

just the player object itself shouldnt cause an issue

#

but if somewhere in removePlayer u did like player.doSomething() then yes

#

wait

#

no

gilded knot
#

hm?

buoyant viper
#

im thinking if u literally passed null or if Player was null lolnvm

gilded knot
#

ah aight

buoyant viper
#

nothing should happen

gilded knot
#

kk dope

#

lmao removePlayer(null)

#

addPlayer(null) :woah:

buoyant viper
#

there is only one true test method though

#

?tryitandsee

#

:(

gilded knot
#

mhm

buoyant viper
#

there we go

tall dragon
#

one weird thing is that the packet specifies that its for mc version 1.18

#

which i am not running

humble tulip
tall dragon
#

yes

ancient plank
#

And they put the <> around it so it doesn't embed

cedar token
#

java.util.ConcurrentModificationException: null
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1597) ~[?:?]
at java.util.HashMap$KeyIterator.next(HashMap.java:1620) ~[?:?]
at net.minecraft.nbt.NBTTagCompound.a(SourceFile:163) ~[spigot-1.18.2-R0.1-SNAPSHOT.jar:3498-Spigot-b081915-10ba1be]
at net.minecraft.nbt.NBTCompressedStreamTools.a(NBTCompressedStreamTools.java:280) ~[spigot-1.18.2-R0.1-SNAPSHOT.jar:3498-Spigot-b081915-10ba1be]
at net.minecraft.nbt.NBTCompressedStreamTools.a(NBTCompressedStreamTools.java:248) ~[spigot-1.18.2-R0.1-SNAPSHOT.jar:3498-Spigot-b081915-10ba1be]
at net.minecraft.world.level.chunk.storage.RegionFileCache.a(RegionFileCache.java:141) ~[spigot-1.18.2-R0.1-SNAPSHOT.jar:3498-Spigot-b081915-10ba1be]
at net.minecraft.world.level.chunk.storage.IOWorker.a(SourceFile:174) ~[spigot-1.18.2-R0.1-SNAPSHOT.jar:3498-Spigot-b081915-10ba1be]
at net.minecraft.world.level.chunk.storage.IOWorker.a(SourceFile:164) ~[spigot-1.18.2-R0.1-SNAPSHOT.jar:3498-Spigot-b081915-10ba1be]
at net.minecraft.util.thread.PairedQueue$b.run(SourceFile:59) [spigot-1.18.2-R0.1-SNAPSHOT.jar:3498-Spigot-b081915-10ba1be]
at net.minecraft.util.thread.ThreadedMailbox.h(SourceFile:91) [spigot-1.18.2-R0.1-SNAPSHOT.jar:3498-Spigot-b081915-10ba1be]
at net.minecraft.util.thread.ThreadedMailbox.a(SourceFile:146) [spigot-1.18.2-R0.1-SNAPSHOT.jar:3498-Spigot-b081915-10ba1be]
at net.minecraft.util.thread.ThreadedMailbox.run(SourceFile:102) [spigot-1.18.2-R0.1-SNAPSHOT.jar:3498-Spigot-b081915-10ba1be]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [?:?]
at java.lang.Thread.run(Thread.java:833) [?:?]
[00:21:08] [Server thread/WARN]: Can't keep up! Is the server overloaded? Running 6219ms or 124 ticks behind
[00:22:13] [Server thread/WARN]: Can't keep up! Is the server overloaded? Running 5544ms or 110 tick

ancient plank
#

?paste

undone axleBOT
hazy parrot
humble tulip
hazy parrot
cedar token
humble tulip
#

@tall dragon 1.8?

hazy parrot
#

i literally can't explain better then i already did

humble tulip
#

I'll help u ina bit

hazy parrot
#

use some translator

tall dragon
hazy parrot
cedar token
hazy parrot
#

either use iterator or Map#removeIf

tall dragon
#

yea @humble tulip its defo receiving my packet now. but its still not acting how i want it to

#

right now the other client just turns the name white

#

instead of not displaying it

quiet ice
#

But in this case, I don't think any of the solutions apply

heady iris
#

how do I fix the Cannot get plugin for class ____ from a static initializer error?

humble tulip
#

@tall dragon lemme see ur code

heady iris
#

it didn't work

humble tulip
#

Let me see what you changed

#

?paste

undone axleBOT
humble tulip
#

I'm not downloading your file

heady iris
#

Collection<ItemStack> drops = this.populateLoot(new Random(), lootContext); you said change PaperLuck to this

#

also this button exists

humble tulip
#

I'm on mobile

#

1 sec

tall dragon
humble tulip
#

Hopping on pc

#

Dm me

tardy delta
humble tulip
#

don't do private fine Plugin plugin = getPlugin(PaperLuck.class)

#

Final

heady iris
# tardy delta

this time i uploaded it as a file so it didnt take up the whole screen

tall dragon
#

but i have noticed something is wrong @humble tulip
in the packet sent by the server the nametagvisibility was stored in field "e" while in mine its stored in field "b"

#

thats probably the issue

#

the wrapper class i got probably not for the right version or something

humble tulip
#

Don't use protocollib then

#

Construct the oacket yourself

tall dragon
#

yea im going to try that

humble tulip
#

@heady iris send the entire class

heady iris
humble tulip
tall dragon
#

@humble tulip omg it works

humble tulip
#

👍 great 🙂

tall dragon
#

now i only need to figure out a way to cleanly revert it.

humble tulip
#

Same process

#

Revert with spigot and see how the packet looks

tall dragon
#

if i were to use the spigot api to re-set the player's team woulnt i just sent the correct packet to change it back?

humble tulip
#

Just change the visibility to always

#

Not necessarily

#

It might try to be efficient by checking if the visibility is the same as what you're trying to to set it to and then do nothing

tall dragon
#

na i mean just re-adding the player to the scoreboard team

humble tulip
#

Ah yh that works

#

Packets are cleaner tho

vocal cloud
#

Inb4 md_5 shows up to complain about people not using the scoreboard API

tall dragon
#

yea unfortunately the scoreboard api is equal to hot garbage

jagged monolith
#

Well he isn't wrong. You don't need packets with scoreboards. Anything the packets can do, the api can do

tall dragon
#

ur capping

#

tell me how to show ghost of invisable players and at the same time hide name tags of opposing players only when they are invisable.

rotund ravine
#

?contribute

rotund ravine
#

Implement it in the API then

chrome beacon
rotund ravine
#

As md5 has said, if the API is missing something try to suggest it instead of using nms and packets.

chrome beacon
#

You set the teams

tall dragon
#

if i change the nametag visibility it would change it for everyone in the team

chrome beacon
#

I believe teams are bound to the scoreboard

#

So you create a new scoreboard for that player and change the teams

#

?jd-s Let me check that real quick

undone axleBOT
tall dragon
#

then that player wont be able to see the ghost of invisable teammates

#

as the player can only be part of one team

chrome beacon
#

You can have per player scoreboards that contain per player teams

tall dragon
#

same issue

chrome beacon
#

That's effectivly doing the same as packets

tall dragon
#

nah cuz the players will all have their own team then

chrome beacon
#

You can do that with the api

tall dragon
chrome beacon
#

No

#

If that would cause the issue then packets won't work either

#

Since the api would use the exact same packets in the same way

tall dragon
#

ofc packets would work

#

i just dont send the packet to his team mates

chrome beacon
#

Yeah with different scoreboards per player you can target a specific players visible teams

#

Just like raw packets do

#

Different players can see diferent teams by being on different scoreboards

#

By see I mean the information sent to the client

tall dragon
#

i mean i tried having a scoreboard per player and was never able to see invisable people

chrome beacon
#

Which is the same as the raw packets would do

#

You're going to need to set everyones team in every scoreboard

tall dragon
#

and then players can just suddenly see invisable people that are not in their team?

chrome beacon
#

You can make them look like they're in the same team while dead just like you would with packets

tall dragon
#

ye thats the part i dont understand then

#

how

chrome beacon
#

All you would have to do is grab the dead players scoreboard and set the teams of every dead player to the same one

#

I'll get some sleep now. Hopefully you can figure it out. If not I can help tomorrow

tall dragon
#

it shoulnt happen when players are dead tho. i have 4 teams and those 4 teams should be able to see their allies in invisibility at all times

#

alright

humble stirrup
#

does pdc have a way to store string arrays?

tall dragon
#

not by default

river oracle
#

Natively? I'm not sure, but you can add your own types

tall dragon
river oracle
#

Alex!!!!

humble stirrup
#

oh cool thanks

fading spindle
humble tulip
#

dont open an inventory on inventory close event

#

either cancel the event or open the inv 1 tick later

fading spindle
#

oh ok

#

but why shouldn't i repoen it

humble tulip
#

inventroycloseevent is called before the inventroy is closed

fading spindle
#

ohh ok but for some reason i cant seem to cancel the evnt

humble tulip
#

ah it's not cancellable

fading spindle
#

ok so i should just open it 1 tick later

humble tulip
#

well just wait 1 tick and open it back

#

yea

fading spindle
#

ok so i haven't gotten into timing and stuff so how would i do that

humble tulip
#

?scheduling

undone axleBOT
fading spindle
#

using wait()

humble tulip
#

nope

fading spindle
#

okay thanks

#

i'l; check the link

sterile token
humble tulip
#

@sterile token did you do what i told in dms?

sterile token
#

The message is print tho

#

Are you already on pc bro?

humble tulip
#

I am

#

well then the last line is your issue

sterile token
#

ok

#

I debug everything

#

I want to only be able to use the off hand:

  1. build: false, member: true, permission: false
  2. build: true, member: true, permission: true
  3. build: false, member: true, permission: true
humble tulip
#

those are the three casees?

sterile token
#

Other posibilities must be cancelled

#

Yeah

#

permission, why? because if you have the region bypass, you can do whatever you want

#

Pleae let me know

#

I have to leave in less than 5m

humble tulip
#

if (member || permission)

#

build doesnt seem to matter?

sterile token
#

it matter

humble tulip
#

not in the 3 cases above

#

so if build : true, member: true, permission: false
what happens

sterile token
#

I mean wait:

If you have the build: true OR permission: true AND member: true

humble tulip
sterile token
#

oh ok

#

Yeah because you cant use OFF HAND unless you are not in the mode or have bypass permission

humble tulip
#

if (member && (build || permission)) return;

sterile token
#

ok

#

I wil ltest

sterile token
humble tulip
#

no

#

setcancelled(!(member && (build || permission)));

hot panther
#

Hi guys, I have given a chunk and now I want to get the coordinates of this chunk (Or the coordinates of a block in this chunk).
How to do this?

vocal cloud
#

?jd-s docs have that info. Or at least they should

undone axleBOT
narrow sphinx
#

@EventHandler
public void onClose(InventoryCloseEvent e) {

    if (!e.getInventory().equals(BedwarsStorage.pmenustorage.get(e.getPlayer()))) return;
            
    e.getPlayer().openInventory(BedwarsStorage.pmenustorage.get(e.getPlayer()));
}

Using this listener to cancel closing an inventory, it works once and then both of the listeners I'm using don't work after reopening the inventory. The inventory initially opened is the same one opened here (BedwarsStorage.pmenustorage.get(e.getPlayer())). It's from a <Player, Inventory> Hashmap

jagged monolith
#

?paste

undone axleBOT
narrow sphinx
tender shard
#

this will always open a new inventory

#

is it about the player's inventory?

#

or some custom GUI?

narrow sphinx
#

It’s a GUI, a command creates an inventory and stores it in a hashmap with the player as the key, and this gets that inventory with using the player from the InventoryClosEvent

tender shard
#

well then obviously your hashmap does not contain this gui inv

hazy parrot
#

Anyone knows how can i have multiline output in github workflow ?

#

I tried

      - name: Generate SHA checksum
        id: checksum
        run: | # EOF not working as delimiter
          cd target/
          CHECKSUM=`sha256sum File.jar`
          echo $CHECKSUM > ../checksum.txt
          echo "checksum<<EOF" >> $GITHUB_OUTPUT
          echo "### SHA256 checksum" >> $GITHUB_OUTPUT
          echo "`\`\`\" >> $GITHUB_OUTPUT
          echo "$CHECKSUM" >> $GITHUB_OUTPUT
          echo "`\`\`\" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

But it just throws Invalid value. Matching delimiter not found 'EOF'

tender shard
undone axleBOT
tender shard
#

oh and please use $(...) instead of ```
...

hazy parrot
tender shard
hazy parrot
#

nop, still doesn't look right

tender shard
# hazy parrot

can you print out the contents of the script you generated?

hazy parrot
#

What script ?

tender shard
#

the thing that the "run: " thing generates

#

I don't know how github actions work, but I'm pretty sure that it saves the whole thing as a script inside /tmp of sth

hazy parrot
tender shard
#

what are the "quotes" for?

hazy parrot
#

escaping \ ig

tender shard
#

yeah but I mean

#

erm

#

how do I say this in english lmao

hazy parrot
#

oh

#

no

tender shard
#

do you just wanna print the checksum?

hazy parrot
#

\ is for escaping "`"

tender shard
#

yeah but what are you going to do with $CHECKSUM?

hazy parrot
#

it like

checksum
#

i want that

tender shard
#

aren't you trying to print it?

hazy parrot
#

no, im trying to put it in release notes

tender shard
#

if so you should do

echo $CHECKSUM
hazy parrot
#

that is why im trying to do markdown format

tender shard
#

aren't you missing an "echo" or "print" statement then?

#

for example:

#
echo "asd"

this would print "asd".
This however:

"asd"

would try to execute "asd"

#

you obviously don't wanna "execute" the checksum, but simply print it out, right?

#

do you got a link to your repo, so I could fork it and try myself?

hazy parrot
#
MESSAGE=$(cat << EOF
          ### SHA256 checksum
          `\`\`\
          $CHECKSUM
          `\`\`\
          EOF
          )

i want this, to simply put something like this inside of MESSAGE var

#

this is my other repo, but every release i manually add new lines

#

so i want to "fix" it

#

😄

tender shard
#

oh I see

#

okay just for fun - try to put this whole thing into one line

hazy parrot
tender shard
#

I never used github actions before

hazy parrot
#

just push tag that starts with v

#

on some commit

#

v1.0.0

#

for example

tender shard
#

okay so I just fork it, and then push a change with commit message "v1.2.3" (or similar) right?

hazy parrot
#

no, not commit message

#

but tag

tender shard
#

uuuugh

#

but git itself doesn't have any tags? :X

hazy parrot
#

its git push origin tag iirc

tender shard
#

aaaaah so it's just a new branch

hazy parrot
#

probably 😄

tender shard
#

okay idk sorry I have no clue how to help you with this lmao

tender shard
#

does it work now?

tender shard
#

this way we can check what exactly the problem is

hazy parrot
#

i hate bash mutiline smh

dry yacht
#

Do you guys know what the latest solution to serializing a bukkit ItemStack is? Years ago we just wrote the bytes a BukkitObjectOutputStream yielded as base64, but that cannot possibly be the best solution. Any other ideas?

tender shard
#

weird

#

anyway, so you got the full thing working now?

tender shard
#

a string?

hazy parrot
tender shard
#

usually I just ask for ?pastes here haha

hazy parrot
#

yeah, thanks alex 😛

dry yacht
# tender shard serializing to what?

Well, to be concrete, let's just say serializing into a database. A relational type would be preferred, as I could of course just dump some JSON into a document oriented DB.

#

Looks like the only truly version independent way will be to store the NBT value. I think the BukkitObjectOutputStream may break when changing the server version.

remote swallow
#

if your storing it in json you could technically follow the serialisation format

dry yacht
torn shuttle
#

has anyone made a guide to updating resource packs to the 1.19.3 format?

buoyant viper
#

isnt it just the usual change the version to 1.19.3s pack format version and maybe redo Vex since it has a new model

tender shard
#

it turns any ItemStack into a byte[]

remote swallow
tender shard
#

e.g. when I want it to be base64 or sth

#

but in 99 % of cases, you don't need/don't want base64

dry yacht
# tender shard then what's wrong with the builtin serialize() method?

I feel like it could break when you got items of an older version and try to feed the byte[] to the API of a newer version. I think I should actually try that. I'd just like to have a failsafe way of reading and storing items, no need to crash if the ItemStack ever gets new properties or some properties aren't available at the current version.

dry yacht
vital sandal
#

How about jsonfy it

#

json is pretty solid to storing datas

#

Or if you want to optimize at memory encoded it with rawdata

dry yacht
# vital sandal How about jsonfy it

Yeah, right, but that only delegates the issue. I still need a reader (which converts all NBT to JSON) and a writer, that converts JSON to the NBT tree. I do not want to rely on sketchy NMS invocations for that, like the #toString(). It jsonifys now, but who knows for how long, and if it'll be that way forever.

vital sandal
#

Just write the reader and encoder on your own ?

dry yacht
#

So I guess I'll navigate the NBT tree both ways and use BSON for a blob-like result.

vital sandal
#

Not taking too long for that :d

#

In fact i use it in many of my projects

dry yacht
dry yacht
#

But I do have a pretty nice reflection library sitting around here, I think it's time to make use of it.

vital sandal
#

Using nms make it version independence isnt it ?

river oracle
#

using nms create version dependence

#

just use reflection and interfaces with multiple maven modules

#

and its easy to get stuff done

vital sandal
#

Any docs for it :d

#

Look new

river oracle
#

NMS doesn't have docs

#

maven modules aren't new

#

reflection is basic java

#

here is an example

#

best I can do

vital sandal
#

Hmmm i mean using it for version dependent

river oracle
#

what is your native language?

vital sandal
#

Any what it really do

#

Not english

river oracle
#

ye ye I somewhat speak spanish though

#

which is why I'm wanting to know

#

anyways I'm not quite sure what you mean. If you want version independence with NMS use maven submodules and reflection as in my above example. If you just want one version you don't need to abstract

#

but keep in mind it will only ever work on that version

dry yacht
# vital sandal Using nms make it version independence isnt it ?

Well, actually yes! I bypass all of the ItemMeta-business and access the raw data as mojang stores it in the world too. I got a pretty powerful way of accessing fields, methods and classes through reflections by running predicates and scanning the environment to find something I describe in a builder-type fashion. I guess I'll have that running in no time. I can share my little lib once it's ready, if you want.

vital sandal
#

I have my 1.12.2 working on 1.16.5 server :d

river oracle
#

that is very very very very very very very very unlikely

vital sandal
#

Yeh i think so

river oracle
#

no

#

I doubt that

vital sandal
#

But it work^

river oracle
#

There is no way since the imports are version specific

#

you should be getting ClassDefNotFound errors

#

especially if you use the CraftBukkit classes that interact with NMS

dry yacht
vital sandal
#

For some reason it still working

river oracle
vital sandal
#

Yeh nms^

#

Pure nms

#

That was 1.12.2 plugin for 1.16.5 ^

wet breach
#

Only way to really not encounter errors between versions is only if nothing changed with the class except the version specific import which you can handle easily with reflection. Otherwise you need version specific classes to not encounter problems

river oracle
#

^ this is just a fact so what you claim to have is impossible

dry yacht
# river oracle he is talking about NMS?

I'm not at all sure tbh, as they make it all seem "so easy and quick", while a proper implementation on top of NMS actually takes quite some elbow grease. I think it's not NMS then.

river oracle
#

could just be some API maybe that abstracts the NMS for them?

#

in that case version independence is achievable as the API does the hard work

wet breach
#

Or both

river oracle
#

🤷🏽‍♂️ who knows

wet breach
#

Anyways, have tires to change out lol

#

Be back in like an hour. Have 8 of them to change on a trailer

river oracle
#

I think I'ma read lol I don't feel like coding lowkey. I took 3 days off and really procrastinating getting back into this project

wet breach
#

Lol

river oracle
#

I mean I do want this $65 its just. I got this brand new book

dry yacht
river oracle
#

so I need this little break tbh

tender shard
#

reminds me of sth too

dry yacht
#

I code even more, xD. But I also constantly burn myself out.

river oracle
#

after I finish this commission I'ma take a small break and go work on a personal project

#

I'm going to teach an AI to play minecraft 🥳 so fun

dry yacht
tender shard
#

I need internet hugs

#

someone please send one

dry yacht
river oracle
#

My plan is to make a semi-lightweight client for training sessions and give it protocol to easily interact with

dry yacht
dry yacht
river oracle
river oracle
#

do you love linear algebra though?

#

thats a whole different beast

dry yacht
river oracle
#

🧠 I would never even bother learning math by myself lol thats why I just stick to the libs :P

dry yacht
#

It's basically a huge ass function with weighted nodes which you train on huge amounts of data to brute-force the thousands of unknowns.

dry yacht
river oracle
#

same here

#

I rather not spend my time learning math

dry yacht
# dry yacht I love math, but I also have so many other interests, :-:

Like, I just got this stupid idea of version-independently persist item-stacks, got out my old reflection-lib and got an adrenaline rush from the idea of actually making this work like I imagined it, lol. This has to seem so weird to people who don't write code or love to get lost in the world of logic and abstraction, xD.

river oracle
#

the first bot I'm going to train to survive the first minecraft night lol I wonder how long before it realizes it can just dig a whole it was makes me curious

dry yacht
dry yacht
river oracle
#

truth

#

I love math a ton, my second field of choice is statistics :P

dry yacht
#

oh boi, :,D.

river oracle
#

however, CS is so broad and profitable there is no point

dry yacht
#

I love statistics too, but I really don't miss it, looking back at school. Maybe that's just due to the fact that my teacher really did a poor ass job. They really lost me at the gaussian distribution, until I learned all of that stuff on my own for the exam and actually managed to understand everything we had to know.

dry yacht
river oracle
#

my stats teacher the best way to explain that guy is the Least NPC human on earth. He is so cool and is super passionate about everything he teaches

river oracle
#

such is being in highschool though

terse panther
#

Is there a tool to play the minecraft sounds on specific pitch instead stay changing the pitch and recompiling?

river oracle
#

pitch is between 0 and 1 afaik

terse panther
remote swallow
#

make it a command and add an arg for pitch?

river oracle
#

idk what stay changing and recompiling is

#

sorry

remote swallow
#

or use a command

terse panther
river oracle
#

command you'd have to execute every time the server starts

terse panther
#

Could be better if there exists a tool, but if not, is a good way

river oracle
remote swallow
buoyant viper
river oracle
buoyant viper
#

Wtf i never said csgo just cs

river oracle
#

I suck at video games

buoyant viper
#

i couldve meant CS source for all u knnow

river oracle
#

do people even play other counter strike games

buoyant viper
#

yeah

river oracle
#

ok I got sidetracked I have a book to read

dry yacht
#

Is there actually a BSON lib available for Java which is not already old enough to die soon? lol

#

Seems like they're all inside of this huge mongodb dependency...

#

Maybe I'll use json after all.

forest shuttle
#

Hey, I'm making a custom pathfindergoal for a custom entity, it's basically a modified PathfinderGoalRandomLookaround
I'm getting this problem where one of the methods I need is called "do" which is a keyword, hence I cannot compile the code.
¿What could I do in this case?

remote swallow
#

what is the error on compile

round finch
#

TheDo

#

just better naming

royal monolith
#

Kits Pvp Server minehut

round finch
#

In general

#

Too

forest shuttle
remote swallow
#

?services dont mind this

undone axleBOT
dry yacht
forest shuttle
#

yup, for some reason

#

Maybe should I get it via reflection?

round finch
#

Do.... Sucks : 👏

dry yacht
dry yacht
#

There are proxies, but idk if that could solve the issue.

forest shuttle
#

It is on net.minecraft.world.entity.Entity from Craftbukkit-remapped.
Yeah, for the JVM "do" is a valid method name so no issues when calling it but no way to call if from code.

#

and aw is private 😢

#

I'll try some reflection black magic

dry yacht
forest shuttle
#

pain

dry yacht
#

There has to be a way around this tho...

#

I already googled, didn't find anything useful. Just know how kotlin can easily support escaped identifiers, with keywords and even spaces in em.

forest shuttle
#

maybe with class.forName

dry yacht
#

Well, you want to override this method, so you have to override it at compiletime, or you're in for a ride

forest shuttle
#

No just access it

#

The e() method on pathfinderGoalRandomLookAround needs its value

forest shuttle
#

yes

tender shard
#

use mojang mappings

forest shuttle
#

oh, that should be orders of magnitudes easier than reverse-engineering method names.
haven't seen it before lmao.
ty

dry yacht
forest shuttle
#

it will probably change it back to "do" at compile time when re-obfuscating. Should be able to get past the parser at that point I guess, let's see if the compiler complains.

dry yacht
#

But the JAR had to compile after being patched with bukkit, so they had to make it work too. Are you sure it's called do at runtime? List all fields of this class with reflect and print them out on stdout, just to make sure.

#

all methods*

sullen marlin
#

alex's link is the right answer

hybrid spoke
#

now put a rick roll in it

dry yacht
#

Awesome, got my nbt tree to json tree up and running, xD.

{"display":{"Lore":["hello","world"],"Name":"{\"text\":\"hi\"}"},"Enchantments":[{"lvl":3,"id":"minecraft:sharpness"},{"lvl":1,"id":"minecraft:flame"}]}

remote swallow
eternal oxide
#

we all did, it was needed

tender shard
#

that link is on this discord since months

#

also

#

?switchmappings

modern sluice
#

Is there a way to disable command logging in the console? Every command is logged, and I'd like to turn it off.

remote swallow
#

you could probably use console spam fix to block it

small thistle
#

Would anyone be able to help me figure out why player.damage(hp) doesn't work? The item and code omitted in ... does work. It just doesn't apply the damage. Hardcoding the statement player.damage(1) works however.

if (event.getItem().getItemMeta().equals(itemManager.mirror.getItemMeta())) {
                    Player player = event.getPlayer();

                    double hp = (int) (Math.random() * (0 - 20 + 1));

                    if (hp == 0.0) {
                        player.sendMessage("Lucky, Mirror took no health away");
                    } else {
                        player.sendMessage("The mirror took " + hp + " of health away.");
                    }
                    player.damage(hp);
... 
}
jagged monolith
small thistle
#

omg that makes so much sense! thank you

stable gorge
#

Is it possible to make a client open a writable book ( Without them having ot have a book in thier inventory ) Via the server?

Looked into Protocollib but it doesn't open anything, I've heard it's not possible to as book writing and such is all client side now? (par the send off)

Wondering if this is true :)

remote swallow
#

the writable book is sadly fully client sided

stable gorge
#

:( so no way to get the client to open one so they can edit in it?

#

I've heard a way is to put one in their hand and get them to right click using protocollib but not sure

onyx fjord
#

it should be possible somehow

#

since hypixel does that after rounds

gilded knot
#

How would I be able to make players instantly respawn?

#

You know when players die they have the Return back to Menu or Respawn Buttons

#

I want it so that they instantly respawn at their spawn point

jagged monolith
#

Could try caneclling the playerDeathEvent. So they technically don't die. Then you can handle the "death" differently.

eternal oxide
#

You can't cancel the death event, The event runs after the player has died

jagged monolith
#

Yeah just realised lol.

eternal oxide
#

You have to catch the damage event and see if their health will be zero.

sullen marlin
#

dont know if it works with writable books though

sullen marlin