22
33import com .google .inject .Inject ;
44import com .velocitypowered .api .event .Subscribe ;
5+ import com .velocitypowered .api .event .connection .PostLoginEvent ;
56import com .velocitypowered .api .event .proxy .ProxyInitializeEvent ;
67import com .velocitypowered .api .event .proxy .ProxyShutdownEvent ;
78import com .velocitypowered .api .plugin .Dependency ;
89import com .velocitypowered .api .plugin .Plugin ;
910import com .velocitypowered .api .plugin .annotation .DataDirectory ;
11+ import com .velocitypowered .api .proxy .Player ;
1012import com .velocitypowered .api .proxy .ProxyServer ;
1113import dev .objz .commandbridge .config .ConfigManager ;
1214import dev .objz .commandbridge .config .model .VelocityConfig ;
2123import dev .objz .commandbridge .scripting .platform .PlatformFeatureKeys ;
2224import dev .objz .commandbridge .scripting .platform .PlatformFeatureSet ;
2325import dev .objz .commandbridge .scripting .platform .PlatformFeatures ;
26+ import dev .objz .commandbridge .util .MM ;
2427import dev .objz .commandbridge .velocity .cli .CBCommand ;
2528import dev .objz .commandbridge .velocity .dispatch .CommandEntry ;
2629import dev .objz .commandbridge .velocity .cmd .bridge .framework .ArgumentBridge ;
3336import dev .objz .commandbridge .velocity .net .out .PingRequest ;
3437import dev .objz .commandbridge .velocity .net .out .RegistrationRequest ;
3538import 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
3744import 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 ;
3950import 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}
0 commit comments