Skip to content

Commit 5e4f1ee

Browse files
authored
Merge pull request #38 from RagingTech/dev
2 parents 4ab24db + 0dd79da commit 5e4f1ee

54 files changed

Lines changed: 4330 additions & 2594 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ Buit-in placeholders are described below. As mentioned before, PlaceholderAPI pl
6565
|networkjoinmessages.spoof|Allows the use of the `/njoinspoof` command. The command will display a fake join/leave/swap message, based on the arguments given.|
6666
|networkjoinmessages.reload|Allows you to reload the configuration file with the `/njoinreload` command.|
6767
|networkjoinmessages.toggle|Allows the usage of the `/njointoggle` command, that lets users choose not to receive certain messages just for them.|
68+
|networkjoinmessages.toggle.others|Allows using the `/njointoggle` command against other players.|
6869
|networkjoinmessages.import|Allows importing users from backend servers' usercache.json files with the `/njoinimport` command.|
6970

7071
## Commands
@@ -75,7 +76,7 @@ Required arguments are enclosed with angle brackets (i.e. <this\>) and optional
7576
|---|---|
7677
|/njoinspoof <join \| leave \| swap \| toggle\> [<from\> <to\>\]|Displays a fake message using the issuer as the trigger player.|
7778
|/njoinreload|Reloads the configuration.|
78-
|/njointoggle <all \| join \| leave \| swap\> <on \| off\>|Toggles the issuers receiving of specific messages.|
79+
|/njointoggle <all \| join \| leave \| swap\> <on \| off\> [player\]|Toggles the issuer's or target player's receiving of specific messages. The `[player]` argument is required when running from console.|
7980
|/njoinimport <pathtousercache.json\> [pathtousercache.json...\]|Imports user's from backend servers' usercache.json files into the joined database so that they will not trigger first join messages. Useful for adding this plugin and using first join messages on an already running network.|
8081

8182
## Contributing

