#help-development

1 messages · Page 1714 of 1

torn oyster
#

i have developers who do the work for me now

#

paid lol

lost matrix
#

Did you teach them?

torn oyster
lost matrix
#

Ah ok

torn oyster
#

were you scared that i was giving out bad quality plugins? lol

lost matrix
solar sable
#

why do i feel like this could change a bit and then everything will be fixed 🤔

worldly ingot
#

Well, firstly, please format that ;p

lost matrix
#

First thing you do now is go into your class and format it

#

What IDE do you use

worldly ingot
#

Ctrl + A, Ctrl + Shift + I

#

(I think it's with Shift?)

solar sable
#

oh god eclipse? @-@

lost matrix
#

Or you do the whole class with Ctrl + Shift + F

worldly ingot
#

Oh, it's Ctrl + I

#

No shift, sorry lol

#

If you did Ctrl + Shift + I already, just Ctrl + Z it. Haha

#

I ALWAYS forget whether or not there's a Shift

young knoll
#

Imagine not just doing ctrl shift F

lost matrix
#
        {
            String discord = ((String) main.getConfig().getString("Discord"));

            player.sendMessage(org.bukkit.ChatColor.BLUE + "Discord: " + org.bukkit.ChatColor.YELLOW + discord);
        }

Can just be

      String discord = ((String) main.getConfig().getString("Discord"));
      player.sendMessage(org.bukkit.ChatColor.BLUE + "Discord: " + org.bukkit.ChatColor.YELLOW + discord);
solar sable
#

so am i

worldly ingot
#

A few notes,
(1) That case to Player will cause you issues if you run it from the console. Though you don't even have to cast to Player. CommandSender declares sendMessage()
(2) The check for cmd.getName() is unnecessary. It's an executor, it will probably be the Discord command executor
(3) You're always returning inside of that check, so the code after it is never run
(4) The block above String discord and player.sendMessage() is redundant

#

Your implementation there can be simplified down to about just 4 lines

#
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        if (sender.hasPermission("store.discord")) {
            String discord = main.getConfig().getString("Discord");
            sender.sendMessage(ChatColor.BLUE + "Discord: " + ChatColor.YELLOW + discord);
        }

        return true;
    }```
#

And if you want to be fancy, you can declare permission: store.discord inside of your plugin.yml with your command so you don't even have to make that perm check

commands:
  discord:
    description: Get a link to the Discord
    usage: /<command>
    permission: store.discord
solar sable
#

well looky here guys, the pickup detector works :D (btw thats 3 of my 4 detectors lol)

worldly ingot
solar sable
#

me happy now

#

execute happy music

worldly ingot
#

Mmmmm, maybe not 100%. At least the first time around you might get it 60% working fingerguns

#

But the fun is getting that extra 40% lol

solar sable
#

i love getting help but most of the times when its asking a lil too much they just get annoyed

worldly ingot
#

If you do that trick I mentioned above with the plugin.yml it will send one for you automatically and you don't have to do the permission check yourself, Bukkit will handle it for you

#

You can even customize that message with a permission-message: "You don't have permission" option as well

solar sable
#

i havent did a command in a while, idk what command to add lol

arctic moth
#

is there an event that like gets mobs when they spawn in a structure

#

like piglin brutes

#

cuz the normal spawn event doesnt work with htem

solar sable
#

huh

#

what are you trying to say?

#

i cant process it

#

atleast put some commas or anything to say it much better

worldly ingot
#

Not anymore, no. There used to be but now chunks generate with entities within them before they're generated

solar sable
#

seeing people asking for help in a not big brain way is funny lol

#

imagine if a person just asks "how to set mob that attack everything"

#

how to play a sound from mc?

#

i mean like how to use the /playsound feature but in the plugin

#

well basically what i want to know is how to play the sound lol

paper viper
#

Player#playSound

#

World#playSound

young knoll
#

One is player specific

#

I'm sure you can guess which

solar sable
#

how to use it in a commandexecutor class?

paper viper
#

just use the method? You can check if the sender is a player and play the sound there if you want to play a sound for a player

solar sable
#

can you show me how?

quaint mantle
#

do you guys have a plugin that allows server members to send a message on discord and turn that message into the minecraft server's MOTD?

shadow tide
#

how do I make a player argument for a command? I have seen plugins have you be able to tab complete player names, I would like to know how to do this.

young knoll
#

Implement TabCompleter

shadow tide
#

how to I implement two things?

eternal oxide
#

you implement that instead of CommandExecutor

shadow tide
#

ooh

eternal oxide
#

actually implement TabExecutor

#

it does both

young knoll
#

Huh, I normally implement both

eternal oxide
#

TabExecutor is just a wrapper for both

young knoll
#

Good to know

#

Not that it matters much

eternal oxide
#

nope

shadow tide
#

how do I implement two things

#

good to know for the future

eternal oxide
#

you either implement TabExecutor, or you implement CommandExecutor, TabCompleter

shadow tide
#

ooh

#

cool

quaint mantle
#

how can i setup a discord channel like this?

shadow tide
#

bruh

#

please

#

dude

quaint mantle
#

?

young knoll
#

You can implement as many interfaces as you want

shadow tide
#

u are breaking discords TOS

young knoll
#

Well, I'm sure there is a limit somewhere

quaint mantle
shadow tide
#

BetterDiscord is against discords TOS

quaint mantle
#

not a big deal

quaint mantle
#

i need this for my smp server

shadow tide
#

its still against discords TOS You must not copy, adapt, modify, prepare derivative works based upon, distribute, license, sell, transfer, publicly display, publicly perform, transmit, stream, broadcast, attempt to discover any source code, reverse engineer, decompile, disassemble, or otherwise exploit the Service or any portion of the Service, except as expressly permitted in these Terms

#

for plugins

#

dude

quaint mantle
#

discord default gui is boring

late current
#

https://cdn.discordapp.com/attachments/853900636428304394/893264752430678106/2021-10-01_11-33-00.mp4

Does anyone know why the inventory doesn't update the first time I open the GUI, but all the times after that it does update?

        if (chatSettings != null && event.getInventory().getName().equalsIgnoreCase(chatSettings.getName())) {
            event.setCancelled(true);
            if (event.getCurrentItem().getItemMeta().getDisplayName().contains("Party Message Sounds")) {
                settings.setPartyMessageSounds(!settings.getPartyMessageSounds());
                chatSettings.setItem(1, ItemUtils.createGuiItem(Material.NOTE_BLOCK, Common.colour(settings.getPartyMessageSounds() ? "&aParty Message Sounds" : "&cParty Message Sounds"), Common.colour("&7Toggle hearing a ding for party messages.")));
                chatSettings.setItem(10, settings.getPartyMessageSounds() ? ItemUtils.createDye(DyeColor.LIME, Common.colour("&aParty Message Sounds"), Common.colour("&7Click to disable!")) : ItemUtils.createDye(DyeColor.RED, Common.colour("&cParty Message Sounds"), Common.colour("&7Click to enable!")));
                ((Player) event.getWhoClicked()).updateInventory();
                return;
            }
shadow tide
quaint mantle
shadow tide
#

you can get banned

quaint mantle
#

idc

late current
#

1.8.8-R0.1-SNAPSHOT

lost matrix
#

Well... too bad

late current
#

Why?

lost matrix
#

1.8 support was dropped almost half a decade ago. This version contains bugs that will never be fixed and lacks a ton of API features.
Almost nobody gives support for such an outdated piece of software.

#

Also only a minority still runs 1.8

shadow tide
#

what if he is trying to write a plugin for a pvp server

lost matrix
shadow tide
#

how do I use onTabComplete?

eternal oxide
#

return a List of tab complete options depending on which arg.length

shadow tide
#

sorry\

#

if I want to give them all of the players, would I use Bukkit.getOnlinePlayers().toArray();?

#

make that a variable, and return that?

vague oracle
#

no

#

because its a list of strings

#

not a list of players

eternal oxide
#

look at the return type of the method

golden turret
young knoll
#

That is their choice

shadow tide
#

what would I do?

pastel stag
#

cause i've posted version 1.0.1 of my plugin and it doesnt seem to be updating....

young knoll
#

Says 1.0.1 for me

#

Can take a few hours iirc

quaint mantle
pastel stag
#

@quaint mantle thank you very much sir, that worked 🙂

quaint mantle
#

wtf

#

that works?

#

🤨

pastel stag
#

yup

#

prints 1.0.1

quaint mantle
#

why did nobody tell me this

pastel stag
#

without &bust prints 1.0

#

yayyy updatechecker class completed haha

#

like a config reload command?

quaint mantle
#

look at the tabcomplete wiki]

#

in commands

#

wiki

#

then just get the plugin and do plugin.reloadConfig()

sharp storm
#

what do i put here (plugin.yml)

name: Launch
api: <-------- here
version: 1.0.0
main: net.j4c0b3y.launch.Main
lost matrix
#

1.17

young knoll
#

Isn't it api-version

hasty prawn
#

yeah

sharp storm
#

when i put 1.16 in there it underlines red

#

and api-version is different

#

its telling me to add api:

young knoll
#

Don't see that on the plugin.yml page

hasty prawn
#

It's different in the sense that api-version actually exists

golden turret
#

the available are 1.13 1.14 1.15 1.1 and 1.17

young knoll
#

1.1

hasty prawn
#

1.1 NotLikeThis

golden turret
#

yes

rugged topaz
#

do plugins by default support multiple versions unless there's an enum discrepency?

#

would my 1.8 plugin work on 1.17 basically?

hasty prawn
#

It depends on what you're doing

sharp storm
#

it says expedcted array or string
should i surround it in ""
api: "1.16"

young knoll
#

If you stick to the API, then there is a good chance it will

rugged topaz
#

alrighty

hasty prawn
#

If you use new features it can break, and if you use NMS at all it'll break

young knoll
#
api-version: 1.17
#

That is the valid entry for plugin.yml

#

api: is not a thing

vague pumice
#

hey so im trying to purchase a hosting server for mc and spigot is one of the options on there. Is it the option i should pick?

rugged topaz
#

oh so i gotta write api-version in my plugin.yml?

young knoll
#

You don't have to

#

But you should

hasty prawn
rugged topaz
#

and since it's written in 1.8.9, i do api-version: 1.8.9?

hasty prawn
vague pumice
young knoll
#

No

hasty prawn
young knoll
#

api-version only exists post 1.13

sharp storm
#
name: Launch
api-version: 1.16
version: 1.0.0
main: net.j4c0b3y.launch.Main

it still shows an error asking for api:

rugged topaz
#

o alr

vague pumice
sharp storm
#

Missing property "api".

young knoll
#

What are you writing your plugin.yml in anyway

hasty prawn
#

Tell it to ignore it

#

It's wrong LULW

young knoll
#

I just write mine in Notepad++

hasty prawn
#

wot

young knoll
#

Why would I use a fancy IDE for a small yml file

hasty prawn
#

Because you can make the file in the fancy ide

#

And then just open it immediately

young knoll
#

I do

hasty prawn
#

Whatever works I guess

young knoll
#

But I'd rather use notepad++ then the plain text editor in my IDE

hasty prawn
#

Does your IDE not have YML support...?

young knoll
#

Not without an addon I assume

hasty prawn
#

Are you using Eclipse PauseChamp

young knoll
#

Yes

hasty prawn
#

Ah

#

IntelliJ supports YML 🤷‍♂️

pastel stag
#

i would imagine that eclipse probably has an add-on for yaml

young knoll
#

Probably

hasty prawn
#

Probably does but Notepad++ is pretty good

lost matrix
#

With the mcdev plugin it event helps you with the plugin.yml content and syntax

young knoll
#

I just copy and paste mine

#

And then edit the main class and name

abstract sleet
young knoll
#

Where is that xkcd

lost matrix
quaint mantle
#

^

abstract sleet
#

Absolutely. I've tried to address that in the thread.

lost matrix
#

Although vault does not support async interections which is really bad if you have a DB backend.

abstract sleet
#

Here's an opportunity to remedy that :)

young knoll
#

Haven’t stopped them yet

#

I imagine most servers with a database backend have their own solution

lost matrix
abstract sleet
#

Usually a cache in the economy provider helps a lot. Unfortunately there are occasions where plugins want a player's balance as they join the server which means.. synchronous call. 😣

lost matrix
abstract sleet
lost matrix
#

You could build a generic abstraction so that you can implement BigDecimal, Double, Long and so on.

neon nymph
#

Is there a tag for all sword materials?

#

I can't seem to find it

lost matrix
#
public interface CurrencyValue<T> {
  
  T getRawValue();
  
  double getDoubleValue();
  
  BigDecimal getBigDecimalValue();
  
  long getLongValue();

}
young knoll
neon nymph
#

D:

lost matrix
young knoll
#

I have a class full of static enum sets in my base library

#

It slowly grows

abstract sleet
#

What would you prefer for your use? The CurrencyValue interface or just double values?

#

I'm unsure if databases even support storing BigDecimals properly. I'm very inexperienced with databases so I'm still learning things.

lost matrix
abstract sleet
vagrant stratus
#

?paste

undone axleBOT
snow ember
# young knoll Yes

Not trying to hate on you or anything, but.... IntelliJ is so much better I could keep listing things
also the text is so much nicer on your eyes... I'd make the switch if I were you :)

hasty prawn
#

If they're used to Eclipse and know how to use it, and it's not hindering their performance, there's really no reason to switch.

lost matrix
prime reef
#

What would be the best way to go about creating a public API for a premium plugin?

#

I'm not really familiar with the process, not sure how to go about doing it

lost matrix
hasty prawn
#

Can't they still find the implementation classes

lost matrix
snow ember
hasty prawn
#

So like, for example, if theres an interface called Server, the actual implementation could be CraftServer or PaperServer or TacoServer, etc etc

#

Obviously PaperServer and TacoServer aren't real but as an example

snow ember
prime reef
snow ember
#

I still never really have understood how spigot hides the implementation classes

hasty prawn
#

The implementation classes are usually just the same name with Craft at the start

#

Implementation of Server is CraftServer

snow ember
#

Yeah ig

#

I've always wanted to make my own server implementation but never had the time

autumn ingot
#

using ChunkData, how do you get the center block of a chunk and get its bukkit location?

#

im trying to spawn in a schematic every chunk

snow ember
#

Is there a Chunk class in the spigot api? I'm assuming there is

autumn ingot
#

yes but i cant access it

snow ember
#

probably getBlock#getChunk

autumn ingot
#

i only have access to ChunkData

snow ember
#

lemme open intellij

#

1s

autumn ingot
#

to be clear im making a chunk generator

snow ember
#

Ohhh

#

Can you get the block obj?

autumn ingot
#

no

#

thats what im trying to do

snow ember
#

Why are you overriding getDefaultPopulators tho

golden turret
snow ember
#

you aren't using it

autumn ingot
snow ember
autumn ingot
#

thats not the point tho

snow ember
golden turret
#

how would you make it possible for the dev to test the plugin?

autumn ingot
snow ember
#

Hm

#

What chunkgenerator class are you using?

#

org.bukkit?

autumn ingot
#

ye

#

i have access to BlockData if that helps

#

i can pull it from chunkData

snow ember
#

there isn't a generateSurface for me

#

spigot ver?

autumn ingot
#

1.17.1

#

they changed a lot of things

snow ember
#

i'm using 1.16.5 shouldnt make a difference tho

#

ah ok

autumn ingot
#

they deprecated some stuff

snow ember
#

yeah

#

getBlockData

#

and use the chunks coordinates

autumn ingot
#

yeah but how do i get the bukkit location from that?

snow ember
#

Yeah i'm confused

#

ChunkData should provide coords

autumn ingot
#

like what am i doing from here

snow ember
#

oh are the coordinates relative to the chunk?

autumn ingot
#

yeah

snow ember
#

just use new Location(coords)

#

Wait that wouldn't work

#

cuz they're relative

autumn ingot
#

thats just gonna create it in the same place every time

#

yeah

snow ember
#

Yeah

#

i'm stumped

#

spigot should probably provide implementations for coordinates of chunks

#

but oh well

#

this code might help

autumn ingot
#

oh

snow ember
#

wait nvm

young knoll
#

You need chunk coords?

snow ember
#

Yeah

autumn ingot
#

no

#

i need world coords

snow ember
#

from chunkdata

autumn ingot
#

i need to extract a block object from a chunk

young knoll
#

So you want to go from chunk coords to world coords?

autumn ingot
#

yes

young knoll
#

Multiple x and z by 16

snow ember
#

that wouldn't do anything

autumn ingot
#

that wouldnt work

#

thats also gonna create it in the same place every time but just x16

snow ember
#

^

young knoll
#

What’s the exact goal here

autumn ingot
snow ember
#

To get the Location of the center block of the chunk

autumn ingot
#

but yes that ^

snow ember
#

yea

young knoll
#

So you have the coordinates of the chunk itself

#

And you want to get the centre block coordinate

#

Multiple the x and z of the chunk by 16

#

And then add 8

autumn ingot
#

that gives me BlockData

#

not Block

young knoll
#

What

autumn ingot
#

i know how to get the center BlockData of the chunk

#

theres no method within ChunkData or BlockData to get a block

young knoll
#

There is in world

autumn ingot
#

i dont have world either

autumn ingot
young knoll
#

You have a getType to get the material of a block

autumn ingot
#

yes and then what do i do

young knoll
#

What do you want to do

#

Why do you need a block instance

#

Action bar is quite old now

#

Added the same time as titles

autumn ingot
young knoll
#

Ah

autumn ingot
#

so i need a bukkit location

young knoll
#

Let’s see here

#

WorldInfo has a getUID

#

And you have Bukkit.getWorld(uuid)

autumn ingot
young knoll
#

You have a world now

#

And you have an x y and z

#

So you can construct a location

#

You need a comma

#

It’s 2 arguments

autumn ingot
young knoll
#

Also you need a component, not a string

autumn ingot
#

where am i getting that from

young knoll
#

Like I said

#

x * 16 + 8

autumn ingot
#

that will not do anything

young knoll
#

Sure it will

autumn ingot
#

that will just give me the same location every time

#

those x and z's are chunk relative

young knoll
#

The javadocs say they are chunk coordinates

#

Can you confirm they only output 0-15?

#

That method takes a component, not a string

autumn ingot
#

alright @young knoll i tried your thing but its not working

#

debugging it

#

to be clear

#

this goes in the bukikt.yml right

#

generator being the plugin name

young knoll
#

I believe so

#

Try adding debug messages or using breakpoints

autumn ingot
#

turns out the method isnt being called

#

wtf does this mean

#

could they be any less specific

young knoll
#

I imagine it’s one of the build methods now

neon nymph
#

Can anyone tell me what's the format for FileConfiguration#getItemStack(path, def)? Like, should the key be a material like "WOODEN_SWORD" orrr?

young knoll
#

The key would be an arbitrary string that you used when saving it

#

ItemStacks aren’t really something that is easily edited manually

neon nymph
#

Ah, so it's meant for when an itemstack is set to it, rather than being edited manually?

young knoll
#

Generally yes

neon nymph
#

Darn, thought it would make my life easier

#

Thanks

young knoll
#

Parsing a material from a config isn’t hard if that is your goal

neon nymph
#

Yea, that's my goal. How would you go about it?

young knoll
#

Use a standard getString and pass it into Material.matchMaterial

#

You will either get a material or null

neon nymph
#

Oh gdi

#

Was trying to find a "fromString" equivalent for material, thought it doesn't exist

#

it was matchMaterial all along

snow ember
#

isn't it valueOf?

late current
#

https://cdn.discordapp.com/attachments/853900636428304394/893264752430678106/2021-10-01_11-33-00.mp4

Does anyone know why the inventory doesn't update the first time I open the GUI, but all the times after that it does update?

        if (chatSettings != null && event.getInventory().getName().equalsIgnoreCase(chatSettings.getName())) {
            event.setCancelled(true);
            if (event.getCurrentItem().getItemMeta().getDisplayName().contains("Party Message Sounds")) {
                settings.setPartyMessageSounds(!settings.getPartyMessageSounds());
                chatSettings.setItem(1, ItemUtils.createGuiItem(Material.NOTE_BLOCK, Common.colour(settings.getPartyMessageSounds() ? "&aParty Message Sounds" : "&cParty Message Sounds"), Common.colour("&7Toggle hearing a ding for party messages.")));
                chatSettings.setItem(10, settings.getPartyMessageSounds() ? ItemUtils.createDye(DyeColor.LIME, Common.colour("&aParty Message Sounds"), Common.colour("&7Click to disable!")) : ItemUtils.createDye(DyeColor.RED, Common.colour("&cParty Message Sounds"), Common.colour("&7Click to enable!")));
                ((Player) event.getWhoClicked()).updateInventory();
                return;
            }
neon nymph
young knoll
#

I believe it can parse minecraft:material for example

young knoll
#

Still gotta handle the exception

quaint mantle
#

how to get the time of the BukkitRunable (like the remain delay) when the server stop to put it in the configuration?

#

Like i have a bukkitrunnable

#

it goes half of the time i set

#

then the server shut down

#

i want it to continue the remain time of the last one

#

i have no idea what keyword to search on spigotmc tho

snow ember
#

in ondisable

#

just get the Task

#

so BukkitTask task = new BukkitRunnable

#

dependency inject it into main class

#

then use task#cancel in onDisable

pastel stag
#

@quaint mantle btw in case you weren't aware, for that cache-busting thing from earlier you can cheat like this "&bust" + System.currentTimeMillis();

#

&bust will obv only work first time so that will give you a different bust everytime

paper geyser
#

so

#

I want to make an addon to a plugin

#

so I want to use their command prefix

#

how would I go about allowing both our plugins to use the same prefix?

vernal pier
#

get their plugin's instance and theirplugin.getCommand("...").setExecutor(...

paper geyser
#

ahhh smart

#

ty

carmine nacelle
#

Alright guys im having a serious brain fart here.. so im trying to have a system that gets the highest even number, so like.. if I have 9 of an item, and I want to take items in multiples of 2.. how would I take ONLY 8 and leave the 1?

#

ive tried doing things with modulo but cant figure it out

ivory sleet
#

leaveAmount = 9%2

vernal pier
#

9/2*2 will give 8 for integer multiplication

ivory sleet
#

wat

steady smelt
#

Block block = (event.getPlayer().rayTraceBlocks(50)).getHitBlock();
How make no give null

#

btw i tried

#

Block block = (Objects.requireNonNull(event.getPlayer().rayTraceBlocks(50))).getHitBlock();

chrome beacon
#

Just do a null check

steady smelt
#

but

#

1 sec

#

im trying to see if it is the left click detection that is the problem

chrome beacon
#

?

steady smelt
#

it was

#

sori

hardy pivot
#

Hi

#

i want to serialize some values to an config.yml

#

but idk how to deserialize the content

#
public class SerializeHolos implements ConfigurationSerializable {
    World world;
    String name;
    String displayName;
    double x;
    double y;
    double z;

    public SerializeHolos(World world, String name, String displayName, double x, double y, double z, CTHolos instance){
        //Hologram hologram = new Hologram(world, format(name), x, y, z, instance);
        this.world = world;
        this.name = name;
        this.displayName = displayName;
        this.x = x;
        this.y = y;
        this.z = z;
    }

    @Override
    public Map<String, Object> serialize() {
        Map<String, Object> serialized = new HashMap<>();
        serialized.put("world", this.world);
        serialized.put("name", this.name);
        serialized.put("displayName", this.displayName);
        serialized.put("x", this.x);
        serialized.put("y", this.y);
        serialized.put("z", this.z);
        return serialized;
    }

    public static SerializeHolos deserialize(Map<String, Object> deserialize) {
        return new SerializeHolos(deserialize.get("world"), deserialize.get("name"),deserialize.get("displayName"));
    }
#
    deserialize.get("world"), deserialize.get("name"),deserialize.get("displayName") //this returns objects and i need strings then doubles for x,y,z
#

i mean in world i need a world type

opal juniper
#

is there any particular reason you are using the x y z & world rather than a Location

#

because Location#serialize and Location.deserialize are a thing

ivory sleet
#

Probably avoiding yaw and pitch shrug

opal juniper
#

meh ig

#

although they arent required by the constructor but will be serialised ig

#

im not a fan of this class name

#

seems like you are using it for any Holo - dont need to put Serialize in the name just cause it implements serializable

digital raptor
#

But I can't figure out how they are making an item invisible?

#

I've tried using air but that has no metadata so I can't add a description

hardy pivot
#

U can use glass pane in all of the slots

rugged topaz
#

if i want to hide all NPCs with the name Click!,

i know i do that with teams, and by adding the entry by name and setting the visibility, but who do i apply the team to? or wha. i just want Click! to be invisible to all players, but players would be able to see one another

team.addEntry("Click!");
team.setNameTagVisibility(NameTagVisibility.NEVER);
opal juniper
#

Thought that teams only applied to players

#

What entity type are teh NPC's

rugged topaz
#

using citizens

rugged topaz
# opal juniper Thought that teams only applied to players

idk, but im messing up somehow. im applying this team to everyone when i'm not sure what i should be doing, it does make npc nametags invisible, which removes the hearts thing i have under their nameplates, and the only way to do that.

opal juniper
#

This is probably a question to ask the devs

#

(the cititzens one)

#

i imagine there must be a method to remove them

quaint mantle
#

Hey is there a way i can replace a item from someone's hand?

quaint mantle
rugged topaz
#

This is probably a question to ask the devs
(the cititzens one)
i imagine there must be a method to remove them
somebody here's gotta know, if anything, this channel is what gave me the idea or the fact that teams would be the only way to remove NPC nameplates

quaint mantle
#

I think that may be deprecated tho 🤔

#

Have a look

#

okay 🙂

opal juniper
#

it is

#

it is main / off hand now

quaint mantle
opal juniper
#

probably

#

its old af

#

they didnt have offhands then right?

rugged topaz
rugged topaz
opal juniper
#

what i thought

#

i think Player#setItemInHand dafaults to main hand beyond 1.8 - but dont use it anyways

vernal pier
#

you need to send scoreboard packet for team color

shadow tide
#

I need all of the online players in a list of strings, how would I do this?

crimson terrace
#

you mean the names of the players?

shadow tide
#

yes

crimson terrace
#

you get a list of the online players by using server#getOnlinePlayers and make a String list you put all the names from the onlinePlayers list into that

#

its 4 lines of code

young knoll
#

Streams

crimson terrace
#

or that

eternal oxide
#
List<String> players = Bukkit.getOnlinePlayers().stream().map(player -> player.getName()).collect(Collectors.toList());```
young knoll
#

