|
2 | 2 |
|
3 | 3 | import com.google.inject.Guice; |
4 | 4 | import com.google.inject.Injector; |
5 | | -import io.papermc.paper.ServerBuildInfo; |
| 5 | +import com.google.inject.Stage; |
6 | 6 | import net.kyori.adventure.text.Component; |
7 | 7 | import net.kyori.adventure.text.minimessage.MiniMessage; |
8 | | -import net.kyori.adventure.util.UTF8ResourceBundleControl; |
9 | | -import net.onelitefeather.antiredstoneclockremastered.api.PlotsquaredSupport; |
10 | | -import net.onelitefeather.antiredstoneclockremastered.api.WorldGuardSupport; |
11 | | -import net.onelitefeather.antiredstoneclockremastered.commands.DisplayActiveClocksCommand; |
12 | | -import net.onelitefeather.antiredstoneclockremastered.commands.FeatureCommand; |
13 | | -import net.onelitefeather.antiredstoneclockremastered.commands.ReloadCommand; |
| 8 | +import net.onelitefeather.antiredstoneclockremastered.injection.MetricsModule; |
| 9 | +import net.onelitefeather.antiredstoneclockremastered.injection.CommandFrameworkModule; |
14 | 10 | import net.onelitefeather.antiredstoneclockremastered.injection.CommandModule; |
15 | 11 | import net.onelitefeather.antiredstoneclockremastered.injection.ExternalSupportModule; |
16 | 12 | import net.onelitefeather.antiredstoneclockremastered.injection.ListenerModule; |
17 | 13 | import net.onelitefeather.antiredstoneclockremastered.injection.PlatformModule; |
18 | 14 | import net.onelitefeather.antiredstoneclockremastered.injection.ServiceModule; |
19 | | -import net.onelitefeather.antiredstoneclockremastered.listener.*; |
20 | | -import net.onelitefeather.antiredstoneclockremastered.plotsquared.v6.PlotSquaredLegacySupport; |
21 | | -import net.onelitefeather.antiredstoneclockremastered.plotsquared.v7.PlotSquaredModernSupport; |
22 | | -import net.onelitefeather.antiredstoneclockremastered.service.api.RedstoneClockService; |
23 | | -import net.onelitefeather.antiredstoneclockremastered.service.factory.RedstoneClockServiceFactory; |
| 15 | +import net.onelitefeather.antiredstoneclockremastered.injection.TranslationModule; |
24 | 16 | import net.onelitefeather.antiredstoneclockremastered.service.UpdateService; |
25 | | -import net.onelitefeather.antiredstoneclockremastered.service.api.TranslationService; |
26 | | -import net.onelitefeather.antiredstoneclockremastered.service.impl.LegacyTranslationService; |
27 | | -import net.onelitefeather.antiredstoneclockremastered.service.impl.ModernTranslationService; |
28 | 17 | import net.onelitefeather.antiredstoneclockremastered.utils.CheckTPS; |
29 | | -import net.onelitefeather.antiredstoneclockremastered.worldguard.v6.WorldGuardLegacySupport; |
30 | | -import net.onelitefeather.antiredstoneclockremastered.worldguard.v7.WorldGuardModernSupport; |
31 | | -import org.bstats.bukkit.Metrics; |
32 | | -import org.bstats.charts.DrilldownPie; |
33 | | -import org.bstats.charts.SimplePie; |
34 | | -import org.bukkit.Material; |
35 | | -import org.bukkit.command.CommandSender; |
36 | | -import org.bukkit.plugin.Plugin; |
37 | 18 | import org.bukkit.plugin.java.JavaPlugin; |
38 | | -import org.incendo.cloud.annotations.AnnotationParser; |
39 | | -import org.incendo.cloud.bukkit.CloudBukkitCapabilities; |
40 | | -import org.incendo.cloud.component.DefaultValue; |
41 | | -import org.incendo.cloud.execution.ExecutionCoordinator; |
42 | | -import org.incendo.cloud.minecraft.extras.MinecraftHelp; |
43 | | -import org.incendo.cloud.minecraft.extras.RichDescription; |
44 | | -import org.incendo.cloud.paper.LegacyPaperCommandManager; |
45 | 19 |
|
46 | | -import java.io.IOException; |
47 | | -import java.net.URL; |
48 | | -import java.net.URLClassLoader; |
49 | | -import java.nio.file.Files; |
50 | | -import java.nio.file.Path; |
51 | | -import java.util.*; |
52 | | - |
53 | | -import static org.incendo.cloud.parser.standard.StringParser.greedyStringParser; |
| 20 | +import java.util.Arrays; |
54 | 21 |
|
55 | 22 | public final class AntiRedstoneClockRemastered extends JavaPlugin { |
56 | | - public static final String RESOURCE_BUNDLE_NAME = "antiredstoneclockremasterd"; |
57 | 23 |
|
58 | 24 | // Injector for dependency injection |
59 | 25 | private Injector injector; |
60 | | - |
61 | | - // Legacy dependencies that are still manually managed |
62 | | - private CheckTPS tps; |
63 | | - private RedstoneClockService redstoneClockService; |
64 | | - private WorldGuardSupport worldGuardSupport; |
65 | | - private PlotsquaredSupport plotsquaredSupport; |
66 | | - private Metrics metrics; |
67 | | - private AnnotationParser<CommandSender> annotationParser; |
68 | | - private UpdateService updateService; |
69 | 26 |
|
70 | 27 | public static final Component PREFIX = MiniMessage.miniMessage().deserialize("<gradient:red:white>[AntiRedstoneClock]</gradient>"); |
71 | 28 |
|
72 | 29 | @Override |
73 | 30 | public void onLoad() { |
74 | 31 | saveDefaultConfig(); |
75 | 32 | reloadConfig(); |
76 | | - injector = Guice.createInjector( |
77 | | - new PlatformModule(this), |
78 | | - new ServiceModule(this), |
79 | | - new ExternalSupportModule(this), |
80 | | - new CommandModule(), |
81 | | - new ListenerModule() |
| 33 | + injector = Guice.createInjector(Stage.PRODUCTION, Arrays.asList( |
| 34 | + new PlatformModule(this), |
| 35 | + new TranslationModule(), |
| 36 | + new ServiceModule(), |
| 37 | + new ExternalSupportModule(), |
| 38 | + new CommandModule(), |
| 39 | + new ListenerModule() |
| 40 | + ) |
82 | 41 | ); |
83 | | - this.worldGuardSupport = injector.getInstance(WorldGuardSupport.class); |
84 | 42 | } |
85 | 43 |
|
86 | 44 | @Override |
87 | 45 | public void onEnable() { |
88 | | - TranslationService translationService = injector.getInstance(TranslationService.class); |
89 | | - this.redstoneClockService = injector.getInstance(RedstoneClockService.class); |
90 | | - this.updateService = injector.getInstance(UpdateService.class); |
91 | | - this.tps = injector.getInstance(CheckTPS.class); |
92 | | - this.plotsquaredSupport = injector.getInstance(PlotsquaredSupport.class); |
93 | | - |
94 | | - // Setup translations |
95 | | - Path langFolder = getDataFolder().toPath().resolve("lang"); |
96 | | - if (Files.notExists(langFolder)) { |
97 | | - try { |
98 | | - Files.createDirectories(langFolder); |
99 | | - } catch (IOException e) { |
100 | | - getSLF4JLogger().error("An error occurred while creating lang folder"); |
101 | | - return; |
102 | | - } |
103 | | - } |
104 | | - var languages = new HashSet<>(getConfig().getStringList("translations")); |
105 | | - languages.add("en-US"); |
106 | | - languages.stream() |
107 | | - .map(Locale::forLanguageTag) |
108 | | - .forEach(locale -> loadAndRegisterTranslation(locale, langFolder, translationService)); |
109 | | - translationService.registerGlobal(); |
110 | | - |
111 | | - // Initialize other components |
| 46 | + injector.getInstance(TranslationModule.class); |
| 47 | + injector.getInstance(CheckTPS.class).startCheck(); |
112 | 48 | donationInformation(); |
113 | | - updateService(); |
114 | | - enableCommandFramework(); |
115 | | - enableTPSChecker(); |
116 | | - enableBStatsSupport(); |
117 | | - registerEvents(); |
118 | | - registerCommands(); |
| 49 | + injector.getInstance(UpdateService.class).schedule(); |
| 50 | + injector.getInstance(UpdateService.class).run(); |
| 51 | + injector.getInstance(UpdateService.class).notifyConsole(getComponentLogger()); |
| 52 | + injector.getInstance(CommandFrameworkModule.class).enable(); |
| 53 | + injector.getInstance(MetricsModule.class).registerCharts(); |
| 54 | + this.injector.getInstance(ListenerModule.class).registerEvents(injector, this); |
119 | 55 | } |
120 | | - |
121 | | - private void updateService() { |
122 | | - this.updateService.run(); |
123 | | - this.updateService.notifyConsole(getComponentLogger()); |
124 | | - } |
125 | | - |
126 | 56 | @Override |
127 | 57 | public void onDisable() { |
128 | | - if (this.updateService != null) { |
129 | | - this.updateService.shutdown(); |
130 | | - } |
| 58 | + injector.getInstance(UpdateService.class).shutdown(); |
131 | 59 | } |
132 | 60 |
|
133 | 61 | private void donationInformation() { |
134 | 62 | getComponentLogger().info(Component.translatable("antiredstoneclockremastered.notify.donation.console")); |
135 | 63 | } |
136 | 64 |
|
137 | | - private void registerCommands() { |
138 | | - if (this.annotationParser != null) { |
139 | | - this.annotationParser.parse(injector.getInstance(ReloadCommand.class)); |
140 | | - this.annotationParser.parse(injector.getInstance(DisplayActiveClocksCommand.class)); |
141 | | - this.annotationParser.parse(injector.getInstance(FeatureCommand.class)); |
142 | | - } |
143 | | - } |
144 | | - |
145 | | - private void enableCommandFramework() { |
146 | | - LegacyPaperCommandManager<CommandSender> commandManager = LegacyPaperCommandManager.createNative( |
147 | | - this, |
148 | | - ExecutionCoordinator.asyncCoordinator() |
149 | | - ); |
150 | | - if (commandManager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER)) { |
151 | | - commandManager.registerBrigadier(); |
152 | | - } |
153 | | - else if (commandManager.hasCapability(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION)) { |
154 | | - commandManager.registerAsynchronousCompletions(); |
155 | | - } |
156 | | - annotationParser = new AnnotationParser<>(commandManager, CommandSender.class); |
157 | | - annotationParser.descriptionMapper(string -> RichDescription.of(Component.translatable(string))); |
158 | | - MinecraftHelp<CommandSender> help = MinecraftHelp.create( |
159 | | - "/arcm help", |
160 | | - commandManager, |
161 | | - sender -> sender |
162 | | - ); |
163 | | - commandManager.command( |
164 | | - commandManager.commandBuilder("arcm").literal("help") |
165 | | - .permission("antiredstoneclockremastered.command.help") |
166 | | - .optional("query", greedyStringParser(), DefaultValue.constant("")) |
167 | | - .handler(context -> { |
168 | | - help.queryCommands(context.get("query"), context.sender()); |
169 | | - }) |
170 | | - ); |
171 | | - } |
172 | | - |
173 | | - // External support now handled by DI in ExternalSupportModule |
174 | | - |
175 | | - private void registerEvents() { |
176 | | - // Register DI-enabled listeners |
177 | | - getServer().getPluginManager().registerEvents(injector.getInstance(PlayerListener.class), this); |
178 | | - |
179 | | - if (getConfig().getBoolean("check.observer", true)) { |
180 | | - getServer().getPluginManager().registerEvents(injector.getInstance(ObserverListener.class), this); |
181 | | - } |
182 | | - |
183 | | - if (getConfig().getBoolean("check.sculk", true)) { |
184 | | - var sculk = Material.getMaterial("SCULK"); |
185 | | - if (sculk != null) { |
186 | | - getServer().getPluginManager().registerEvents(injector.getInstance(SculkListener.class), this); |
187 | | - } |
188 | | - } |
189 | | - |
190 | | - if (getConfig().getBoolean("check.piston", true)) { |
191 | | - getServer().getPluginManager().registerEvents(injector.getInstance(PistonListener.class), this); |
192 | | - } |
193 | | - |
194 | | - // Material-dependent listeners now use dependency injection |
195 | | - if (getConfig().getBoolean("check.comparator", true)) { |
196 | | - var comparator = Material.getMaterial("COMPARATOR"); |
197 | | - if (comparator != null) { |
198 | | - var listener = injector.getInstance(ListenerModule.class) |
199 | | - .createComparatorListener(comparator, redstoneClockService, tps, this); |
200 | | - getServer().getPluginManager().registerEvents(listener, this); |
201 | | - } else { |
202 | | - var listener1 = injector.getInstance(ListenerModule.class) |
203 | | - .createComparatorListener(Material.getMaterial("REDSTONE_COMPARATOR_OFF"), redstoneClockService, tps, this); |
204 | | - var listener2 = injector.getInstance(ListenerModule.class) |
205 | | - .createComparatorListener(Material.getMaterial("REDSTONE_COMPARATOR_ON"), redstoneClockService, tps, this); |
206 | | - getServer().getPluginManager().registerEvents(listener1, this); |
207 | | - getServer().getPluginManager().registerEvents(listener2, this); |
208 | | - } |
209 | | - } |
210 | | - |
211 | | - if (getConfig().getBoolean("check.redstoneAndRepeater", true)) { |
212 | | - var repeater = Material.getMaterial("REPEATER"); |
213 | | - if (repeater != null) { |
214 | | - var listener = injector.getInstance(ListenerModule.class) |
215 | | - .createRedstoneListener(repeater, redstoneClockService, tps, this); |
216 | | - getServer().getPluginManager().registerEvents(listener, this); |
217 | | - } else { |
218 | | - var listener1 = injector.getInstance(ListenerModule.class) |
219 | | - .createRedstoneListener(Material.getMaterial("DIODE_BLOCK_ON"), redstoneClockService, tps, this); |
220 | | - var listener2 = injector.getInstance(ListenerModule.class) |
221 | | - .createRedstoneListener(Material.getMaterial("DIODE_BLOCK_OFF"), redstoneClockService, tps, this); |
222 | | - getServer().getPluginManager().registerEvents(listener1, this); |
223 | | - getServer().getPluginManager().registerEvents(listener2, this); |
224 | | - } |
225 | | - } |
226 | | - } |
227 | | - |
228 | | - private void enableTPSChecker() { |
229 | | - this.tps.startCheck(); |
230 | | - } |
231 | | - |
232 | | - private void enableBStatsSupport() { |
233 | | - this.metrics = new Metrics(this, 19085); |
234 | | - this.metrics.addCustomChart(new SimplePie("worldguard", this::bstatsWorldGuardVersion)); |
235 | | - this.metrics.addCustomChart(new SimplePie("plotsquared", this::bstatsPlotSquaredVersion)); |
236 | | - this.metrics.addCustomChart(new DrilldownPie("maxcount", this::bstatsMaxCount)); |
237 | | - } |
238 | | - |
239 | | - private Map<String, Map<String, Integer>> bstatsMaxCount() { |
240 | | - var map = new HashMap<String, Map<String, Integer>>(); |
241 | | - var count = getConfig().getInt("clock.maxCount"); |
242 | | - var entry = Map.of(String.valueOf(count), 1); |
243 | | - switch (count) { |
244 | | - case 0 -> map.put("0 \uD83D\uDEAB", entry); |
245 | | - case 1, 2, 3, 4, 5 -> map.put("1-5 \uD83D\uDE10", entry); |
246 | | - case 6, 7, 8, 9, 10 -> map.put("6-10 \uD83D\uDE42", entry); |
247 | | - case 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 -> map.put("11-25 \uD83D\uDE0A", entry); |
248 | | - case 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 -> |
249 | | - map.put("26-50 \uD83D\uDE00", entry); |
250 | | - default -> map.put("50+ \uD83D\uDE01", entry); |
251 | | - } |
252 | | - return map; |
253 | | - } |
254 | | - |
255 | | - private String bstatsPlotSquaredVersion() { |
256 | | - if (this.plotsquaredSupport != null) { |
257 | | - return this.plotsquaredSupport.getVersion(); |
258 | | - } |
259 | | - return "unknown"; |
260 | | - } |
261 | | - |
262 | | - private String bstatsWorldGuardVersion() { |
263 | | - if (this.worldGuardSupport != null) { |
264 | | - return this.worldGuardSupport.getVersion(); |
265 | | - } |
266 | | - return "unknown"; |
267 | | - } |
268 | | - |
269 | | - private void loadAndRegisterTranslation(Locale locale, Path langFolder, TranslationService translationService) { |
270 | | - try { |
271 | | - ResourceBundle bundle = loadResourceBundle(locale, langFolder); |
272 | | - if (bundle != null) { |
273 | | - translationService.registerAll(locale, bundle, false); |
274 | | - } |
275 | | - } catch (Exception e) { |
276 | | - getSLF4JLogger().error("An error occurred while loading language file for locale {}", locale, e); |
277 | | - } |
278 | | - } |
279 | | - |
280 | | - private ResourceBundle loadResourceBundle(Locale locale, Path langFolder) throws Exception { |
281 | | - Path langFile = langFolder.resolve(RESOURCE_BUNDLE_NAME + "_" + locale.toLanguageTag() + ".properties"); |
282 | | - |
283 | | - if (Files.exists(langFile)) { |
284 | | - try (URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{langFolder.toUri().toURL()})) { |
285 | | - return ResourceBundle.getBundle(RESOURCE_BUNDLE_NAME, locale, urlClassLoader, UTF8ResourceBundleControl.get()); |
286 | | - } |
287 | | - } else { |
288 | | - return ResourceBundle.getBundle(RESOURCE_BUNDLE_NAME, locale, UTF8ResourceBundleControl.get()); |
289 | | - } |
290 | | - } |
291 | | - |
292 | | - public CheckTPS getTps() { |
293 | | - return tps; |
294 | | - } |
295 | | - |
296 | | - public RedstoneClockService getRedstoneClockService() { |
297 | | - return redstoneClockService; |
298 | | - } |
299 | | - |
300 | | - public WorldGuardSupport getWorldGuardSupport() { |
301 | | - return worldGuardSupport; |
302 | | - } |
303 | | - |
304 | | - public PlotsquaredSupport getPlotsquaredSupport() { |
305 | | - return plotsquaredSupport; |
306 | | - } |
307 | | - |
308 | | - public UpdateService getUpdateService() { |
309 | | - return updateService; |
310 | | - } |
311 | 65 | } |
0 commit comments