Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Multiple Listeners (2+ ports bind + with unique motd and other) #1046

Open
softy-oniguru opened this issue Jul 25, 2023 · 17 comments
Open
Labels
type: feature New feature or request

Comments

@softy-oniguru
Copy link

softy-oniguru commented Jul 25, 2023

I would like to see this function in Velocity, because after switching from Bungeecord I could not find it. In Bungeecord, this is implemented using:

listeners:
    - server1: "address"
    motd: "Welcome to server1"
    ...something...
    
    - server2: "address"
    motd: "Welcome to server2"
    ...something...

I think you can also implement this somehow using lists, just specify a separate section in the config named [Network] and make a list of servers and connection data into it (bind, motd, show-max-players, online-mode)

My idea about it in the config:

[network]
bind = "localhost:25565"
motd = "<#09add3>A Velocity Server"
show-max-players = 500
#online-mode = true (I think this can be a difficult task, because it is not implemented even in bungeecord)

[network]
bind = "localhost:25566"
motd = "<#d3ad09>A Velocity Server"
show-max-players = 250
#online-mode = false

in JSON form it would look like:

{
  "network": [
    { "bind": "localhost:25565", "motd": "<#09add3>A Velocity Server", "show-max-players": 250, "online-mode": true},
    { "bind": "localhost:25566", "motd": "<#d3ad09>A Velocity Server", "show-max-players": 500, "online-mode": false}
  ]
}

I don't know English well, I use a translator, so there may be inaccuracies in the translation.

@softy-oniguru
Copy link
Author

softy-oniguru commented Jul 25, 2023

I feel like this will get in a future 4.0.0 update xd
we are waiting for update in 2024 💀

@JustEli
Copy link

JustEli commented Jul 29, 2023

Fully agreed. Would be extremely useful for bigger networks that want to move to Velocity but are currently stuck on Bungee. I would love to see the possibility to bind multiple IP addresses to different servers (like you can with Bungee).

@Nacioszeczek Nacioszeczek added the type: feature New feature or request label Aug 12, 2023
@PedroMPagani
Copy link

why not launch 2 velocities? -> you kind of want 2 netty servers so ;O

@PedroMPagani
Copy link

and btw, if you dont know this, you can already do it, you can track hostnames and you can just bind the 0.0.0.0 or the two ips to ptero and velocity on 0.0.0.0, both ips will forward requests.

@JustEli
Copy link

JustEli commented Oct 3, 2023

why not launch 2 velocities? -> you kind of want 2 netty servers so ;O

Because then you can't send players around between servers.

and btw, if you dont know this, you can already do it, you can track hostnames and you can just bind the 0.0.0.0 or the two ips to ptero and velocity on 0.0.0.0, both ips will forward requests.

It's not an ideal solution, but I'm currently doing something like that. Not ideal, because for one, if you have players with 3 of your servers in their list, it tends to time out the ping for the later ones in their server list, because they are pinging the same netty server multiple times for multiple servers. It's not only for that reason tho.

@PedroMPagani
Copy link

  1. YOU mean send between backend servers?
  2. Are you saying that if they ping the same netty server the ping is denied? Are you using any anti ddos service here or are you talking about direct-ip connect?

@MrPowerGamerBR
Copy link

MrPowerGamerBR commented Oct 27, 2023

Here's another use case that I'm currently using in Waterfall that can't be currently reproduced in Velocity:

Currently my setup is Waterfall + Geyser (standalone), the Waterfall proxy has two listeners: One that is open to everyone, and another localhost bound listener with PROXY protocol enabled. This works, and it is nifty since I'm able to know what connections are Java or Bedrock connections by looking up what listener they connected to, and I can update the Geyser proxy without restarting the Waterfall proxy

However I don't know how I could replicate this setup easily with Velocity, because Velocity doesn't support multiple listeners


I thought about running Geyser directly in Velocity, but then every time I need to update Geyser, I need to restart the entire Velocity proxy. I also have some code that checks if the user is connected via Geyser in PreLoginEvent, and Geyser's API can only check if a player is a Geyser player by its UUID. (which, sadly, the UUID is not present during the PreLoginEvent phase)

I thought about running two Velocity instances, but that's bad since I wouldn't have a "single source of truth" of how many players are connected to the server, and proxy wide broadcasts would be completely borked. (Yes, I know there are solutions about this, such as running RedisBungee and stuff like that... but I would rather not do this)

I thought about running Velocity (connected via PROXY protocol) -> Velocity <- Geyser (connected via PROXY protocol), but it seems that if you are doing Velocity to Velocity connections, you are probably doing something very wrong.

It seems that maybe the solution would be Velocity (with PROXY protocol), then Geyser connects to Velocity and then you have a nginx server running PROXY protocol that redirects Java players to the Velocity instance.

However, it makes the system way more complex compared to the simplicity of setting up two listeners instead.

@xism4
Copy link
Contributor

xism4 commented Oct 27, 2023

Here's another use case that I'm currently using in Waterfall that can't be currently reproduced in Velocity:

Currently my setup is Waterfall + Geyser (standalone), the Waterfall proxy has two listeners: One that is open to everyone, and another localhost bound listener with PROXY protocol enabled. This works, and it is nifty since I'm able to know what connections are Java or Bedrock connections by looking up what listener they connected to, and I can update the Geyser proxy without restarting the Waterfall proxy

However I don't know how I could replicate this setup easily with Velocity, because Velocity doesn't support multiple listeners

I thought about running Geyser directly in Velocity, but then every time I need to update Geyser, I need to restart the entire Velocity proxy. I also have some code that checks if the user is connected via Geyser in PreLoginEvent, and Geyser's API can only check if a player is a Geyser player by its UUID. (which, sadly, the UUID is not present during the PreLoginEvent phase)

