Skip to content

Commit cb0d430

Browse files
committed
feat: added legacy runtime detection and copy example.yml to scripts. also added bstats metrics
1 parent 6108129 commit cb0d430

5 files changed

Lines changed: 124 additions & 4 deletions

File tree

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ git checkout v3
9292
- [x] Placeholder and PlaceholderAPI support
9393
- [x] Console, player, and operator execution modes
9494
- [x] Offline command queue
95-
- [ ] Database backend for task queue (currently JSON file)
95+
- [ ] Database backend for task queue (currently JSON file) | maybe?
9696

9797
- [x] **Admin Commands (`/cb`)**
9898
- [x] `/cb help`
@@ -102,10 +102,11 @@ git checkout v3
102102
- [x] `/cb list`
103103
- [x] `/cb ping`
104104
- [x] `/cb debug`
105+
- [ ] `/cb dump`
105106
- [x] Dual-mode output (chat and console)
106107
- [ ] Automatic update checker
107-
- [ ] `/cb dump`
108108
- [ ] Dump export to file or paste service
109+
- [ ] bstats
109110

110111
- [ ] **Web Interface**
111112
- [ ] ...

dist/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ dependencies {
2929
implementation("org.snakeyaml:snakeyaml-engine:2.10")
3030
implementation("com.google.code.gson:gson:2.13.2")
3131
implementation("net.kyori:adventure-text-minimessage:4.17.0")
32+
implementation("org.bstats:bstats-velocity:3.1.0")
3233
}
3334

3435