I believe you can use a method reference there

lavish hemlock
#

yeah

#

Player::getName

#

even then, why use streams? they're slightly more inefficient than just writing out a foreach, y'know

#

if you're truly poggers, make your own functional lib with monadic lists :) (or use Kotlin)

#

bc y'know, the above in Kotlin is just

#

val players = Bukkit.onlinePlayers.map(Player::getName)/map { it.name }

#

ez

analog ore
#

what does it compile to

#

from kotlin

lavish hemlock
#

probably

#

List<String> players = Bukkit.getOnlinePlayers().map(Player::getName)

#

which is the Java representation of what it would compile to

#

List in Kotlin is completely different from List in Java.

#

For one, Kotlin's List is not an interface and instead represents an immutable list (while MutableList is a mutable list)

#

And it contains a large amount of utility methods.

#

(Which may or may not be extension functions, I'd have to check)

#

But the benefit is that you're applying that function to the list instead of applying it to a Stream (or Sequence in Kotlin)

analog ore
#

the #map() function is missing in java, would make things a lot cleaner sometimes

lavish hemlock
#

which has significantly less overhead as you don't have to instantiate a new stream pipeline, although the immutable list may make it slightly less efficient

lavish hemlock
#

hell, they only added List.of and such in like, Java 9 or later iirc

analog ore
#

I always start typing it anyway when switching from ts

#

yup

lavish hemlock
#

and that goes to show that the standard library designers don't know what they're doing :)