I thought about running two Velocity instances, but that's bad since I wouldn't have a "single source of truth" of how many players are connected to the server, and proxy wide broadcasts would be completely borked. (Yes, I know there are solutions about this, such as running RedisBungee and stuff like that... but I would rather not do this)

I thought about running Velocity (connected via PROXY protocol) -> Velocity <- Geyser (connected via PROXY protocol), but it seems that if you are doing Velocity to Velocity connections, you are probably doing something very wrong.

It seems that maybe the solution would be Velocity (with PROXY protocol), then Geyser connects to Velocity and then you have a nginx server running PROXY protocol that redirects Java players to the Velocity instance.

However, it makes the system way more complex compared to the simplicity of setting up two listeners instead.

You can use redisbungee

@MrPowerGamerBR
Copy link

Here's another use case that I'm currently using in Waterfall that can't be currently reproduced in Velocity:
Currently my setup is Waterfall + Geyser (standalone), the Waterfall proxy has two listeners: One that is open to everyone, and another localhost bound listener with PROXY protocol enabled. This works, and it is nifty since I'm able to know what connections are Java or Bedrock connections by looking up what listener they connected to, and I can update the Geyser proxy without restarting the Waterfall proxy
However I don't know how I could replicate this setup easily with Velocity, because Velocity doesn't support multiple listeners
I thought about running Geyser directly in Velocity, but then every time I need to update Geyser, I need to restart the entire Velocity proxy. I also have some code that checks if the user is connected via Geyser in PreLoginEvent, and Geyser's API can only check if a player is a Geyser player by its UUID. (which, sadly, the UUID is not present during the PreLoginEvent phase)
I thought about running two Velocity instances, but that's bad since I wouldn't have a "single source of truth" of how many players are connected to the server, and proxy wide broadcasts would be completely borked. (Yes, I know there are solutions about this, such as running RedisBungee and stuff like that... but I would rather not do this)
I thought about running Velocity (connected via PROXY protocol) -> Velocity <- Geyser (connected via PROXY protocol), but it seems that if you are doing Velocity to Velocity connections, you are probably doing something very wrong.
It seems that maybe the solution would be Velocity (with PROXY protocol), then Geyser connects to Velocity and then you have a nginx server running PROXY protocol that redirects Java players to the Velocity instance.
However, it makes the system way more complex compared to the simplicity of setting up two listeners instead.

You can use redisbungee

I could, but this makes the stack way more complex since I would need to host a Redis instance AND host two separate Velocity instances.

Here's the solution that I came up with: I forked Velocity and exposed the ConnectionManager to let plugins to be able to setup binds, each bind with their custom settings

Then in my plugin I setup the listeners two listeners: One for Java Edition, then another localhost only bind with PROXY protocol enabled for Geyser, making it work like Bungee's multi listener support.

You may be thinking "well that's more complex than using RedisBungee and two Velocity instances!!!" and to that I say: smh let me have fun it wasn't even that hard 😭

@RezzedUp
Copy link

With the recently announced end of life of Waterfall, the only thing keeping me back from migrating over to Velocity is the lack of this specific feature.

My use case is as follows: I essentially run a group of independent but loosely related servers which happen to share a network. Each one is directly joinable and there is no centralized hub. Now, why would I want independent listeners with distinct configuration? Server lists. I obviously can't reuse the same IP/port for each server, since server lists would correctly identify them as "the same server". With my current setup, I'm able to run several distinct communities under the same network while simultaneously assigning each server a different publicly accessible port rather than simply relying on something like forced hosts.

@PedroMPagani
Copy link

would forced hosts not work for you?

@RezzedUp
Copy link

would forced hosts not work for you?

No. Again, each one of my servers needs a unique IP/port in order to be listed separately on server lists. I currently achieve this on Waterfall by having multiple listeners bound to different ports. Since Velocity only supports one listener (one port binding) for the entire proxy, forced hosts obviously won't solve this problem.

@PedroMPagani
Copy link

pay someone to impl this on velocity

@MrPowerGamerBR
Copy link

MrPowerGamerBR commented Mar 29, 2024

pay someone to impl this on velocity

Implementing this is not that hard, the only reason Velocity does not support this yet is because of Velocity's configuration format iirc (I may be wrong, check it on PaperMC's Discord server when I asked about it there)

If they just want to migrate to Velocity now with a stop gap solution, it isn't hard to expose the connection manager to plugins

https://github.com/SparklyPower/SparklyVelocity

@PedroMPagani
Copy link

do it

@JustEli
Copy link

JustEli commented Mar 29, 2024

pay someone to impl this on velocity

Implementing this is not that hard, the only reason Velocity does not support this yet is because of Velocity's configuration format iirc (I may be wrong, check it on PaperMC's Discord server when I asked about it there)

If they just want to migrate to Velocity now with a stop gap solution, it isn't hard to expose the connection manager to plugins

https://github.com/SparklyPower/SparklyVelocity

pull request when

@alexstaeding
Copy link
Contributor

alexstaeding commented Mar 29, 2024

would forced hosts not work for you?

No. Again, each one of my servers needs a unique IP/port in order to be listed separately on server lists. I currently achieve this on Waterfall by having multiple listeners bound to different ports. Since Velocity only supports one listener (one port binding) for the entire proxy, forced hosts obviously won't solve this problem.

Would it not be possible to set up multiple NAT mappings to the same internal ip and port? This way you expose multiple ports externally.

You can also achieve a similar result if you have access to multiple external IPs - it shouldn't be a problem to pass L4 packets from multiple IPs/ports to your velocity instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: feature New feature or request
Projects
None yet
Development

No branches or pull requests

8 participants