@@ -49,6 +50,7 @@ tasks {
4950
relocate("org.jboss.threads", "dev.objz.libs.jboss.threads")
5051
relocate("org.spongepowered.configurate", "dev.objz.libs.configurate")
5152
relocate("org.yaml.snakeyaml", "dev.objz.libs.snakeyaml")
53+
relocate("org.bstats", "dev.objz.libs.bstats")
5254
mergeServiceFiles()
5355

5456
from(project(":velocity").layout.projectDirectory.dir("src/main/resources")) { include("velocity-plugin.json") }

velocity/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ dependencies {
2828
compileOnly("org.spongepowered:configurate-core:4.2.0")
2929
compileOnly("dev.jorel:commandapi-velocity-core:11.1.0")
3030

31+
compileOnly("org.bstats:bstats-velocity:3.1.0")
32+
3133

3234
compileOnly("net.william278:papiproxybridge:1.8.4")
3335

velocity/src/main/java/dev/objz/commandbridge/velocity/Main.java

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
import com.google.inject.Inject;
44
import com.velocitypowered.api.event.Subscribe;
5+
import com.velocitypowered.api.event.connection.PostLoginEvent;
56
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
67
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
78
import com.velocitypowered.api.plugin.Dependency;
89
import com.velocitypowered.api.plugin.Plugin;
910
import com.velocitypowered.api.plugin.annotation.DataDirectory;
11+
import com.velocitypowered.api.proxy.Player;
1012
import com.velocitypowered.api.proxy.ProxyServer;
1113
import dev.objz.commandbridge.config.ConfigManager;
1214
import dev.objz.commandbridge.config.model.VelocityConfig;
@@ -21,6 +23,7 @@
2123
import dev.objz.commandbridge.scripting.platform.PlatformFeatureKeys;
2224
import dev.objz.commandbridge.scripting.platform.PlatformFeatureSet;
2325
import dev.objz.commandbridge.scripting.platform.PlatformFeatures;
26+
import dev.objz.commandbridge.util.MM;
2427
import dev.objz.commandbridge.velocity.cli.CBCommand;
2528
import dev.objz.commandbridge.velocity.dispatch.CommandEntry;
2629
import dev.objz.commandbridge.velocity.cmd.bridge.framework.ArgumentBridge;
@@ -33,10 +36,19 @@
3336
import dev.objz.commandbridge.velocity.net.out.PingRequest;
3437
import dev.objz.commandbridge.velocity.net.out.RegistrationRequest;
3538
import dev.objz.commandbridge.velocity.net.session.SessionHub;
39+
import dev.objz.commandbridge.velocity.ui.Theme;
40+
import net.kyori.adventure.text.Component;
41+
import net.kyori.adventure.text.event.ClickEvent;
42+
import net.kyori.adventure.text.event.HoverEvent;
3643

3744
import org.slf4j.Logger;
45+
import org.bstats.velocity.Metrics;
3846

47+
import java.io.IOException;
48+
import java.io.InputStream;
49+
import java.nio.file.Files;
3950
import java.nio.file.Path;
51+
import java.util.concurrent.TimeUnit;
4052

4153
@Plugin(id = "commandbridge", name = "CommandBridge", version = "3.0.0", url = "https://cb.objz.dev", description = "I did it!", authors = {
4254
"objz" }, dependencies = { @Dependency(id = "commandapi"),
@@ -48,6 +60,7 @@ public final class Main {
4860
private final Path dataDir;
4961
private final Object pluginInstance;
5062
private final Logger velocityLogger;
63+
private final Metrics.Factory metrics;
5164

5265
private ConfigManager configManager;
5366
private WsServer ws;
@@ -63,23 +76,29 @@ public final class Main {
6376
private Object backendBootstrap;
6477
private ArgumentBridge argumentBridge;
6578
private PlatformFeatures platformFeatures;
66-
79+
private boolean legacyDetected;
6780

6881
public static boolean isPapiEnabled = false;
6982

7083
@Inject
71-
public Main(ProxyServer proxy, Logger velocityLogger, @DataDirectory Path dataDir) {
84+
public Main(ProxyServer proxy, Logger velocityLogger, @DataDirectory Path dataDir, Metrics.Factory metrics) {
7285
this.proxy = proxy;
7386
this.dataDir = dataDir;
87+
this.metrics = metrics;
7488
this.pluginInstance = this;
7589
this.velocityLogger = velocityLogger;
7690
Log.install(velocityLogger);
7791
}
7892

7993
@Subscribe
8094
public void onProxyInitialization(ProxyInitializeEvent e) {
95+
int pluginID = 22008;
96+
metrics.make(this, pluginID);
8197
Log.info("Initializing CommandBridge");
8298

99+
copyExampleScript();
100+
checkLegacyInstallation();
101+
83102
configManager = new ConfigManager(dataDir);
84103
boolean ok = configManager.load(VelocityConfig.class);
85104
cfg = configManager.current(VelocityConfig.class);
@@ -214,4 +233,59 @@ private void loadClientMode() {
214233
Log.error(ex, "Failed to start client mode");
215234
}
216235
}
236+
237+
private void copyExampleScript() {
238+
Path scriptsDir = dataDir.resolve("scripts");
239+
Path exampleFile = scriptsDir.resolve("example.yml");
240+
if (Files.exists(exampleFile)) return;
241+
242+
try {
243+
Files.createDirectories(scriptsDir);
244+
try (InputStream in = getClass().getResourceAsStream("/example.yml")) {
245+
if (in != null) {
246+
Files.copy(in, exampleFile);
247+
Log.debug("Created example script at scripts/example.yml");
248+
}
249+
}
250+
} catch (IOException ex) {
251+
Log.error("Failed to copy example script: {}", ex.getMessage());
252+
}
253+
}
254+
255+
private void checkLegacyInstallation() {
256+
Path oldFolder = dataDir.getParent().resolve("CommandBridge");
257+
if (!Files.isDirectory(oldFolder)) return;
258+
259+
legacyDetected = true;
260+
Log.warn("Detected old CommandBridge installation at '{}'. Please view the migration guide: https://cb.objz.dev/docs/migration/", oldFolder);
261+
}
262+
263+
@Subscribe
264+
public void onPostLogin(PostLoginEvent event) {
265+
if (!legacyDetected) return;
266+
267+
Player player = event.getPlayer();
268+
if (!player.hasPermission("commandbridge.admin")) return;
269+
270+
proxy.getScheduler().buildTask(pluginInstance, () -> {
271+
if (!player.isActive()) return;
272+
273+
String migrationUrl = "https://cb.objz.dev/docs/migration/";
274+
275+
player.sendMessage(Component.empty());
276+
player.sendMessage(MM.parse(
277+
"<" + Theme.C_WARN + "><bold>\u26A0 CommandBridge</bold></" + Theme.C_WARN + "> "
278+
+ "<" + Theme.C_ERROR + ">Old installation detected</" + Theme.C_ERROR + ">"));
279+
player.sendMessage(MM.parse(
280+
"<" + Theme.C_MUTED + ">A legacy </><white>CommandBridge</white>"
281+
+ "<" + Theme.C_MUTED + "> folder was found in your plugins directory.</" + Theme.C_MUTED + ">"));
282+
player.sendMessage(MM.parse(
283+
"<" + Theme.C_MUTED + ">View the migration guide: </" + Theme.C_MUTED + ">"
284+
+ "<" + Theme.C_ACCENT + "><underlined>" + migrationUrl + "</underlined></" + Theme.C_ACCENT + ">")
285+
.clickEvent(ClickEvent.openUrl(migrationUrl))
286+
.hoverEvent(HoverEvent.showText(MM.parse(
287+
"<" + Theme.C_MUTED + ">Click to open migration guide</" + Theme.C_MUTED + ">"))));
288+
player.sendMessage(Component.empty());
289+
}).delay(3, TimeUnit.SECONDS).schedule();
290+
}
217291
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# CommandBridge - Example Script
2+
# For a full reference of all options, visit https://cb.objz.dev/docs
3+
4+
version: 2
5+
6+
name: example
7+
description: An example command script - edit or replace this with your own
8+
enabled: false # Set to true to activate this script
9+
aliases: [ex]
10+
11+
permissions:
12+
enabled: true # Requires commandbridge.command.example to use
13+
silent: false
14+
15+
register:
16+
- id: "client-1"
17+
location: VELOCITY
18+
19+
defaults:
20+
run-as: CONSOLE
21+
execute:
22+
- id: "client-1"
23+
location: BACKEND
24+
server:
25+
target-required: false
26+
schedule-online: false
27+
timeout: 5s
28+
delay: 0s
29+
cooldown: 0s
30+
31+
args:
32+
- name: player
33+
required: true
34+
type: PLAYERS
35+
36+
- name: message
37+
required: true
38+
type: TEXT
39+
40+
commands:
41+
- command: "msg ${player} ${message}"

0 commit comments

Comments
 (0)