vagrant stratus
#

well, they do to an extent lol

lavish hemlock
#

(I jest, of course)

vagrant stratus
#

also..

#

I'm way to tired to be coding so I'm drawing a blank since i don't have anything i can copy paste anymore

  private boolean inRange(int value) {
    return (value >= minArgLength) && (value <= maxArgLength);
  }

What would this be if -1 were to be taken into account?

#

I've been up way too long 👀

lavish hemlock
#

well

#

the value on the right would be true

#

but the one on the left would be false

#

so it would return false

vagrant stratus
#

I meant code wise lol

#

it's for command arg checking

lavish hemlock
#

oh

#

well

#

I don't know how you want to check for -1 lmao

vagrant stratus
#

e.g.
a min of 2 but max of -1 being infinite in this case

lavish hemlock
#

oh

#

well then you may need an enum

vagrant stratus
#

hmm

vagrant stratus
#

that.. would make things more complicated that it should be

#

i know I did it before but i don't have the code anymore 👀

#

Don't remember what i yoinked it from either 😐

lavish hemlock
#

see you have to represent 3 possibilities in this

#
  • not in range
  • in range
  • infinite range
#

which means you need a bit of a tristate-esque enum

analog ore
#

return value == -1 || checkRange?

lavish hemlock
#

damn I just cracked my knuckles so hard they fucking echoed

