Skip to content

Commit 3704955

Browse files
committed
changed to LOWEST_PLAYERS for lobby balance & impl docs
1 parent f8e100f commit 3704955

File tree

5 files changed

+109
-3
lines changed

5 files changed

+109
-3
lines changed

README.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,108 @@
44

55
**RedisBridge** is a complete rewrite of my previous plugin [JBridge](https://github.com/JossArchived/JBridge), developed for Nukkit and WaterdogPE. It provides automatic server registration, player management, and seamless communication between backend servers and the proxy.
66

7+
# ⚙️ Available Commands
8+
RedisBridge includes ready-to-use commands for your proxy (WaterdogPE, Velocity, BungeeCord) or backend servers:
9+
10+
- `/lobby`
11+
Teleports the player to an available lobby instance using the `LOWEST_PLAYERS` strategy to avoid overloading a single lobby while keeping activity balanced.
12+
13+
- `/transfer <server>`
14+
Transfers the player to a specific instance if available. Useful for networks with multiple game modes.
15+
16+
- `/whereami`
17+
Displays information to the player showing which instance and group they are currently in, along with the number of players and instance capacity.
18+
19+
# 📡 Instance Management Usage
20+
RedisBridge includes a **distributed instance discovery and selection system** for minigame servers, lobbies, or backend servers using Redis and a low-latency distributed cache.
21+
22+
Each server instance sends **automatic heartbeats** via `InstanceHeartbeatMessage` containing:
23+
24+
- `id` (unique identifier)
25+
26+
- `group` (e.g., `lobby`, `solo_skywars`, `duels`)
27+
28+
- `players` (current online players)
29+
30+
- `maxPlayers` (maximum capacity)
31+
32+
- `host` and `port`
33+
34+
This allows other servers and the proxy to know in real time which instances are available, their capacity, and their status.
35+
36+
The `InstanceManager`:
37+
38+
- Uses a local cache with a 10-second expiration to keep instance state updated efficiently.
39+
40+
- Allows you to:
41+
42+
- Retrieve instances by ID (`getInstanceById`)
43+
44+
- Retrieve all instances in a group (`getGroupInstances`)
45+
46+
- Get total player counts or per group (`getTotalPlayerCount`, `getGroupPlayerCount`)
47+
48+
- Get total maximum player capacity or per group (`getTotalMaxPlayers`, `getGroupMaxPlayers`)
49+
50+
Provides **automatic available instance selection** using different strategies:
51+
52+
- `RANDOM`: Selects a random instance in the group.
53+
54+
- `LOWEST_PLAYERS`: Selects the instance with the fewest players.
55+
56+
- `MOST_PLAYERS_AVAILABLE`: Selects the instance with the most players.
57+
58+
Example:
59+
60+
```java
61+
InstanceInfo instance = InstanceManager.getInstance().selectAvailableInstance("lobby", InstanceManager.SelectionStrategy.LOWEST_PLAYERS);
62+
63+
if (instance != null) {
64+
// Connect player to this instance
65+
}
66+
```
67+
68+
This system enables your network to distribute players dynamically without relying on a heavy centralized matchmaking server.
69+
70+
# 🚀 Communication Usage
71+
RedisBridge simplifies inter-server communication over Redis, enabling you to publish and subscribe to messages seamlessly between your proxy and backend servers.
72+
73+
## How it works?
74+
- Uses Redis Pub/Sub on a single channel (redis-bridge-channel) for all message transmission.
75+
76+
- Messages are serialized in JSON and identified using their type field.
77+
78+
- Each message type can have:
79+
80+
- A registered class (MessageRegistry) for deserialization.
81+
82+
- An optional handler (MessageHandlerRegistry) for automatic processing when received.
83+
84+
- Includes default messages for instance heartbeat and shutdown announcements to enable automatic instance tracking.
85+
86+
## Publishing Messages
87+
To send a message to all connected instances:
88+
```java
89+
YourCustomMessage message = new YourCustomMessage();
90+
// fill your message data here
91+
92+
redisBridge.publish(message, "sender-id");
93+
```
94+
95+
## Handling Incoming Messages
96+
- Register your message type:
97+
```java
98+
MessageRegistry.register("your-message-type", YourCustomMessage.class);
99+
```
100+
- Register your message handler:
101+
```java
102+
MessageHandlerRegistry.register("your-message-type", new MessageHandler<YourCustomMessage>() {
103+
@Override
104+
public void handle(YourCustomMessage message) {
105+
// handle your message here
106+
}
107+
});
108+
```
7109

8110
## License
9111
**RedisBridge** is licensed under the [MIT License](./LICENSE). Feel free to use, modify, and distribute it in your projects.

core/src/main/java/net/josscoder/redisbridge/core/RedisBridgeCore.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
import redis.clients.jedis.JedisPool;
1616
import redis.clients.jedis.JedisPubSub;
1717

18+
/**
19+
* Part of this code is taken from:
20+
* <a href="https://github.com/theminecoder/DynamicServers/blob/master/dynamicservers-common/src/main/java/me/theminecoder/dynamicservers/DynamicServersCore.java">DynamicServers</a>
21+
*/
1822
public class RedisBridgeCore {
1923

2024
public static final String CHANNEL = "redis-bridge-channel";

nukkit/src/main/java/net/josscoder/redisbridge/nukkit/command/LobbyCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public boolean execute(CommandSender sender, String label, String[] args) {
2525

2626
InstanceInfo availableInstance = InstanceManager.getInstance().selectAvailableInstance(
2727
"lobby",
28-
InstanceManager.SelectionStrategy.MOST_PLAYERS_AVAILABLE
28+
InstanceManager.SelectionStrategy.LOWEST_PLAYERS
2929
);
3030
if (availableInstance == null) {
3131
player.sendMessage(TextFormat.RED + "There are no lobbies available!");

waterdogpe/src/main/java/net/josscoder/redisbridge/waterdogpe/handler/LobbyJoinHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class LobbyJoinHandler implements IJoinHandler {
1313
public ServerInfo determineServer(ProxiedPlayer proxiedPlayer) {
1414
InstanceInfo availableInstance = InstanceManager.getInstance().selectAvailableInstance(
1515
"lobby",
16-
InstanceManager.SelectionStrategy.MOST_PLAYERS_AVAILABLE
16+
InstanceManager.SelectionStrategy.LOWEST_PLAYERS
1717
);
1818
if (availableInstance == null) {
1919
return null;

waterdogpe/src/main/java/net/josscoder/redisbridge/waterdogpe/handler/ReconnectLobbyHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public ServerInfo getFallbackServer(ProxiedPlayer player, ServerInfo oldServer,
2323

2424
InstanceInfo availableInstance = InstanceManager.getInstance().selectAvailableInstance(
2525
"lobby",
26-
InstanceManager.SelectionStrategy.MOST_PLAYERS_AVAILABLE
26+
InstanceManager.SelectionStrategy.LOWEST_PLAYERS
2727
);
2828
if (availableInstance == null) {
2929
return null;

0 commit comments

Comments
 (0)