Skip to content

Commit 2635364

Browse files
committedApr 28, 2023
Add messageall and transferall commands
1 parent 1fac3bc commit 2635364

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed
 

‎README.md

+9
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,12 @@ GeyserConnect is an easy way for Bedrock Edition clients to connect to any Java
1313
GeyserConnect is an extension for Geyser that allows for a list of Minecraft: Java Edition servers to be displayed and accessed through 1 public Geyser instance. It is effectively give the customisability of [BedrockConnect](https://github.com/Pugmatt/BedrockConnect) to [Geyser](https://github.com/GeyserMC/Geyser).
1414

1515
If you wish to use DNS redirection please see the [bind9](bind9) folder in this repository.
16+
17+
## Commands
18+
All commands are prefixed ingame with `/geyserconnect` or in console with `geyserconnect`
19+
20+
| Command | Description | Example | Console only |
21+
|------------------------------------|----------------------------------------------|--------------------------------------------------------|--------------------|
22+
| `menu` | Reconnect and get back to the menu. | `/geyserconnect menu` | :x: |
23+
| `messageall (chat\|gui) <message>` | Send a message to all online users. | `/geyserconnect messageall gui This is a test message` | :heavy_check_mark: |
24+
| `transferall <ip> [passAsVhost]` | Transfer all online users to another server. | `/geyserconnect transferall gc.example.com true` | :heavy_check_mark: |

‎src/main/java/org/geysermc/connect/extension/GeyserConnect.java

+99
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,25 @@
3131
import org.geysermc.connect.extension.config.ConfigLoader;
3232
import org.geysermc.connect.extension.storage.AbstractStorageManager;
3333
import org.geysermc.connect.extension.storage.DisabledStorageManager;
34+
import org.geysermc.connect.extension.utils.Utils;
35+
import org.geysermc.cumulus.form.CustomForm;
3436
import org.geysermc.event.subscribe.Subscribe;
37+
import org.geysermc.geyser.GeyserImpl;
3538
import org.geysermc.geyser.api.command.Command;
39+
import org.geysermc.geyser.api.command.CommandSource;
3640
import org.geysermc.geyser.api.connection.GeyserConnection;
3741
import org.geysermc.geyser.api.event.bedrock.SessionInitializeEvent;
3842
import org.geysermc.geyser.api.event.lifecycle.GeyserDefineCommandsEvent;
3943
import org.geysermc.geyser.api.event.lifecycle.GeyserPostInitializeEvent;
4044
import org.geysermc.geyser.api.extension.Extension;
45+
import org.geysermc.geyser.api.network.AuthType;
4146
import org.geysermc.geyser.session.GeyserSession;
4247

48+
import java.util.Arrays;
49+
import java.util.Collection;
50+
import java.util.List;
51+
import java.util.stream.Collectors;
52+
4353
public class GeyserConnect implements Extension {
4454
private static GeyserConnect instance;
4555
private Config config;
@@ -116,5 +126,94 @@ public void onCommandDefine(GeyserDefineCommandsEvent event) {
116126
session.sendUpstreamPacket(transferPacket);
117127
})
118128
.build());
129+
130+
event.register(Command.builder(this)
131+
.source(CommandSource.class)
132+
.name("messageall")
133+
.description("Send a message to everyone connected to this GeyserConnect server.")
134+
.executor((source, command, args) -> {
135+
if (!source.isConsole()) {
136+
source.sendMessage("This command can only be ran from the console.");
137+
return;
138+
}
139+
140+
String type = args[0].toLowerCase();
141+
String message = Arrays.stream(args).skip(1).collect(Collectors.joining(" "));
142+
143+
if (message.isEmpty()) {
144+
source.sendMessage("You must specify a message.");
145+
return;
146+
}
147+
148+
Collection<GeyserSession> sessions = GeyserImpl.getInstance().getSessionManager().getSessions().values();
149+
150+
switch (type) {
151+
case "chat":
152+
for (GeyserSession session : sessions) {
153+
session.sendMessage(message);
154+
}
155+
break;
156+
case "gui":
157+
for (GeyserSession session : sessions) {
158+
session.sendForm(CustomForm.builder()
159+
.title("Notice")
160+
.label(message)
161+
.build());
162+
}
163+
break;
164+
default:
165+
source.sendMessage("Invalid message type. Valid types: chat, gui");
166+
return;
167+
}
168+
})
169+
.build());
170+
171+
172+
event.register(Command.builder(this)
173+
.source(CommandSource.class)
174+
.name("transferall")
175+
.description("Transfer everyone connected to this GeyserConnect server to another.")
176+
.executor((source, command, args) -> {
177+
if (!source.isConsole()) {
178+
source.sendMessage("This command can only be ran from the console.");
179+
return;
180+
}
181+
182+
String ip = args[0].toLowerCase();
183+
int port = 19132;
184+
boolean passAsVhost = args.length > 1 && Boolean.parseBoolean(args[1]);
185+
186+
// Split the ip and port if needed
187+
String[] parts = ip.split(":");
188+
ip = parts[0];
189+
if (parts.length > 1) {
190+
try {
191+
port = Integer.parseInt(parts[1]);
192+
} catch (NumberFormatException ignored) {
193+
}
194+
}
195+
196+
for (GeyserSession session : GeyserImpl.getInstance().getSessionManager().getSessions().values()) {
197+
String sessionIp = ip;
198+
199+
// If we are passing with a vhost construct the vhost
200+
if (passAsVhost) {
201+
sessionIp = session.remoteServer().address();
202+
sessionIp += "._p" + session.remoteServer().port();
203+
if (session.remoteServer().authType() == AuthType.OFFLINE) {
204+
sessionIp += "._o";
205+
}
206+
sessionIp += "." + ip;
207+
}
208+
209+
GeyserConnect.instance().logger().info("Sending " + Utils.displayName(session) + " to " + sessionIp + (port != 19132 ? ":" + port : ""));
210+
211+
TransferPacket transferPacket = new TransferPacket();
212+
transferPacket.setAddress(sessionIp);
213+
transferPacket.setPort(port);
214+
session.sendUpstreamPacket(transferPacket);
215+
}
216+
})
217+
.build());
119218
}
120219
}

0 commit comments

Comments
 (0)
Please sign in to comment.