analog ore
#

oh wait you mean unbound low/high

vagrant stratus
#

I believe for -1 it would just consider anything above min true, yea?

minArgs = 3
maxArgs = -1

so as long as it's 3 or above it's true

minArgs = 3
maxArgs = 6
must be between 3-6 args

analog ore
#

you could just add the -1 check inside each condition then

lavish hemlock
#

hmm

#

good point

#

you learn new logic every day

vagrant stratus
#

due to sleepiness

lavish hemlock
#

(this is what OOP does to you)

#

if (value == -1) return true?

vagrant stratus
analog ore
#

nop

#

he meant unlimited bounds

#

not the value right?

lavish hemlock
#

well

#

that method is for checking the bounds

#

and checking if the value is in the bounds

analog ore
#

but value is not gonna be 1

#

he wants to pass through if the argument ranges are -1

lavish hemlock
#

oh

vagrant stratus
#

Yea, if the args are clamped to 1 and 5 for example it must be between 1 and 5 however if it's between 1 and -1 then as long as it's 1 or above it's true

analog ore
#

return (min == -1 || checkMin) && (max == -1 || checkMax);

vagrant stratus
#

there we go

#

That should be it 😂

lavish hemlock
#

damn well

#

gg

slow tusk
#

How does this work

#

Do I need to invite a bot

