#waterfall-dev
1 messages · Page 12 of 1
thanks for helping :D
its working now ^^
@wide maple were you ever able to get your switching rework tests to work? I've been trying to send a custom login and respawn packet to the client, but I think my dimension is invalid, as the client displays this error.
I listened in to normal packets sent by the server to get an example of what a valid login/respawn packet looked like, but I was still unable to get it working properly.
that's the code I used to create the fake limbo dimension, based on what I found in your code here https://github.com/Xernium/BungeeCord/blob/b4f955a8f700d010b6058770bde68a7fb495b17c/protocol/src/main/java/net/md_5/bungee/protocol/registry/DimensionType.java
I can't seem to import waterfall as a maven dependency.
This is what I have configured
// Repos
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
<repository>
<id>destroystokyo-repo</id>
<url>https://repo.destroystokyo.com/repository/maven-public/</url>
</repository>
// Dependency
<dependency>
<groupId>io.github.waterfallmc</groupId>
<artifactId>waterfall-api</artifactId>
<version>1.16-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
This is the error https://i.imgur.com/Sh1s5RO.png
oh. Ignore me
my version ID was incorrect
@sturdy nymph you’re better off referring to what we do in velocity- I didn’t update my switching rework to 1.16.2 (which is where the registry changed) ie https://github.com/VelocityPowered/Velocity/blob/master/proxy/src/main/java/com/velocitypowered/proxy/connection/registry/DimensionData.java
However if you’re planning to go through with it- you’ll also have to implement the biome registry part in 1.16.2- good luck on that one
@wide maple I see, thank you. Do you know what the absolute minimum requirements are for the dimension? I'm just sending my own login packet, so I'm defining my own, single, empty dimension, so I don't have to keep track of everything else, as I'm pretty sure that would make it more likely that my plugin would break with updates, especially given that I don't have a huge amount of time to work on updating it.
Also, sorry if I missed it, where is this biome registry? Or is that what the dimension defining info is called (all the ambient_life, piglin_safe, infiniburn data)? Or is that something else on top of it? I can't see any clear example of it on wiki.vg
How do i build travertine with 1.16.2 support
it supports 1.16.2?
I am having an odd issue. Sometimes PlayerDisconnectEvent is not called when a player disconnects. I believe the reason is because they timed out. The way they time out, I think, is because they connect to a server right as it is shutting down. So they connect and get immediately disconnected but waterfall/bungee (not sure whos fault it is) never calls the event. I noticed this because I have a log database that tracks all the times players join/leave (and with this, I calculate full play time with ease), and sometimes there is a row left with 0 (the default, which means they are online still) as the disconnect time. So over time it gives players insanely high play times. I have a temporary solution, but I'm confused on why this would be happening.
I've changed my thoughts on what's causing it. I just tested what I explained and that's not what the cause is.
I'm kind of clueless now
could you make waterful pull its config from a mysql database on startup?
or better yet. just completely use a mysql database table for its config
is that possible?
Without patching it or without a custom launcher that’s not possible. However- it’s possible to modify all values the config did. set after startup
So a plugin that after it starts up. It modifies the config.yml from the database
Then next restart it would have the config you want
zero reason to do that as a plugin/fork imo, you can simply pull the updated file from your database via yourt startup script
(or just use NFS)
you can easily implement your own configuration adapter
set it in onLoad and call it a day
however when you really insist on using *sql then you must do your own configuration remapping - bungeecord expects kind of key-value storage
ProxyPlayer#getListenerInfo or something like that
Ended up finding it plugin.getProxy().getConfig().getListeners()
excuse my ignorance but what is the correct way to build a test waterfall version without having to create a patch?
mvn package
thank you
You should always mvn clean package imo
How to send JSON message to player directly (Not use BaseComponent etc) via Bungeecord?
I found ComponentSerializer::parse. So, it was resolved thx.
that was gonna be the first thing I'd suggest. Alternatively you can always send raw packers
¯_(ツ)_/¯
so like im confusion
at first i thought plugin messaging was easy
but
how would i send something down a custom channel which has a subchannel and an argument such as an integer
so it can indicate its either removing or adding an integer from something
i tried following this https://www.spigotmc.org/wiki/sending-a-custom-plugin-message-from-bungeecord/ and i get sub channels but adding more data is confusion
should i just send something like subchannelname;data;moredata
and then recognise that
or
ping me if anyone answers
The data goes to the byte array
The channel is to define the type of message you are sending
The exemple is perfect and this is how you should do
yea but i want to send extra data
like the channel, sub channel, multiple uuids, and an integer
ByteArrayDataInput in = ByteStreams.newDataInput( event.getData() );
String subChannel = in.readUTF();
like i see this on the tutorial
does that in.readutf thing return the whole string of data sent
it depends on how you send it
just read in the same order as you send
e.g. first readUTF, then readInt and then readUTF again
if you want multiple UUIDs then I suggest using an int to indicate the count then write the UUIDs as longs (most and least singificant bytes)
then you can read the amount and read the longs
(of course you can also just write them as UTF but afaik that is more data
Yea that makes more sense I didn't know that's how it worked thank you
getting a null on line 29 some times
I assume the response is null some times, is that normal?
If there was no response, yes
everything can be null in bungee
^ pretty much. a quick look at some beans tells me there are no preconditions as to what can be passed in
major thing is pass through, if the server doesn't respond, it'll be null
how can I send a message to a player? I tried to watch this tutorial https://www.spigotmc.org/wiki/sending-a-custom-plugin-message-from-bungeecord/
The home of Spigot a high performance, no lag customized CraftBukkit Minecraft server API, and BungeeCord, the cloud server proxy.
but I don't figured out how to send the data to the player
see if i have a Configuration, is there a way to loop through sections in that config?
nvm i dont need it anymore i found a better solution
config.getKeys
probable due to your config file's encoding
make sure to use UTF8 for that
also, uh, wrong channel I guess. I see that you asked in paper too lmao
since 1.16 i cant use ComponentSerializer.parse(json); because they is something new like contents can someone help.
com.google.gson.JsonParseException: Could not parse JSON: missing 'text' property
[{"text":"[Suratix] player has voted!","clickEvent":{"action":"OPEN_URL","value":"minecraft-server.eu"},"hoverEvent":{"action":"SHOW_TEXT","contents":[{"value":"Click for Vote"}],"legacy":false}}]
are you using the latest version?
if so then this might be the first time for this happening on the server side instead of client? Oo
yeah i used now the newest version same error
Mojang changed something with the components
yeah :c
iirc, value is now "text", as it's complaining about
oh, right, that isn't even valid components
only 1.5x the size but yeahfor the current specification if you really must use raw json input for whatever reason
I don't know what to do now.
replace "value" with "text"
i replaced contents with text its work now without error, message is displaying but clickEvents & hoverEvents dont work.
ok thanks i fix it now complety without replacing stuff.
ComponentSerializer.toString(baseComponent); //All Components to String.
ComponentSerializer.parse(object.get("baseComponents").getAsString()); //All Components from String to Components
What should I do to prevent hitting the mojang rate limit on waterfall?
load balancing of some form
not sure what to do
You either mitigate it by running multiple waterfall proxies across different IPs, or by using proxies or something somehow, waterfall lets you configure the auth URL for this purpose
how many players do you think is a good amount for a single proxy?
I run everything on 1 big dedicated server
more about join velocity than anything
Everything on a single box ain't going to do you much good here
Unless you're doing something to contain stuff in a way that you can configure it to use different public IPs somehow
Does velocity have a way to configure the auth url
oh
Does velocity have a way to configure the auth url
@grizzled thistle I’m pretty “eh” on that one, I can see the benefits but it seems too much like an official piracy hatch for me. We’ll see.
I felt the same which is why I kinda delayed on it
what are people supposed to do then about the rate limit Tux
Eventually I got to the "people already use plugins for this stuff, and not like replacing a line in the server is that hard"
I mean, it’s an one line patch, I could do it easily
But it’s late now, so I won’t do it yet
Don't know of any off the top of my head, stuff like "online/offline" join stuff are capable of doing it, etc
isn't that like cracked servers
Do consider that you need to find a way to bypass the limit
You could throttle logins before any authentication is done
You'd need to setup a proxy which can distribute the requests
There is no magical way of doing this
That’s per IP, not very effective since a real attack would use open proxies or similar
the easiest option for smaller networks is to just RR proxy instances
whats that
not sure how to do that
Are you really running into rate limit issues?
I'm afraid I'm going to be, getting 200+ players concurrently
You aren’t running into them now. Best to wait and see
Is there a class or method path I can look for to see, if the current proxy implementation is Waterfall?
waterfall configuration class
because it's not part of the api
lemme c
io.github.waterfallmc.waterfall.conf.WaterfallConfiguration
ok thanks
Can I just cast the getLogger to a SLF4J logger when I want to have a more generic Logger (For multi-platform support)?
no
the plugin logger doesn't implement the slf4j logger
you need to use LoggerFactory or getSLF4JLogger
I don't quite understand the LoggerFactory one...
And since my plugin wouldn't just run on Waterfall is there no guarantee that their SLF4JLogger implementation is there...
LoggerFactory is the standard approach slf4j exposes for getting a logger
And since my plugin wouldn't just run on Waterfall is there no guarantee that their SLF4JLogger implementation is there...
Then you neither have a guarantee slf4j is even on the classpath
So something like this?
yes, that will work
you can use getClass() if your logger is an instance variable
but assuming you just want a global logger for your entire plugin, this is fine
Okay.... Now I just need to find a way to make a platform-independand YAML config handler... Will be sooooo fun 
it's not too hard; use snakeyaml to load a Map<String, Object>
Sounds easy for you, but I'm quite a beginner on this part
the Map you get will be a hierarchical Map of nested maps. Each subsection is a map within the top level map
and so on
.....Thanks for making it even more complicated sounding
no, that's the truth.
Your map won't have keys such as "section.subsection.subkey"
rather you'll get "section" in the top-level Map which points to a smaller Map corresponding to the subsection.
But how would I load a file tho?
yaml.load(Reader)
like a config.yml inside the resources folder...
Files.newBufferedReader(Path, Charset)
or use InputStream with clazz.getResourceAsStream
PluginClass.class.getResourceAsStream("/config.yml")
Isn't there JUST a simple lib to load and handle files with simple "getString", "getInt", etc? It gets really annoying by now...
(and yes, it works independently from the BungeePlugin class
If it does then why are there things like the ConfigurationProvider from Bungee 
And also constructors for the Bungee plugin?
Like which parts of it are important to look at?
Idk... I quickly made this thing which I use in my bot (Although slightly different) to load files
https://hasteb.in/setubizo.java
the class that I pasted
either copy it or use the maven artifact
and it does not depend on the BungeePlugin class in the same repo, I didn't say that it doesn't depend on Bungee's Plugin class
The class you pasted does use BungeeCord stuff which I can't because my plugin should also support Velocity and not just BungeeCord/Waterfall
it's a configuration wrapper for Bungee
then shade the configuration library of your choice in your plugin if you don't want to use Bungee's configuration library
I personally suggest using HOCON with this library: https://github.com/lightbend/config ;D
Many said I should use SnakeYAML, but I never did use it.... So if you have a starter guide would I appreciate it
both bungee and bukkit use snakeyaml so just do what they do I guess
I personally would just use a platform-specific configuration adapter
(at least that's what I do in my cross platform plugins. use Bungee's configuration api for bungee and Velocity's Configurate in Velocity
Would Configurate from SpongePowered be an option to use?
yes, its what Velocity uses internally
okay. Just need to find out how I can set two separate paths for source and target location, since it seems Configurate only has a way to set one...?
.3 is out
Is md already awake
I think it’s too petty to make a dedicated patch for this, it’s literally just a protocol bump
I’ll rebuild patches and PR it once it’s ready
no 
@trail plume wanna merge that pr? its really petty
yes, read the contributing.md
or just the readme I guess, lol: https://github.com/PaperMC/Waterfall#how-to-compiling-from-source
I love seeing people report issues to BungeeCord GitHub when using Waterfall
I mean, that report is literally a bungee issue anyways
Don’t tell him that
Next he is gonna need to start considering taking paper issues seriously like they affect spigot too
... and not just paper
... but nobody reports them on spigot
... because barely anyone uses spigot on its own anymore
... but he doesn’t care either way
When Spigot is gone... that'll be a great day.
Maybe gone isn't the right word
But more so that Paper becomes mainstream as Spigot is (kinda? not as much as it used to be). Maybe even if Paper was not a Spigot fork, but a Bukkit fork
(that'd be great)
it'll be a great day when Velocity is dominant
Having an issue running a plugin through Waterfall. Wondering if anyone's got some insight on the matter. Basically struggling to use hex colours in text. Tried with raw use of java.awt.Color#Any_Color but the ChatColor fails to parse it. Parses fine with raw net.md_5.bungee.api.ChatColor#Any_Color.
I've managed to get our tab list running using the same method of creating a color by decoding hex and using ChatColor.of(), but it seems to fail in a standalone plugin and not placeholders. I'm not entirely sure on possible reasons for it at this point. Using Waterfall 372 and previously Waterfall 371.
Well, it won't work because of how toString works
public String toString() {
return getClass().getName() + "[r=" + getRed() + ",g=" + getGreen() + ",b=" + getBlue() + "]"
is how it dumps out the string
the way that API works also won't change between where it's called, that more just sounds like something is potentially mishandling it elsewhere in your plugins
rgb support is a hack in bukkit
the bungee ChatColor.of() uses the java.awt.Color input though, afaik
And Color.decode(#FFFFFF) and Color.decode(0xFFFFFF) work outside of the ChatColor usage from all testing/usage I've done.
gdi bungee api 
You mean, it fails in tab but not in chat, etc?
It fails in chat, like in the screenshot above, but my tab list prints out fine using that method to create a string for a placeholder
Hmm- I wonder if it's textcomponent actually
Not the colour creation but the representation of it when put into chat
Lemme play with it, sec
You mean like how event and build are the same color?
Are you sure that you have nothing else on the server which might be toying with it?
Nothing, running this through a blank waterfall instance to be sure.
And it's that none of the hex colours are pulling up proper
Should be more similar to https://i.imgur.com/W28sgti.png
(Mod, Tech, Build, Reception for those colours, using the exact same hex values)
Okay yeah it is TextComponent
For each entry the first line is just raw ProxiedPlayer.sendMessage(message), and the second is ProxiedPlayer.sendMessage(new TextComponent(message))
The first of course being deprecated
you can't do the latter
You need to actually set the color of the component using the color method on the component
Alright, I'll take a look into that then. A bit annoying, but hey, at least it'll work.
There is also the adventure library if you want a nicer API to work with
Noted, thanks zz! Your help is very much appreciated
Well, yea, but that's basically just how chat components works, and it makes sense with how they're represented, better than magic strings like we had/have
Fair enough, I suppose it's just my magic string user being frustrated that I need to go back and redo every textcomponent call haha
TextComponent i think it was has a fromLegacy method, and also has the legacy RGB code hack in it
(which is why sendMessage works)
public void sendMessage(String message)
{
sendMessage( TextComponent.fromLegacyText( message ) );
}
Mhm, I just try to avoid deprecated like the plague.
Don't wanna have to go through a global restructure in the event of it being removed
How would I go about adding a SLF4J logger to BungeeCord (Not Waterfall)?
It does work on Waterfall as it implements its own Logger instance of SLF4J, but since I also want to support BungeeCord is this an issue for me....
Yeah, but how is the question
classloader abuse?
there are a lot of plugins which shade slf4j
either because they use it or because they use hikaricp
if you do decide to do that, do remember to relocate it as well
and remember that plugin.getSLF4JLogger is not what you want
iirc, slf4j already deals with the magic needed, but, god knows; You'd need to look over other plugins maybe
LP miiight use it iirc
mixing multiple slf4j bindings is not supported
conflicting slf4j versions will not work out. you have to relocate both the api and binding if you shade them
you can't relocate slf4j bridge, it uses a service locator or something
yeah
yes
therefore you don't relocate slf4j bridge
you only relocate slf4j-api and slf4j-jdk14. it works
alright so when im building waterfall i put bungee cord in the Waterfall-Proxy folder correct?
When I run the script it says no pom.xml in waterfall-proxy server
Is there any public alternative to reconnect_yaml with redis support?
@trail plume http://i.insanemc.net/idea64_u6RlFo23LR.png i am trying to update my custom travertine fork with my own patches and i try to add 1.16.2+ support. But when i do that this error occurs.
[ERROR] The build could not read 1 project -> [Help 1] [ERROR] [ERROR] The project io.github.waterfallmc:waterfall-parent:1.16-R0.2-SNAPSHOT (C:\Users\joelb\OneDrive\Bureaublad\gay\Travertine\Travertine-Proxy\pom.xml) has 1 error [ERROR] Non-resolvable parent POM for io.github.waterfallmc:waterfall-parent:1.16-R0.2-SNAPSHOT: Could not find artifact io.github.waterfallmc:waterfall-super:pom:dev-SNAPSHOT and 'parent.relativePath' points at wrong local POM @ line 6, column 13 -> [Help 2] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException [ERROR] [Help 2] http://cwiki.apache.org/confluence/display/MAVEN/UnresolvableModelException
what is the correct version?
please read the rules; pinging core, devs, mods, or triage without a valid (this is a channel for help, anyone could help with this) reason ain't allowed
Then help ?
Nobody owes you support in any capacity
The error is also spelt out in english
: Could not find artifact io.github.waterfallmc:waterfall-super:pom:dev-SNAPSHOT and 'parent.relativePath' points at wrong local POM
The parent pom is incorrect
Or, at least, does not line up with that pom there
What's the repo for waterfall 
The Minecraft plugin is doing something wrong and I don't know where to start to fix it
though I would guess repo.destroystokyo.com is the same as papermc.io, i'm not entirely sure
it may also be that you omitted the R0 number
what dejay you are here too
Does Waterfall Support fast server switch?
.try
We don't know, nor do we support it, but, it might work 🤷♂️
Mhm. Fine. Thanks
*fast server switch: The hacky completely bad solution that uses fake dim switches
... which doesnt work in 1.16 and newer anyway
... and is not even as fast as a properly implemented normal switch
the normal server switch already uses fake dimension switches afaik. the fast one tried to not even do that but simply resend all the chunk stuff iirc
Well that’s out the window now
Also @trail plume the jank on that GitHub issue with invisible players is caused by that horrible half-assed tablist uuid rewriting Bungeecord does. Shiver would you accept an option to disable that in WF as a PR?
@wide maple the goal is switching without "black-screen" / "dim-switch-screen"
That won’t fly in 1.16 anymore at all
mhm. okay - thanks for your help 😛
if you’re curious as to why: https://github.com/SpigotMC/BungeeCord/pull/2861
@stone rover
The problem is that since 1.16.2+ the indexes of the biome registry that is now also sent have to match
If you want to modify the source to allow it- go for it
But I have to warn you
What I said about indexes still applies
You also have to modify the server most likely
mhm. not sure - maybe it will work in my case, but you are right - its not safe^^
what's tablist rewriting?
daaamnit cat
now i have to figure out configuration migration :(
i have tablist rewrite disabling in firefly as well
if get() != null, set, set to null, move on be happy
thank am happ now
what
move on, nothing to see here
the jank on that GitHub issue with invisible players is caused by that horrible half-assed tablist uuid rewriting Bungeecord does.
Yet more evidence proving that the decisions made in Velocity were the correct ones in the long run
Would it be ok to run a chat filter and chat logging on the proxy instead of each game server? since all messages go through that anyways, can't really see any disadvantage to it except it might cause more load on the proxy
you shouldnt put a lot of stress on the proxy imo
really depends on what kind of calculations you do
I personally do all chat stuff on the proxy, lol
all your checks happen on the network threads unless you take steps to pull off it, iirc
Can confirm
If you’re interrupting the packet queue especially
^ cancellable Events do that in that context
Ah right, so maybe better to handle logging on the proxy but any filters on each server
was thinking to have like regex chat filters
Trying to get MOTD to show hex colours but it always shows as red. I've confirmed that i'm getting the hex String and replacing correctly with ChatColor.of(hexval with #) but when i use it via new TextComponent(convertedText), When i use #6600cc it turns it into &c which i've noticed is probably because it changes to this when not a textcomponent: https://gyazo.com/253c28ac5cad5a561148fe44e311b536 Does anyone have any ideas how i should go about this?
Use components properly
or use the fromLegacy method on TextComponent, vanilla doesn't understand spigots hex horror show
Hello, i'm writing a Sponge plugin, and I have a number of sponge servers all running under a waterfall proxy. How can I redirect a player from one server to another programatically?
No idea of sponges API, but you'd send a plugin message
the waterfall proxy has to do the actual redirecting, right?
Yes
basically my sponge plugin would somehow have to inform the proxy to redirect
(DiscordBot) https://www.spigotmc.org/wiki/bukkit-bungee-plugin-messaging-channel/ -- Bukkit & Bungee Plugin Messaging Channel | SpigotMC - High...: "Aug 25, 2020 ... This page explains the Bukkit and BungeeCord plugin messaging channel. The channel allows plugins to communicate with the..."
The home of Spigot a high performance, no lag customized CraftBukkit Minecraft server API, and BungeeCord, the cloud server proxy.
ofc, you'd need to adopt for sponges API, but shouldn't be much different
bungeecord:main is the modern compat one iirc
(So, from whatever version they made that a namespace thing, use ^, otherwise, use the bungee one it says on there)
ok, that's useful
What about adding a new server to the proxy programatically? is that even possible?
You'd need a plugin on the proxy for that
so i'd somehow communicate to the plugin on the proxy to register the new server
and it would do that via the waterfall API?
yup
cool, thanks
is there a waterfall plugin build.gradle somewhere i could peek at? I see the artifact is pinned in here, but that's not all i'll need i'm assuming
public class AtherysProxyPlugin extends Plugin implements Listener {
@Override
public void onEnable() {
getProxy().registerChannel("atherysproxyplugin:main");
}
@EventHandler
public void onPluginMessage(PluginMessageEvent pluginMessageEvent) {
if ("atherysproxyplugin:main".equals(pluginMessageEvent.getTag())) {
// received message on the atherysproxyplugin:main channel
}
}
}
Is this the correct way to consume a plugin message on some channel? The one guide on spigot's website uses the PluginMessageListener interface, but that's not present in Bungee or Waterfall's API, only the Spigot API.
InetSocketAddress inetSocketAddress = new InetSocketAddress("1.1.1.1", 8080);
ServerInfo serverInfo = getProxy().constructServerInfo("test server", inetSocketAddress, "test", false);
getProxy().getServers().put("test-server", serverInfo);
and is this the intended way to dynamically register a new server with the proxy?
afaik, yes and yes
what is the url to the repository i need to add to my maven configuration to use the waterfall plugin api
same one as paper
apparently not
wrong artifact
oh
it was the one generated by the mc development idea plugin
also there isnt any autocomplete for the group or artifact so something else is wrong
Is it possible to know what is consuming ram in waterfall?
typical heap dumps for checking the heap, native memory is generally "good luck"
.paste
Please paste large logs to a pastebin: https://paste.gg
A sensible, modern pastebin. Share text and source code snippets with no hassle.
I mean, it basically says what the issue is
as for how you managed to run out of direct memory
Each netty thread uses like 16MB iirc for direct memory, so, either you just have too many netty threads configured, or, something else is eating memory
How can I find out?
🤷♂️
netty has a leak detector flag, but, really, i got no idea how you'd debug that stuff
native memory stuff is basically ass to deal with
could be
public class AtherysProxyPlugin extends Plugin implements Listener {
@Override
public void onEnable() {
getProxy().registerChannel("atherysproxy:main");
}
@EventHandler
public void onPluginMessage(PluginMessageEvent pluginMessageEvent) {
getSLF4JLogger().info(pluginMessageEvent.getTag() + ": " + new String (pluginMessageEvent.getData()));
if ("atherysproxy:main".equals(pluginMessageEvent.getTag())) {
ProxyCommand command = ProxyCommandService.getInstance().resolve(pluginMessageEvent.getData());
command.run();
}
}
}
Hi, i just want to make sure i'm intercepting plugin messages correctly, because using this code, I can't get anything on the proxy
not even the logger outputs anything in this case
Is the tag in the PluginMessageEvent the channel name or something else?
you need to register it
Am I not doing that in onEnable?
Aren't event handlers in the plugin main file automatically registered?
proxy doesn't care about registration
You need to make sure that it's registered on players, otherwise it's not gonna send it
how would i do that?
i mean, is this something i do on the proxy side, or on the plugin sending the messages?
Well, that's what registerChannel is supposed to do is send the registration for that over
So wait, registerChannel registers the channel not only on the proxy, but also on all of the server connected on the proxy? am I understanding this right?
yes
The server will only let you send messages for known channels
Wait, I misread
It's too... erm... idk, am braindead
You need to register the event listeners, as proxi said, nothing to do with the channels
Proxi, come babysit me thx
how do i register an event with the waterfall api though? 😄 this is getting to pretty noob-level questions I know, but the last time I wrote Spigot/Bukkit plugins was 4 years ago
I only have the waterfall api and nothing else in my proxy plugin project. Can I also add the bukkit/spigot api?
Yes, but, you'd not be able to use bungee stuff in spigot code and vice versa, given that they won't exist in those environments
So, you'd need some form of logical seperation between the two, which is where people go for multi-module setups
right, but this brings me back to my question, how do i register my event listener? 😄
same as on bukkit, through the method on the plugin manager
aha, right. Thank you very much, I didn't realize I even had to register mylistener 😄
and is the 1st byte ( at index 0 ) reserved or something? I keep getting a seemingly junk value in the first byte, with my actual message after that in the array
Beginner question (sorry in advance)
What is the easiest way to retrieve a list of all users connected to the proxy?
I am trying to update an old plugin (~2016) that used these two things:
BungeeCord.getInstance().getPlayers().size()
BungeeCord.getInstance().getPlayers())
Besides not working in current versions, I haven't even figured out how that originally worked.
I have extracted the API javadocs from bungee build 1188, but couldn't find any mention of it.
use Proxy.getInstance()
Thanks!
For some weird reason, this plugin was using BungeeCord.getInstance() for something which is completely doable via the API
(The BungeeCord class is internal implementation and could change unexpectedly)
oh sorry, I think it's ProxyServer
I think it might still need an import (sorry; I am quite new to a lot of this stuff)
usually your IDE will suggest imports
Currently have this
so remove that import
ah, thanks, found it
net.md_5.bungee.api.ProxyServer
How would one go about having multiple authors in bungee.yml?
I attempted the bukkit authors: [1, 2, 3] in that screenshot
It's nothing to do with yaml
authors: [1, 2, 3] fails to load bungee.yml
author: [1, 2, 3] produces null
Bungee wants a string there
Is there a reason bungeecord, and subsequently waterfall ignore events handlers in superclasses?
This is not the same registration behaviour from bukkit
That's just how bungees event API is implemented
It follows the "norm" of event systems, but, somewhat bleh considering how it's all subclassed, etc
Thats like... pretty shitty though?
Well, yes, but, bungee
no they don't
Bukkit lets you determine how that works
bungee, the event you listen to is the class that was fired
I read the question wrong my bad
Wait I think you both misunderstood.....
abstract class Super implements Listener {
protected abstract void handle(SomeEvent event)
@EventHandler
public void onSomeEvent(SomeEvent event) {
handle(event)
}
}
final class SomeImplementation extends Super {
@Override
protected void handle(SomeEvent event) {
// code here
}
}
// somewhere else
proxy.pluginManager.registerEvents(somePlugin, new SomeImplementation())
This will not work on bungee
But it does work on spigot/paper
Bungee searches for event handlers with Class#getDeclaredMethods only
but spigot/paper uses both Class#getMethods and Class#getDeclaredMethods
oh
Issue already exists
And he said its a wontfix because
The only approach then is to implement logic to climb the class hierarchy which imo is overkill.
Which is just... not true...
bukkit does this... which is... honestly some really weird code
all done
lmao
so someone tried 4 years ago already and that's exactly how i guessed it'd go
md just doesn't want to do shit
it's his ball, but he doesn't want to play nor let anyone else to
He could quite literally just copy paste the code, and it would cause 0 issues
suggesting violating open source licenses 👀
?
you can't just copy Bukkit code into Bungee xD Bukkit is under GPLv3
What about GPLv3 prohibits copying a specific piece of code from one project to another?
that the pirce of code is copyrighted and the GPLv3 doesn't allow using it in incompatible projects?
*piece
Define incompatible
The copyright prohibits you from including the code in proprietary work that does not allow the release of the source itself alongside it
Both of which are conditions bungeecord does not fall under
Bungee isn't under an open source license, GPLv3 requires that the license is GPLv3 compatible and that the combined work (the download) needs to be distributed under the GPLv3 or an even stricter copyleft license
and bungee can't be distributed under the GPLv3 without a re-licensing of it
it's BSD 3-Claus with an extra non-commercial clause which makes it non-free
*3-Clause
oh, i see
Where is the actual line drawn here though?
wherever a court would decide
The implication of the license is that it must be redistributed with a modified version of the program
4 lines of code is not the program
4 lines might be an extreme complex calculation, I assume it would depend on the overall impact and whether or not it could be easily written differently or not
remember, you can fit a lot into 4 lines of code
How is that complex?
(assuming your code style is bad)
how is what complex? I am talking purely theoretically, no code was ever linked ;)
I posted a screenshot of the code
4 lines was a hyperbole
I'm referring to the way the bukkit code unions the two method arrays
Technically, it could be one line
but whatever
I would say "don't do the hashset size specification and you would probably be good"
also I personally would just use putall, lol
Streams
so yeah, if you copy that 1:1 it would be greater risk of copyright violation seeing as there are lots of alternatives
PaperMC Discord, where professional lawyers discuss implications of theoretically incompatible licences that realistically aren't enforced and their implicate
whether or not it would actually have any impact beyond "yeah, it's stolen but dude, it has zero impact" is for a judge to decide
I mean, the GPLv3 was "enforced" on CraftBukkit so...
or well, I guess technically it was the LGPLv3
granted one could argue that CraftBukkit inherits Bukkit's license if APIs are really copyrightable but ¯_(ツ)_/¯
I personally don't believe in the "copyrightable API specifications" argument and act accordingly lol
wat
LMFAO
❓
It was a joke..
Ya know... about how OOP breeds an obsession with deep inheritance based applications
jokes about oop in basically a java community
damn your life must be really miserable when you can make jokes what only you'd laugh over
:/
Does it make you feel better to say things like that?
tbh that whole argument is moot: everything should be GPLv3 anyways, otherwise why even bother with open source?
To put other people down?
runs
I prefer a good MIT or Apache License 2.0 personally
yes sxtanna
sounds like somethign someone who doesn't hate proprietary software would say
Not to mention my original comment wasn't even suggesting he actually copy paste it
It was just to show that what he said in the issue was completely incorrect
"<Sxtanna> He could quite literally just copy paste the code, and it would cause 0 issues"
Yeah, he could...
I replied to the "0 issues" part
I prefer open source software, but don't care if proprietary stuff uses my code.
I was referring to the issues he raised in the github issue though
well you didn't say that ¯_(ツ)_/¯
@bleak current You don't think that is a little more indicative of your life being miserable?
you can't expect people to read everything you ever said :P
( ͡° ͜ʖ ͡°)
@potent lichen What did you mean in your comment?
smh my head
which one?
@potent lichen on github
As much as I would support this idea, it is unfortunately an API break for anyone defining and using their own hierarchy of events, such as in a plugin API.
I meant exactly what I said. I don't know how to say it otherwise
at this point it's true
What does a hierarchy of events have to do with the issue?
yeah, everyone working around this behaviour would have their events run twice then
That's the whole subject of the issue
No its not???
It has nothing to do with the event class
It has to do with implementers of the Listener interface
The event bus doesn't register listeners in super classes
I didn't say anything about Listener implementations
But thats what the issue is about?
Maybe I misinterpreted this issue
You quoting like that is throwing me off so hard xD
Like before with the license thing, I thought you were hinting at a rule I broke or something
No, sxtanna is right
no? lmao
Not for phoenix
fix your damn clients lmao
you realise that "greentext" is just 4chan-quotes, right?
But youre... quoting
not my problem if discord didn't decide to display the >
(or properly format quotes green)
> this will be the only time I'm doing that though :P
I mean, that's the bot's issue then
How would you even introduce convenient interop for that
it's easy: you realise that greentext is a well-established internet meme so you take the context in consideration when reading any quote on platforms other than 4chan
No, I know how to fix it
I'm just saying it would kinda suck to completely remove the ability to do it
Yeah, but it doesn't look like that for us phoenix
It just looks like youre literally quoting someone else
it looks exactly like a quote what are you talking about?

@potent lichen https://github.com/SpigotMC/BungeeCord/issues/2694
As it so happens, what you are referring to was also addressed in another issue
also I mean my comment literally was a "quote", not a literal one but one of the "action taken"
@tulip otter There's always Velocity if you don't want to deal with BungeeCord's... strange approach to things
@weary grove Velocity uses kyori event library
Which looks like it literally just does the exact same thing
Only calls getDeclaredMethods
With an interface called MethodScanner https://github.com/KyoriPowered/event/blob/master/method/src/main/java/net/kyori/event/method/MethodScanner.java#L37
That doesn't even scan methods
It filters and classifies them
Both have "strange" approaches
@sage cradle ^
Actually Bukkit is the weird one
For example, here is an event bus library that is very popular on Android. It uses getDeclaredMethods (with a fallback for some Android-specific quirks): https://github.com/greenrobot/EventBus/blob/34a1537af7364cec9444a24431c566d434d4d0b8/EventBus/src/org/greenrobot/eventbus/SubscriberMethodFinder.java#L150
If you scroll up a bit, you will see that they look in super classes
yeah I scrolled too far down
Well maybe we can think about scooting up the superclass hierarchy.
It legit just doesnt make sense to not look in super classes
You arent registering this specific class, youre registering this instance of this object
Imagine if you only had access to call methods of the class you have a reference to
Completely defeats the purpose of inheritance
Well, if you're me, you prefer composition over inheritance anyway.
does anybody know what could make SnakeYaml not find a certain class for loading an object from a config?
(and yes, I can access the class before trying to laod the config xD)
Exception?
Snake won't be in the context of the classloader of stuff
well, of plugins, don't think that there is anything for that
hm
yeah, seems to be the case. meh
now to figure out how to change that 👀
I guess that's where paper's way of loading plugin-classes before existing ones would come in handy 
can one like hide classes of a different class loader? xD
ok apparently one can just use a custom class loader for yaml constructors
Actually Bukkit is the weird one
@weary grove blame me, scanning superclasses was sth I specifically added when I did bukkit
I think it seemed like it could be useful
git blame exists for this very reason!
and then CB came along
find bad apis, check the blame, ping them with your complaints!
Bukkit isn't even the weird one
Even the guava event bus gets methods from super classes
it does make more sense to recognise inherited methods
Sxtanna put it best - you're registering an object instance as a listener, not a class. Its methods are not only those declared.
@tulip otter well, I'm planning a total redo of the Velocity event system and yes, we'll iterate superclasses when the time comes
Well isn't that just lovely
What are you going to actually do? @weary grove
bungeecord api support for velocity when??!???
didn't someone already write a compat layer?
if not that seems really easy to write
@tulip otter mainly improvements around async handling of events
planning to prototype it outside of Velocity and it will be called PALEO (mainly as a joke)
but the premise is very serious
Interesting
basic idea: every event listener is part of a linked list, and an event listener is free to "interrupt" the execution of the event listeners, do some async thing, then modify the result and continue as if nothing had happened
with no interference in the event or race conditions
it will also be amenable to concurrent (de)registration of listeners, such that listener state remains consistent
and an event listener is free to "interrupt" the execution of the event listeners, do some async thing, then modify the result and continue as if nothing had happened
What does this do to the call site though?
See, in part that doesn't make sense to me, you're still blocking the executor, so you're going to want to be in an async context there already
best I can see is maybe you can free up the event thread earlier for some form of "post it back to there once you're done"
it would probably make sense to define two kinds of listeners: 1.) simple ones, which are similar to those in the current system 2.) forwarding ones, which are able to asynchronously continue event execution, such as through some controller object
It’s not going to allow blocking at all.
And we are making all events “forwarding” event listeners
There is method behind this madness, you’ll have to see for yourself
How is it possible that its non blocking and forwarding?
Do you have to supply a callback to the eventbus or something?
No callbacks.
Ok, how?
I mean, I'll have to wait to see your impl to see what you mean
But, this sounds like DFU territory
I’m not going to go full Mojang 
Are you going to explain?
I think I can explain more once this isn’t literally a sketch out in my head
Perhaps it will be best if you wait for the end product
meh, I don't think I care that much
I will never use velocity, so it doesnt really apply to me
I will never use velocity, so it doesnt really apply to me
But why?
It’s what Waterfall should’ve been but couldn’t be.
I have 0 reason to
I am the founder of the Waterfall project.
velocity's api is great and its implementation very much the same ^^
each to their own tho i suppose
Don't get me wrong, I am definitely not a purveyor of superiority in any direction
I don't really care for either API xD
i wouldnt be recommending it this much if bungee managed at least to nullability annotate its api tbh
switching to velocity! :D
What?
Just to let you know, the code generated by kotlin automatically inserts nullability annotations
When youre using it from kotlin, kotlin knows the nullability because its kotlin, and Java knows the nullability because of the annotations
You dont have to use kotlin yourself to benefit from it
Thats not a serious question?
Thats... not what I said
i mean, bungee uses lombok in the API...
The implication was that bungee would be written in Kotlin
Thats the simple solution to nullability ambiguity
how does kotlin tooling know whether a Java method returns null? Only a nullability annotation makes that possible
Otherwise, kotlin has no idea of knowing what is nonnull
hence its 'platform types'
The implication was that bungee would be written in Kotlin
rewriting bungee from scratch... sounds like velocity
sure we'll rewrite Velocity in Kotlin 
I never presented what I said as an actual suggestion
@weary grove Yeah, you really should though
For multiple reasons
JRoy 👀
you know, as much as it pains me to say it, in this case 
you shouldn't shit into your ide in public
please kotlin in the privacy in your own home
joke's on you i don't go out!
@sage cradle why do you say that?
Are you joking?
No we aren't. Kotlin really allows you to fuck up code readability really bad. Without IDE seaching for where the hell those bunch of extensions methods were defined is a pain.
Tell me, how do you resolve static members without IDE searching?
you're probably young
What??
you praise the kotlin god
you've been staring at the kotlin sun for too long that its burnt your retinas
you don't understand common sense anymore
and think kotlin is the best programming language ever
You don't search statics, because nobody in braindead enough to use static imports.
Who said anything about static imports?
Kotlin is great tho, just not a replacement for java.
Kotlin is 100% a replacement for Java
technically yes, effectively no
@civic valve I don't understand why you're so angry about this...
Both technically and effectively
It does everything Java does, but better in every way
because you say shit like that
No, it doos poor at making code readable.
Some other things, like built-in nullability is great.
because you say shit like that
What does it not do better?
Its not "built in nullability"
Its an unambiguous nullability type system
I’ve seen Kotlin produce bytecode that does a lot of unnecessary stuff and is slower ultimately than the java counterpart. I am not on Kotlins side either. If kotlin were also able to run natively then we could talk about it
The type system is WAY better too
@wide maple It does
It compiles to JS, the JVM, and Native code
And you can disable the compiler intrinsics
Nah, the performance isn't usually a problem, since we are talking about GC based languages anyway.
People often do so when targeting platforms that are bitchy about it, like android
What does it not do better?
Syntax sucks, very bad readability, the bytecode gen is just bad, decompiling is a nightmare, forced nullability is meh but you should be writing proper code that has nullability checks in the first place
@civic valve Ok, so you're just ignorant...
New idea- rewrite your anticheat in kotlin and nobody will ever be able to decompile it ever again
Thats fine, we can work on that

Sorry do you have any job in the programming field in the real world
The thing is that, the readability is why are we writing java. If i wanted to type in shit faster i could just have used python, which i do.
Kotlin is perfectly decompilable?
holy shit
It literally compiles to the same JVM bytecode as Java???

I disagree. Name one decompiler that doesn’t crap itself after 3 sec of kotlin decompiling
Many doesn't, but high level code result is crap anyway.
IntelliJ's
barely
^
I'm also certain JD-GUI has 0 problems as well
Syntax sucks, very bad readability
Please do elaborate on this
I find this topic extremely interesting
var
The thing is, as long you aren't a single person in the team, you will suddenly find out that readability of the code is what it matter, and not the writing speed.
@wide maple Why are we even considering decompilability as a metric for a front end language
@civic valve What about var?
because decompiling is a big part of JVM culture?
holy shit
Here is an example val withdrawPlan = player.inventory.createWithdrawPlan(...)
Can we arrive at the truth already that- while maybe nice- Kotlin will never find the space in this community it’s so desperately trying to get and that for a good few reasons
Now find what's where using only notepad
@wide maple Because youre gatekeeping it
@real cave ?
Also a lot of people don’t want to re-learn how to code things in java
That single line alone would not be an entire file
You would have imports
@wide maple why would you need to relearn Java?
And what about Java libraries is the crux?
Widely different syntax for one, lots of crashes with libraries using native callbacks for two (yes that’s why the android people complain and I do too)
How is that readable-
When projects get complex it just isn’t usable and does fail a lot
What do you mean how is it readable??
anyways to explain why the syntax is shit;
varyou take more time to figure out what the variable actually is when you usevarand can get to a point where it's impossible without an IDE- instance-creation expression isn't clear and very confusing
- they literally sprinkle single characters all over the place to live their null-free dream
- variable assignments aren't expressions
- no ternary operator
- no automatic type casting
- Generics is hell
- no sane structure syntax
Its java code with annotations???
- var you take more time to figure out what the variable actually is when you use var and can get to a point where it's impossible without an IDE
var in kotlin is not type inference
var for type inference is a Java 10 thing
kotlin uses var more
Kotlin uses var and val to indicate mutability and immutability
nobody uses var in java
var = mutable
val = immutable
you're missing the point
var thisCanChange: Int = 10
val thisCannotChange: Int = 20
No, you're wrong....
I'm not missing anything
shit syntax still
int varName = 10;
var varName: Int = 10;
- instance-creation expression isn't clear and very confusing
Its the exact same as Java, but withoutnew
Kotlin doesnt require semicolons
Also bad
^

Call me old fashioned but I am used to have two instructions in one line if it helps cement my logic
So what I've learned is that you guys dont actually hate kotlin for a reason, you just dont understand it
or reduces patch size!
@tulip otter no
You didn't learn shit
because you don't want to
* variable assignments aren't expressions
* no ternary operator
These are two things that most people who come from Java appreciate the most
you think kotlin is perfect
Kotlin already has a ternary syntax for something else
Multiple ternaries doesn't make sense
And the kotlin if else is an expression
that's worse syntax
it's correct
Kotlin has BETTER auto casting than Java
Kotlin syntax is a mix of python syntax and something else.
unless changed recently
So if you have used python you would be very familiar with the syntax
val object: Any = "Hello"
if (object is String) {
println(object.length)
}
Kotlin syntax is a mix of python syntax and something else.
takes the bad parts of java, php, js, and python and shits on them
Kotlin has always had better auto casting
Its baked into the kotlin type system and program flow
that's not auto casting
n o
Its automatically casting object to String after you confirm its a string
not the kind I'm talking about
You won’t find turf in the minecraft community with Kotlin. It’s a niche here if anything
The one thing I know that Kotlin has and java doesn’t (which isn’t necessarily good) is KotlinExposed
Are you talking about type coercion??
Like for numbers?
Because thats not casting
Not even in Java
And youve just been attacking me for no reason
- Generics is hell
- no sane structure syntax
This just doesnt make sense
Kotlin has WAY better generic projection syntax

And the structure of almost everything is way more concise and simple
Like what do you mean generics are hell?
reified generics are great tho, just sometimes they get in the way.
They dont get in the way dude, they have a specific purpose, and if you arent using them within the bounds of that purpose, they dont work
Thats like.. everything
And reified generics arent even a part of the generic system
Its syntax sugar
Lord have mercy on my soul
Here is my issue with Kotlin in the minecraft community.
Java is why modding is popular
The java syntax is fine because it’s easy and simple and doesn’t have many complicated functions (I’ll regret that phrase later).
A lot of people know java code
We have a vivid modding or modifying community as a result
Were you to convert the backend of that to Kotlin not only would you alienate yourself from the community-
You’d also make it harder for yourself to get people interested in your project aside form a small niche group
@wide maple It is a very different statement to make that Kotlin is a bad language and Kotlin does not fit into the community
(which are both just objectively incorrect things to say)
And this should not be your "issue with Kotlin"
Kotlin exists whether you like it or not
But that’s sadly true for anything Kotlin I’ve seen so far

Android has literal CENTURIES of being Java everything
Did I mention natives along the way with that regard? Marketing is a lot of what drives this too
But its adoption and transition to being mostly kotlin has been huge
If you give people way too much tools to make things go wrong, they will do it. So you have to not give people the tools to shoot the foot.
The more different syntax sugar you have, the harder it to read the code, but the easier it is to write the code.
Kotlin has more syntax sugar than java, and way more tools to do shit wrong.
That's why you can't directly compare it to java.
Literally the only language you can compare and exchange java with is Go
@civic valve bruh... WHAT
name big apps written in kotlin?
facebooks entire app suite is java/react
netflix is java/react
Pinterest, Postmates, Evernote, Uber, Square
not all google apps
BRUH
uber being the biggest
You're in so much denial
Android forcing kotlin is a political thing, not preference btw.
It pains me
yeah switch to general
Android does not force Kotlin
People just fucking like Kotlin
Its a good language xD
hello, how can i connect a player when i have deleted the "default server"
i tested with a "connect" on post login but it doesn't work
Velocity 1.1.0 handles this case a lot better
Hey guys!
I'm trying to write a plugin that'll check the server uptime of a proxy server, how's this possible?
Right now I have the code to checking if the server is online / offline, but how can I get the uptime? Could I send like a command to the server and get the output back?
you don't without running a plugin on that server
either get the data manually or use your own custom command sender to get the feedback of some command that you run
I use this one for that: https://code.minebench.de/Minebench/Minequery
it would be one solution