build.gradle.kts

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
plugins {
22
`java`
3-
`maven-publish`
43
// Shade plugin
54
id("com.gradleup.shadow") version "8.3.8"
65
// Blossom plugin for Pebble templating
@@ -12,6 +11,14 @@ group = property("group") as String
1211
version = property("version") as String
1312
description = property("description") as String
1413

14+
// Dependency versions
15+
val lombokVersion = "1.18.42"
16+
val bstatsVersion = "3.0.2"
17+
val adventureVersion = "4.24.0"
18+
val gsonVersion = "2.13.2"
19+
val h2Version = "2.2.224"
20+
val velocityVersion = "3.4.0-SNAPSHOT"
21+
1522
java {
1623
toolchain {
1724
languageVersion.set(JavaLanguageVersion.of(21))
@@ -28,50 +35,45 @@ repositories {
2835
maven("https://jitpack.io")
2936
// William278
3037
maven("https://repo.william278.net/releases/")
31-
// Elytrium
32-
maven("https://maven.elytrium.net/repo/")
38+
// Elytrium: local jar used as maven repo is down
39+
flatDir { dirs("libs") }
3340
// SayanDevelopment
34-
// Invalid SSL certificate local jar file utilized for the time being
35-
flatDir {
36-
dirs("libs")
41+
maven("https://repo.sayandev.org/snapshots") {
3742
content {
3843
includeGroup("org.sayandev")
3944
}
4045
}
41-
// maven("https://repo.sayandev.org/snapshots") {
42-
// content {
43-
// includeGroup("org.sayandev")
44-
// }
45-
// }
4646
}
4747

4848
dependencies {
4949
// Proxy APIs
5050
compileOnly("net.md-5:bungeecord-api:1.21-R0.2")
51-
compileOnly("com.velocitypowered:velocity-api:3.4.0-SNAPSHOT")
52-
annotationProcessor("com.velocitypowered:velocity-api:3.4.0-SNAPSHOT")
53-
compileOnly("com.velocitypowered:velocity-proxy:3.4.0-SNAPSHOT") {
51+
compileOnly("com.velocitypowered:velocity-api:$velocityVersion")
52+
annotationProcessor("com.velocitypowered:velocity-api:$velocityVersion")
53+
compileOnly("com.velocitypowered:velocity-proxy:$velocityVersion") {
5454
exclude(group = "com.velocitypowered", module = "velocity-proxy-log4j2-plugin")
5555
}
5656

57+
// JDBC drivers
58+
implementation("com.h2database:h2:${h2Version}")
59+
5760
// bStats
58-
implementation("org.bstats:bstats-bungeecord:3.0.2")
59-
implementation("org.bstats:bstats-velocity:3.0.2")
61+
implementation("org.bstats:bstats-bungeecord:$bstatsVersion")
62+
implementation("org.bstats:bstats-velocity:$bstatsVersion")
6063

6164
// Utilities
62-
compileOnly("org.projectlombok:lombok:1.18.42")
63-
annotationProcessor("org.projectlombok:lombok:1.18.42")
64-
testCompileOnly("org.projectlombok:lombok:1.18.42")
65-
testAnnotationProcessor("org.projectlombok:lombok:1.18.42")
65+
compileOnly("org.projectlombok:lombok:$lombokVersion")
66+
annotationProcessor("org.projectlombok:lombok:$lombokVersion")
67+
testCompileOnly("org.projectlombok:lombok:$lombokVersion")
68+
testAnnotationProcessor("org.projectlombok:lombok:$lombokVersion")
6669

67-
implementation("com.google.code.gson:gson:2.13.2")
70+
implementation("com.google.code.gson:gson:$gsonVersion")
6871
implementation("org.jetbrains:annotations:16.0.1")
69-
implementation("com.h2database:h2:2.2.224")
7072

7173
// Adventure & MiniMessage
7274
implementation("net.kyori:adventure-platform-bungeecord:4.4.1")
73-
implementation("net.kyori:adventure-text-minimessage:4.24.0")
74-
implementation("net.kyori:adventure-text-serializer-plain:4.24.0")
75+
implementation("net.kyori:adventure-text-minimessage:$adventureVersion")
76+
implementation("net.kyori:adventure-text-serializer-plain:$adventureVersion")
7577

7678
// MiniPlaceholders
7779
compileOnly("io.github.miniplaceholders:miniplaceholders-api:3.0.1")
@@ -98,12 +100,8 @@ dependencies {
98100
testImplementation("org.mockito:mockito-core:5.19.0")
99101
testImplementation("org.mockito:mockito-junit-jupiter:5.19.0")
100102

101-
testImplementation("com.google.code.gson:gson:2.13.2")
102-
testImplementation("org.jetbrains:annotations:16.0.1")
103-
testImplementation("com.h2database:h2:2.2.224")
104-
105103
testImplementation("net.luckperms:api:5.4")
106-
testImplementation("net.kyori:adventure-text-serializer-plain:4.24.0")
104+
testImplementation("net.kyori:adventure-text-serializer-plain:$adventureVersion")
107105
testImplementation("io.github.miniplaceholders:miniplaceholders-api:3.0.1")
108106
}
109107

@@ -117,7 +115,8 @@ sourceSets {
117115
}
118116
}
119117

120-
configurations.all {
118+
// Exclude legacy JUnit 4 from test runtime only
119+
configurations.testRuntimeClasspath {
121120
exclude(group = "junit", module = "junit")
122121
}
123122

@@ -144,10 +143,6 @@ tasks.shadowJar {
144143
archiveClassifier.set("")
145144
relocate("org.bstats", "xyz.earthcow.networkjoinmessages.libs.bstats")
146145
relocate("dev.dejvokep.boostedyaml", "xyz.earthcow.networkjoinmessages.libs.boostedyaml")
147-
148-
dependencies {
149-
exclude(dependency("io.github.miniplaceholders:miniplaceholders-api"))
150-
}
151146
}
152147

153148
tasks.build {

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Project metadata
22
group=xyz.earthcow.networkjoinmessages
3-
version=3.4.0
3+
version=3.5.0
44
description=A plugin handling join, leave and swap messages for proxy servers.
55

66
# Plugin.yml metadata
-32.2 MB
Binary file not shown.
877 KB
Binary file not shown.
Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,31 @@
11
package xyz.earthcow.networkjoinmessages.bungee.abstraction;
22

33
import net.md_5.bungee.api.config.ServerInfo;
4+
import org.jetbrains.annotations.NotNull;
45
import xyz.earthcow.networkjoinmessages.bungee.BungeeMain;
56
import xyz.earthcow.networkjoinmessages.common.abstraction.CoreBackendServer;
67
import xyz.earthcow.networkjoinmessages.common.abstraction.CorePlayer;
78

89
import java.util.List;
10+
import java.util.Objects;
911
import java.util.stream.Collectors;
1012

1113
public class BungeeServer implements CoreBackendServer {
1214
private final ServerInfo bungeeServer;
1315

14-
public BungeeServer(ServerInfo bungeeServer) {
15-
this.bungeeServer = bungeeServer;
16+
public BungeeServer(@NotNull ServerInfo bungeeServer) {
17+
this.bungeeServer = Objects.requireNonNull(bungeeServer, "bungeeServer must not be null");
1618
}
1719

1820
@Override
1921
public String getName() {
20-
if (bungeeServer == null) {
21-
return null;
22-
}
2322
return bungeeServer.getName();
2423
}
2524

2625
@Override
2726
public List<CorePlayer> getPlayersConnected() {
28-
if (bungeeServer == null) {
29-
return null;
30-
}
31-
return bungeeServer.getPlayers().stream().map(proxiedPlayer -> BungeeMain.getInstance().getOrCreatePlayer(proxiedPlayer.getUniqueId())).collect(Collectors.toList());
27+
return bungeeServer.getPlayers().stream()
28+
.map(proxiedPlayer -> BungeeMain.getInstance().getOrCreatePlayer(proxiedPlayer.getUniqueId()))
29+
.collect(Collectors.toList());
3230
}
3331
}

src/main/java/xyz/earthcow/networkjoinmessages/common/Core.java

Lines changed: 76 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,63 +4,114 @@
44
import org.bstats.charts.CustomChart;
55
import xyz.earthcow.networkjoinmessages.common.abstraction.CorePlugin;
66
import xyz.earthcow.networkjoinmessages.common.abstraction.PremiumVanish;
7-
import xyz.earthcow.networkjoinmessages.common.commands.CoreImportCommand;
8-
import xyz.earthcow.networkjoinmessages.common.commands.CoreReloadCommand;
9-
import xyz.earthcow.networkjoinmessages.common.commands.CoreSpoofCommand;
10-
import xyz.earthcow.networkjoinmessages.common.commands.CoreToggleJoinCommand;
7+
import xyz.earthcow.networkjoinmessages.common.broadcast.MessageFormatter;
8+
import xyz.earthcow.networkjoinmessages.common.broadcast.ReceiverResolver;
9+
import xyz.earthcow.networkjoinmessages.common.commands.*;
10+
import xyz.earthcow.networkjoinmessages.common.config.PluginConfig;
1111
import xyz.earthcow.networkjoinmessages.common.listeners.CorePlayerListener;
1212
import xyz.earthcow.networkjoinmessages.common.listeners.CorePremiumVanishListener;
1313
import xyz.earthcow.networkjoinmessages.common.modules.DiscordIntegration;
14+
import xyz.earthcow.networkjoinmessages.common.modules.DiscordWebhookBuilder;
1415
import xyz.earthcow.networkjoinmessages.common.modules.SayanVanishHook;
15-
import xyz.earthcow.networkjoinmessages.common.util.Formatter;
16-
import xyz.earthcow.networkjoinmessages.common.util.SpoofManager;
16+
import xyz.earthcow.networkjoinmessages.common.player.*;
17+
import xyz.earthcow.networkjoinmessages.common.storage.*;
18+
import xyz.earthcow.networkjoinmessages.common.util.*;
1719

1820
import java.util.Collection;
1921

22+
/**
23+
* Composition root. Constructs and wires all plugin components together.
24+
* The only class allowed to know about all components simultaneously.
25+
*/
2026
@Getter
2127
public class Core {
22-
private final CorePlugin plugin;
2328

29+
private final CorePlugin plugin;
2430
private final Collection<CustomChart> customCharts;
2531

2632
private final CorePlayerListener corePlayerListener;
2733
private final CoreImportCommand coreImportCommand;
2834
private final CoreSpoofCommand coreSpoofCommand;
2935
private final CoreReloadCommand coreReloadCommand;
3036
private final CoreToggleJoinCommand coreToggleJoinCommand;
31-
3237
private final CorePremiumVanishListener corePremiumVanishListener;
3338

3439
public Core(CorePlugin plugin, PremiumVanish premiumVanish) {
3540
this.plugin = plugin;
3641

42+
// Infrastructure
3743
ConfigManager configManager = new ConfigManager(plugin);
44+
PluginConfig config = new PluginConfig(plugin, configManager);
3845

39-
SayanVanishHook sayanVanishHook;
46+
// Optional third-party hooks
47+
SayanVanishHook sayanVanishHook = null;
4048
if (plugin.isPluginLoaded("SayanVanish")) {
4149
sayanVanishHook = new SayanVanishHook();
4250
plugin.getCoreLogger().info("Successfully hooked into SayanVanish!");
43-
} else {
44-
sayanVanishHook = null;
4551
}
4652

47-
Storage storage = new Storage(plugin, configManager);
48-
Formatter formatter = new Formatter(plugin, storage, storage.getPPBRequestTimeout());
49-
MessageHandler messageHandler = new MessageHandler(plugin, storage, formatter, sayanVanishHook);
50-
SpoofManager spoofManager = new SpoofManager(plugin, storage, messageHandler);
51-
DiscordIntegration discordIntegration = new DiscordIntegration(plugin, storage, formatter, messageHandler, configManager.getDiscordConfig());
53+
PlayerJoinTracker firstJoinTracker = null;
54+
PlayerDataStore playerDataStore = null;
55+
56+
StorageType firstJoinType = config.getFirstJoinStorageType();
57+
StorageType playerDataType = config.getPlayerDataStorageType();
58+
59+
try {
60+
ActiveStorageBackends backends = StorageInitializer.initialize(
61+
firstJoinType,
62+
playerDataType,
63+
config.buildSqlConfig(),
64+
plugin.getDataFolder().toPath(),
65+
plugin.getCoreLogger());
66+
firstJoinTracker = backends.joinTracker();
67+
playerDataStore = backends.playerDataStore();
68+
plugin.getCoreLogger().info("Storage initialized — first-join: " + firstJoinType
69+
+ ", player-data: " + playerDataType + ".");
70+
} catch (StorageInitializer.StorageInitializationException e) {
71+
plugin.getCoreLogger().severe("Storage initialisation failed: " + e.getMessage()
72+
+ " — first-join tracking and persistent player data will be unavailable.");
73+
plugin.getCoreLogger().debug("Exception: " + e);
74+
}
75+
76+
// Core data / state
77+
PlayerStateStore stateStore = new PlayerStateStore(plugin, config, playerDataStore);
78+
79+
// Placeholder resolution
80+
PlaceholderResolver placeholderResolver = new PlaceholderResolver(plugin, config);
81+
82+
// Message building
83+
MessageFormatter messageFormatter = new MessageFormatter(plugin, config, sayanVanishHook);
84+
ReceiverResolver receiverResolver = new ReceiverResolver(plugin, config);
85+
MessageHandler messageHandler = new MessageHandler(plugin, config, stateStore, placeholderResolver, receiverResolver);
86+
87+
// Player event helpers
88+
SilenceChecker silenceChecker = new SilenceChecker(plugin, config, stateStore, sayanVanishHook, premiumVanish);
89+
LeaveMessageCache leaveMessageCache = new LeaveMessageCache(plugin, config, messageFormatter, placeholderResolver);
90+
LeaveJoinBufferManager leaveJoinBuffer = new LeaveJoinBufferManager(plugin, config);
91+
92+
// Discord integration
93+
DiscordWebhookBuilder webhookBuilder = new DiscordWebhookBuilder(plugin, configManager.getDiscordConfig());
94+
DiscordIntegration discordIntegration = new DiscordIntegration(plugin, placeholderResolver, messageFormatter, webhookBuilder, configManager.getDiscordConfig());
5295

53-
this.customCharts = storage.getCustomCharts();
96+
// Spoof
97+
SpoofManager spoofManager = new SpoofManager(plugin, config, messageHandler, messageFormatter, placeholderResolver);
5498

55-
this.corePlayerListener = new CorePlayerListener(plugin, storage, messageHandler, sayanVanishHook, premiumVanish);
99+
this.customCharts = config.getCustomCharts();
56100

57-
this.coreImportCommand = new CoreImportCommand(corePlayerListener.getPlayerJoinTracker());
58-
this.coreSpoofCommand = new CoreSpoofCommand(storage, messageHandler, spoofManager);
59-
this.coreReloadCommand = new CoreReloadCommand(plugin, configManager, storage, formatter, messageHandler, discordIntegration);
60-
this.coreToggleJoinCommand = new CoreToggleJoinCommand(storage, messageHandler);
101+
// Listeners
102+
this.corePlayerListener = new CorePlayerListener(
103+
plugin, config, stateStore, messageHandler, messageFormatter,
104+
receiverResolver, silenceChecker, leaveMessageCache, leaveJoinBuffer,
105+
placeholderResolver, firstJoinTracker
106+
);
61107

62-
this.corePremiumVanishListener = premiumVanish == null ? null :
63-
new CorePremiumVanishListener(plugin.getCoreLogger(), storage, spoofManager);
108+
// Commands
109+
this.coreImportCommand = new CoreImportCommand(firstJoinTracker);
110+
this.coreSpoofCommand = new CoreSpoofCommand(config, stateStore, messageHandler, spoofManager);
111+
this.coreReloadCommand = new CoreReloadCommand(configManager, config, placeholderResolver, messageHandler, leaveMessageCache, discordIntegration);
112+
this.coreToggleJoinCommand = new CoreToggleJoinCommand(config, stateStore, messageHandler, plugin, silenceChecker, playerDataStore);
64113

114+
this.corePremiumVanishListener = premiumVanish == null ? null
115+
: new CorePremiumVanishListener(plugin.getCoreLogger(), config, spoofManager);
65116
}
66-
}
117+
}

0 commit comments

Comments
 (0)