analog ore
#

you could actually get rid of the check on the min

#

since -1 is always gonna be lower

vagrant stratus
lavish hemlock
slow tusk
#

Discord to minecraft chat

analog ore
#

SRV?

lavish hemlock
#

oh

#

yeah you'd need a bot or webhook for that

slow tusk
#

Can you tell me how

lavish hemlock
#

nope, sorry

#

never used SRV

analog ore
#

I bet there's a tutorial on their page

lavish hemlock
#

also this is the wrong channel, you should've asked in #help-server

slow tusk
#

Do I need to make a bot

analog ore
#

They have a support discord and the installation process is explained on the resource page

solar sable
#

guys how to fix .setExecutor being null?

vagrant stratus
analog ore
young knoll
analog ore
#

that's probably getCommand(), so you're missing the command in plugin.yml

#

or misspelled it in getCommand(String)

lavish hemlock
solar sable
#

oh yeh i forgot the plugin.yml my bad

#

😆

analog ore
lavish hemlock
#

IF THE METHOD USES DYNAMIC LOOKUP AND DOES NOT EXIST AT RUNTIME, IT IS THEORETICALLY NULL

solar sable
#

chill

lavish hemlock
#

no

#

:)

tall dragon
#

No need to yell 😋

lavish hemlock
#

I'm not yelling, I'm just speaking very loudly

#

trying to be nice to the hard-of-hearing people in chat

#

(is that the term? who cares)

vagrant stratus
#

Yelling would be IF THE METHOD USES DYNAMIC LOOKUP AND DOES NOT EXIST AT RUNTIME, IT IS THEORETICALLY NULL

#

or an image of it

#

all caps 100 font size, bolded

tall dragon
#

Nah thats another level. Thats screaming

lavish hemlock
#

nahhhh

#

only the children in my basement scream

#

I mean what

solar sable
#

this is the null thing btw

lavish hemlock
#

that is a warning

solar sable
#

if it is only 2 getcommand its fine and it runs the plugin but when i add a third one, it doesnt want to enable the plugin

quaint mantle
#

hover over it, what does it say?

lavish hemlock
#

it is showing up bc getCommand is probably annotated with @Nullable

#

which means it may return null

#

but not that it does return null, just that it may

analog ore
#

is that IntelliJ? 🤔

solar sable
analog ore
#

Alt + Enter, insert Objecs.requireNonNull

solar sable
lavish hemlock
#

it's unclean

quaint mantle
#

yeah don't do that 😂

lavish hemlock
#

also don't use assert, or even a null check in this situation

analog ore
#

why wouldn't you

lavish hemlock
#

as I said, it's unclean

quaint mantle
#

^^

solar sable
#

then what do i do to stop it being null?

lavish hemlock
#

if you have multiple commands, you have multiple Objects.requireNonNull

quaint mantle
#

it's not null

#

its a warning

#

You're free to leave it

solar sable
#

oh yeh my bad i meant might be null

tacit drift
#

won't be null

analog ore
#

it might be null

solar sable
tacit drift
#

unless you remove the class

#

do you have a onCommand method in those classes?

quaint mantle
lavish hemlock
#
private PluginCommand commandNonNull(String name) {
    return Objects.requireNonNull(getCommand(name));
}
solar sable
#

uh yeh sure

lavish hemlock
#

you can also do that

#

and then use commandNonNull instead of getCommand

#

Which is much cleaner, as you type less code overall.

tall dragon
#

Just use a simple rule for yourself. as soon as you have duplicated code. Extract it and make a method out of it

lavish hemlock
#

DRY ftw

terse zodiac
#

guys

young knoll
#

getCommand will only return null if you don’t have the command in your plugin.yml

terse zodiac
#

help me

analog ore
#

Not much DRY when you do it once.

young knoll
#

You ram out of memory

analog ore
#

if you had a single command, it would end up the same.

young knoll
#

Also that isn’t eve spigot

lavish hemlock
young knoll
#

That’s when you fix it?

lavish hemlock
#

yeah

#

it throws an exception if it's left out

young knoll
#

Not really any point in handling the null

lavish hemlock
#

therefore letting you know you need to fix it lmao

#

which is why you should check it

#

so you don't have to wonder why your code isn't executing

#

before figuring out it's bc you didn't define your command

young knoll
#

It will already throw an exception

#

Which is easy enough to understand

lavish hemlock
#

excuse me but

#

if it throws an exception

#

why would it return null

analog ore
#

the only pro of doing this is shutting up the IDE

lavish hemlock
#

that too ^

vagrant stratus
analog ore
#

he meant the NPE if the command was null

lavish hemlock
#

fair but

analog ore
#

and i'd say he's right as long as you're doing a plugin and not a command library or something.

lavish hemlock
#

I prefer handling it myself

vagrant stratus
young knoll
#

I already told them they ran out of memory

#

And it isn’t even spigot

lavish hemlock
#

that's why you're not a helper

lavish hemlock
vagrant stratus
lavish hemlock
#

yeah that is uhhh

#

Forge

analog ore
#

@terse zodiac how much RAM do you have allocated for the server in total?

lavish hemlock
#

@terse zodiac how much memory do you have allocated t-

#

ok then

analog ore
#

what's the default flag value for Xmx

#

🤔

lavish hemlock
#

2GB I think?

analog ore
#

that's prob the issue then

lavish hemlock
#

maybe 4?

vagrant stratus
young knoll
#

“The default values for Xmx is based on the physical memory of the machine. The Xmx value is 25% of the available memory with a maximum of 25 GB. However, where there is 2 GB or less of physical memory, the value set is 50% of available memory with a minimum value of 16 MB and a maximum value of 512 MB”

lavish hemlock
#

Memory: 48129320 bytes (45 MB) / 2147483648 bytes (2048 MB) up to 2147483648 bytes (2048 MB)

vagrant stratus
lavish hemlock
#

hmmm

terse zodiac
#

4GB :D

#

ram?

#

my computer have 16

analog ore
terse zodiac
#

for minecraft 4gb

analog ore
#

i'll find a java playground

#

xd

lavish hemlock
#

2048MB == 2GB though

#

is the stacktrace just shit?

vagrant stratus
# analog ore what
    if (!inRange(args.length)) {
      sendMessage(player, messagesConfig.getString("not-enough-arguments"));
      return true;
    }
  private boolean inRange(int value) {
    return (value >= minArgLength) && (maxArgLength == -1 || value <= maxArgLength);
  }

Looks like 0 gets passed the check, unless I'm being dumb again lol

#

which is likely seeing as I've been up longer than i should be 👀

analog ore
#

what values are min & max

lavish hemlock
#

your & mom

#

🤣 I am very funny

analog ore
#

veri funi

#

give me the values

vagrant stratus
#

wait...hmm...lemme double check something...i might just be dumb

#

#AlsoFuck0length

analog ore
#

seems fine tho

vagrant stratus
#

Nope i'm just dumb

#

need to make it 1 & -1

analog ore
#

I bet there'll be someone scouting tabs I have open

#

most likely maow

lavish hemlock
#

how did you know?

analog ore
#

because I do it as well

#

always

lavish hemlock
#

what's that first one?

analog ore
#

first one pinned or IUS

lavish hemlock
#

yes

analog ore
#

IUS is a google doc with notes from a lecture

lavish hemlock
analog ore
#

Intro to software engineering

vagrant stratus
lavish hemlock
#

My BF is non-existent.

I don't have one anymore.

vagrant stratus
#

hand could count

lavish hemlock
#

Eh he doesn't fall asleep very often tbh.

vagrant stratus
#

xD

lavish hemlock
#

But yeah my ex is in WV so we never had that problem.

#

In fact, he typically stayed up really late talking to me.

#

Istg we were in a call for like 14-16 hours one day.

#

Actually that happened 3 times in the span of a week.

analog ore
#

#help-emotional-development

lavish hemlock
#

#relationship-help

vagrant stratus
#

okay yea @analog ore I'm too tired to code. Time to sleep.
The classes don't handle 0 arg properly now, so they need rewritten lol

analog ore
#

is it open src

#

i'm bored

vagrant stratus
analog ore
#

wait I have class in 10 never mind

vagrant stratus
#

I have open src stuff lol

quaint mantle
#

how do i detect when a player is jumping? PlayerMoveEvent?

terse zodiac
#

guys

#

my minecraft work

#

only crashes when I open the 2nd page of mods

eternal oxide
#

mods are not spigot and wrong channel. This is for plugin development

terse zodiac
#

oh

#

okay

vernal pier
#

sure if you want to you can use real teams

#

yeah since scoreboard entries are all strings

#

for players their name and for entities their uuid

#

yes, uuid as the string entry

quaint mantle
#

Database Library

gusty bough
#

Is it possible to know with spigot api if a player is affected by a scoreboard displayed for a team (/scoreboard objectives setdisplay sidebar.team.*** teamName) ?

#

With scoreboard#getEntries() i can get all players referenced manually (by /scoreboard players add) but not with teams

lusty cipher
#

how tf do I debug this issue with no stack trace being printed and the server just shutting down?

eternal oxide
#

it can;t be terminating with no logs at all, not unless you are force closing teh jre

tardy delta
#

how should i load everything that a command needs to work (f.e. warp files, locations) to objects? Should i just make one class for it?

analog ore
#

When you set a static field to null, is it eligible for GC

#

It is right

#

The object is unreachable

#

Thanks

quaint mantle
#

how to move blocks (like hole in the wall in minecraft chamionship event )

eternal oxide
analog ore
#

Really

#

I'm not sure here

eternal oxide
#

Static variables are referenced by the Class object which is referenced by the class loader. unless the class is unloaded the static variables are permanent

ivory sleet
#

Which is not safe because every single hard reference to the class and the classloader needs to go away

analog ore
#

There would be no reference to it, hence it would be eligible for GC?

ivory sleet
#

But why?

lusty cipher
# lusty cipher

this seems to be happening because of an empty switch.... weird

analog ore
ivory sleet
#

Why set it to null

analog ore
#

I could accept you saying simply no, but I'm interested in what's the reason behind it.

ivory sleet
#

Sure the value of the field would be gone and gc’d if isn’t referenced somewhere else

ivory sleet
#

But then using your static variable is pointless

#

If it isn’t going to be referenced from somewhere else

eternal oxide
#

Its a static field so its referenced by the Class. Setting it to null, its still referenced by the class.

ivory sleet
#

Just by assigning a variable null does not mean its current instance it was holding will be gc’d

eternal oxide
#

if it is referenced it can't be put up for GC

ivory sleet
#

And obv if you’d have a static final variable of a primitive type the value is going to be inlined so there you don’t even have to be worried.

analog ore
#

Not sure what I should've found out there

#

I understand how classes & interfaces are unloaded

#

I'm interested in the field referencing another object in heap

eternal oxide
#

static variables are covered under those rules too

#

Just because you set it to null does not remove all references to it.

analog ore
#

I understand that

eternal oxide
#

a static field is referenced by the class its in. So unless you can unload that class your field is held by the class reference

analog ore
#

But you're still talking about fields, not their values

ivory sleet
#

You already got the answer of their values

eternal oxide
analog ore
#

Okay okay

ivory sleet
#

He asked if the instance the field was referencing to would be gc’d tho if he would mutate the variable with null.

analog ore
#

Yup

eternal oxide
#

um, an interesting question

ivory sleet
#

And the answer is yes and no

analog ore
#

Thanks for rephrasing

eternal oxide
#

I don't know but I would assume yes, however it could be reassigned

ivory sleet
#

If some other variable references that object, then it by convention cannot be gc’d unless some very specific circumstances I’m not going to talk about, but if that field is the only strong reference to that object then yes, it’d be enqueued for gc.

analog ore
#

Thank you

median flint
#

How would you make a YAML database?

eternal night
#

there is really no point in making a yaml database

#

if you need unstructured data, use json based dbs like mongodb

median flint
#

Can't I just store stuff in a yaml file though?

eternal night
#

Well yea sure but that is not a database

median flint
#

Oh

median flint
eternal night
#

Well you can still store things in plain yaml files

#

which might be a lot easier

#

just because it isn't a remote database maintained by its own process etc

#

doesn't mean it is unusuable

median flint
#

Do you know how I would make that then?

#

I just need to store only a few lines of information

eternal night
#

spigot has this

median flint
#

Ty

eternal night
#

which allows you to work with config files

#

you can however create other files besides the config.yml using the same system

median flint
#

I'll try that

#

oo

ivory sleet
#

Maybe put the yml storage behind some sort of boundary in case you wanna switch in the future it wouldn't be too big of a hassle

#

Like having an interface to talk with the persistent storage implementation whatever that might be

median flint
#

Nothing public or useful

ivory sleet
#

I guess but you never really know what it might grow into in the future

median flint
#

But ye that would be a good idea to do that

median flint
#

I have the least efficient code ever rn

ivory sleet
#

then you got yourself a goal to work towards? write more efficient code

#

:p

tardy delta
#

can i load an Set<UUID> in string format from config?

ivory sleet
#

Yeah

#

assume its a List<String>

tardy delta
#

ah ok

median flint
ivory sleet
#

loop through the strings, if a string can be validly turned into a uuid, convert and add to the set basically

ivory sleet
tardy delta
#

yea i got it thanks

tardy delta
eternal oxide
#

then fix it. Don;t use an array, use a Set/List

tardy delta
#

its a set.toString()

lusty cipher
#

you can use regex theoretically to parse it back

#

but yeah, don't do this

tardy delta
#

or maybe i can just do

new HashSet<String>(Arrays.asList(file.getString("vanished-players").replaceAll("[]", "").split(", ")))
#

smh

#

what can i use instead?

eternal oxide
#

add it as a List and getStringList

tardy delta
#

but i saved it with file.set("vanished-players", hashset)

eternal oxide
#

bukkits yaml parser doesn;t understand Set use a List and it will.

tardy delta
#

but if i just use file.set(..., list) will it be save as

  • uuid1
  • uuid2
    etc?
eternal oxide
#

yes

#

probably 🙂

tardy delta
#

i hope

#

😳

eternal oxide
#

just write a wrapper method to save and load

#

build a string List, put in config, read String List from config and return yoru Set<UUID>

tardy delta
#

uhh lemme search that up

#

i hope this will

#

btw saving all the lists etc to the files, should i do that async?

eternal oxide
#

teh actual saving to disc yes

#

adding to teh config, no

#

thats just in memory

#

just remember to save/load lock

golden turret
eternal oxide
#

yep

golden turret
#

or simply

eternal oxide
#

there is a get method you can provide teh class

golden turret
#

new HashSet<>(getList())

tardy delta
#

with the saving you mean FileConfiguration#save(file)?

quaint mantle
#

If i create a inventory using a command e.g. Inventory trashCan = Bukkit.createInventory(player, 36, "Trash Can"); and want to detect when it's opened in an event, how do i do that?

eternal oxide
#

save and load (if you can) async

quaint mantle
eternal oxide
#

if (inventory == trashCan)

golden turret
#

InventoryHolder

#

🙏

eternal oxide
#

You are only instance checking an Inventory, no need for a Holder

tardy delta
#
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> ConfigManager.saveConfig(ConfigManager.FileType.DATA));
ivory sleet
#

lock it

tardy delta
#

i've never used locks

ivory sleet
#

yeah well

#

what if you'd save the data concurrently

tardy delta
#

then strange things would happen

#

i know the concept of locks but i never found it useful to use it

ivory sleet
#

lets say you do indeed save to a file async

quaint mantle
#

the event and the created inventory

eternal oxide
#

what?

#

You mean the trashCan

#

?di then learn

undone axleBOT
ivory sleet
#

normally if you coded spigot plugins you should have realized everything you write gets executed linearly fourteenbrush

#

When we work with async, that is not the case

quaint mantle
#

One is a command class where it creates the inventory and the other is in a event class

ivory sleet
#

code declared above other code can be executed after that other code

#

or at the same time

tardy delta
#

yes

eternal oxide
ivory sleet
#

and yes exactly at the same time

#

so the problem here with files comes down to that you might be writing to the same file twice under the same time

#

and then you would end up with a corrupt file

#

or well

#

sort of corrupt

#

corrupt data at least

#

It actually happened I believe in LP early days

tardy delta
#

oh

ivory sleet
#

but lucko fixed it sophisticatedly

quaint mantle
eternal oxide
#

passing a reference of a variable to another class

quaint mantle
#

oh

ivory sleet
# tardy delta oh

anyways locking is when we ensure across multiple threads only one thread can at the moment do something

#

and every code executed passed to a single thread must run linearly

#

so then you'd be safe

#

bbl but I will send you an example of how locking can be done

quaint mantle
tardy delta
#

isnt this just something like synchronized {}?

eternal oxide
#

the rough way, yes.

quaint mantle
#

and what is that?

eternal oxide
#

soryr that was to fourteen

quaint mantle
#

oh

quaint mantle
tardy delta
#

i read a book about operating systems

ivory sleet
#

it has no fairness policy

#

and it doesn't provide a read write mechanism

tardy delta
#

i dont even know what it does exactly do

ivory sleet
#

oh maybe elgar could explain that then

tardy delta
#

take your time i havent wifi the whole weekend 😳

eternal oxide
#

yep, synchronized is not realy relevant in thsi case

crude hound
#

onEntityChangeChunk?

eternal oxide
#

You could make it work by simply sync locking your data access class

#

but thats rough and basic

quaint mantle
#

Why is <Player>.getTargetBlockExact() when i'm looking at a sign not return an Block that is an instance of Sign?

eternal oxide
#

not performant when you are trying to run things async

quaint mantle
vagrant stratus
eternal oxide
#

no

gusty bough
#

Is there a way to detect if a scoreboard objective is displayed to a player with spigot api?

vagrant stratus
#

what are you doing exactly anyways, Killer?

quaint mantle
#
Player player = (Player) sender;
Block looking = player.getTargetBlockExact(10);
System.out.println((looking instanceof Sign));
if(!(looking instanceof Sign)) return false;```always returns false. Any idea why?
eternal oxide
#

someone posted a really nice save/load lock class the other week

vagrant stratus
eternal night
#

blocks are never an instance of a sign

#

the block state might be

gusty bough
#

looking.getState() instanceof Sign

#

Someone knows the answer of my question ?

eternal oxide
#

?paste

undone axleBOT
eternal oxide
#

The save/load locks will though. It uses a ReentrantReadWriteLock to prevent collisions

ivory sleet
#

thonk static

tardy delta
#

Ah i understand

#

Saw that before

quaint mantle
#

sing cacher

#
public static void addLine(String holo, String text) {
        ConfigurationSection section = 
        data.getConfig().getConfigurationSection(holo);
        List<String> lines = section.getStringList("lines");
        lines.add(text);
        section.set("lines", lines);
        data.saveConfig();
    }

is there anything wrong about this ?

eternal oxide
ivory sleet
wispy plume
#

Hey, how can I put rgb text into a TextComponent in Bungee?

golden turret
#

use a rgb pc

wispy plume
#

Nani?

#

Anyway i know already, ChatColor.of(HEX)

gusty bough
#

Is there a way to read the real code behind a spigot method? I would like to see Player#getScoreboard()

#

Like deobfuscated

ivory sleet
#

well

#

just depend on the server jar rather on the api

#

use mojmaps in case you want to "unobfuscate" it

gusty bough
#

not for mojang code but spigot one