• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CyclopsMC / CyclopsCore / #479033814

10 Nov 2025 01:50PM UTC coverage: 22.089% (-0.002%) from 22.091%
#479033814

push

github

rubensworks
Fix commands not being available after reload command

Closes CyclopsMC/IntegratedDynamics#1556

0 of 2 new or added lines in 1 file covered. (0.0%)

1 existing line in 1 file now uncovered.

2297 of 10399 relevant lines covered (22.09%)

0.22 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/main/java/org/cyclops/cyclopscore/init/ModBase.java
1
package org.cyclops.cyclopscore.init;
2

3
import com.google.common.collect.Lists;
4
import com.google.common.collect.Maps;
5
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
6
import lombok.Data;
7
import net.minecraft.commands.CommandSourceStack;
8
import net.minecraft.commands.Commands;
9
import net.minecraft.world.item.CreativeModeTab;
10
import net.minecraftforge.api.distmarker.Dist;
11
import net.minecraftforge.api.distmarker.OnlyIn;
12
import net.minecraftforge.client.event.RegisterKeyMappingsEvent;
13
import net.minecraftforge.common.MinecraftForge;
14
import net.minecraftforge.event.RegisterCommandsEvent;
15
import net.minecraftforge.event.server.ServerAboutToStartEvent;
16
import net.minecraftforge.event.server.ServerStartedEvent;
17
import net.minecraftforge.event.server.ServerStartingEvent;
18
import net.minecraftforge.event.server.ServerStoppingEvent;
19
import net.minecraftforge.eventbus.api.EventPriority;
20
import net.minecraftforge.eventbus.api.SubscribeEvent;
21
import net.minecraftforge.fml.DistExecutor;
22
import net.minecraftforge.fml.ModContainer;
23
import net.minecraftforge.fml.ModList;
24
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
25
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
26
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
27
import net.minecraftforge.registries.ForgeRegistries;
28
import net.minecraftforge.registries.NewRegistryEvent;
29
import net.minecraftforge.registries.RegisterEvent;
30
import org.apache.logging.log4j.Level;
31
import org.cyclops.cyclopscore.client.icon.IconProvider;
32
import org.cyclops.cyclopscore.client.key.IKeyRegistry;
33
import org.cyclops.cyclopscore.client.key.KeyRegistry;
34
import org.cyclops.cyclopscore.command.CommandConfig;
35
import org.cyclops.cyclopscore.command.CommandVersion;
36
import org.cyclops.cyclopscore.config.ConfigHandler;
37
import org.cyclops.cyclopscore.helper.LoggerHelper;
38
import org.cyclops.cyclopscore.modcompat.IMCHandler;
39
import org.cyclops.cyclopscore.modcompat.ModCompatLoader;
40
import org.cyclops.cyclopscore.modcompat.capabilities.CapabilityConstructorRegistry;
41
import org.cyclops.cyclopscore.network.PacketHandler;
42
import org.cyclops.cyclopscore.persist.world.WorldStorage;
43
import org.cyclops.cyclopscore.proxy.ClientProxyComponent;
44
import org.cyclops.cyclopscore.proxy.IClientProxy;
45
import org.cyclops.cyclopscore.proxy.ICommonProxy;
46

47
import java.util.List;
48
import java.util.Map;
49
import java.util.function.Consumer;
50

51
/**
52
 * Base class for mods which adds a few convenience methods.
53
 * Dont forget to call the supers for the init events.
54
 * @author rubensworks
55
 */
56
@Data
×
57
public abstract class ModBase<T extends ModBase> {
58

59
    public static final EnumReferenceKey<String> REFKEY_TEXTURE_PATH_GUI = EnumReferenceKey.create("texture_path_gui", String.class);
×
60
    public static final EnumReferenceKey<String> REFKEY_TEXTURE_PATH_MODELS = EnumReferenceKey.create("texture_path_models", String.class);
×
61
    public static final EnumReferenceKey<String> REFKEY_TEXTURE_PATH_SKINS = EnumReferenceKey.create("texture_path_skins", String.class);
×
62
    public static final EnumReferenceKey<Boolean> REFKEY_RETROGEN = EnumReferenceKey.create("retrogen", Boolean.class);
×
63
    public static final EnumReferenceKey<Boolean> REFKEY_CRASH_ON_INVALID_RECIPE = EnumReferenceKey.create("crash_on_invalid_recipe", Boolean.class);
×
64
    public static final EnumReferenceKey<Boolean> REFKEY_CRASH_ON_MODCOMPAT_CRASH = EnumReferenceKey.create("crash_on_modcompat_crash", Boolean.class);
×
65
    public static final EnumReferenceKey<Boolean> REFKEY_INFOBOOK_REWARDS = EnumReferenceKey.create("rewards", Boolean.class);
×
66

67
    private final String modId;
×
68
    private final LoggerHelper loggerHelper;
×
69
    private final ConfigHandler configHandler;
×
70
    private final Map<EnumReferenceKey<?>, Object> genericReference = Maps.newHashMap();
×
71
    private final List<WorldStorage> worldStorages = Lists.newLinkedList();
×
72
    private final RegistryManager registryManager;
×
73
    private final IKeyRegistry keyRegistry;
×
74
    private final PacketHandler packetHandler;
×
75
    private final ModCompatLoader modCompatLoader;
×
76
    private final CapabilityConstructorRegistry capabilityConstructorRegistry;
×
77
    private final IMCHandler imcHandler;
×
78

79
    private ICommonProxy proxy;
80
    private ModContainer container;
81

82
    private CreativeModeTab defaultCreativeTab = null;
×
83

84
    public ModBase(String modId, Consumer<T> instanceSetter) {
×
85
        instanceSetter.accept((T) this);
×
86
        this.modId = modId;
×
87
        this.loggerHelper = constructLoggerHelper();
×
88
        this.configHandler = constructConfigHandler();
×
89
        this.registryManager = constructRegistryManager();
×
90
        this.keyRegistry = new KeyRegistry();
×
91
        this.packetHandler = constructPacketHandler();
×
92
        this.modCompatLoader = constructModCompatLoader();
×
93
        this.capabilityConstructorRegistry = constructCapabilityConstructorRegistry();
×
94
        this.imcHandler = constructIMCHandler();
×
95

96
        // Register listeners
97
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
×
98
        DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setupClient));
×
99
        FMLJavaModLoadingContext.get().getModEventBus().addListener(EventPriority.LOWEST, this::afterRegistriesCreated);
×
100
        FMLJavaModLoadingContext.get().getModEventBus().addListener(EventPriority.HIGHEST, this::beforeRegistriedFilled);
×
101
        DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onRegisterKeyMappings));
×
102
        MinecraftForge.EVENT_BUS.register(this);
×
103

104
        // Register proxies
105
        DistExecutor.runForDist(
×
106
                () -> () -> this.proxy = this.constructClientProxy(),
×
107
                () -> () -> this.proxy = this.constructCommonProxy()
×
108
        );
109

110
        populateDefaultGenericReferences();
×
111

112
        // Initialize config handler
113
        this.onConfigsRegister(getConfigHandler());
×
114
        getConfigHandler().initialize(Lists.newArrayList());
×
115
        getConfigHandler().loadModInit();
×
116

117
        loadModCompats(getModCompatLoader());
×
118
    }
×
119

120
    public String getModName() {
121
        return getContainer().getModInfo().getDisplayName();
×
122
    }
123

124
    /**
125
     * @return The mod container of this mod.
126
     */
127
    public ModContainer getContainer() {
128
        if (container == null) {
×
129
            container = ModList.get().getModContainerByObject(this).get();
×
130
        }
131
        return container;
×
132
    }
133

134
    protected LoggerHelper constructLoggerHelper() {
135
        return new LoggerHelper(getModId());
×
136
    }
137

138
    protected ConfigHandler constructConfigHandler() {
139
        return new ConfigHandler(this);
×
140
    }
141

142
    protected RegistryManager constructRegistryManager() {
143
        return new RegistryManager();
×
144
    }
145

146
    protected PacketHandler constructPacketHandler() {
147
        return new PacketHandler(this);
×
148
    }
149

150
    protected ModCompatLoader constructModCompatLoader() {
151
        return new ModCompatLoader(this);
×
152
    }
153

154
    protected CapabilityConstructorRegistry constructCapabilityConstructorRegistry() {
155
        return new CapabilityConstructorRegistry(this);
×
156
    }
157

158
    protected IMCHandler constructIMCHandler() {
159
        return new IMCHandler(this);
×
160
    }
161

162
    protected LiteralArgumentBuilder<CommandSourceStack> constructBaseCommand() {
163
        LiteralArgumentBuilder<CommandSourceStack> root = Commands.literal(this.getModId());
×
164

165
        root.then(CommandConfig.make(this));
×
166
        root.then(CommandVersion.make(this));
×
167

168
        return root;
×
169
    }
170

171
    /**
172
     * @return The icon provider that was constructed in {@link ClientProxyComponent}.
173
     */
174
    @OnlyIn(Dist.CLIENT)
175
    public IconProvider getIconProvider() {
176
        return ((ClientProxyComponent) getProxy()).getIconProvider();
×
177
    }
178

179
    /**
180
     * Save a mod value.
181
     * @param key The key.
182
     * @param value The value.
183
     * @param <T> The value type.
184
     */
185
    public <T> void putGenericReference(EnumReferenceKey<T> key, T value) {
186
        genericReference.put(key, value);
×
187
    }
×
188

189
    private void populateDefaultGenericReferences() {
190
        putGenericReference(REFKEY_TEXTURE_PATH_GUI, "textures/gui/");
×
191
        putGenericReference(REFKEY_TEXTURE_PATH_MODELS, "textures/models/");
×
192
        putGenericReference(REFKEY_TEXTURE_PATH_SKINS, "textures/skins/");
×
193
        putGenericReference(REFKEY_RETROGEN, false);
×
194
        putGenericReference(REFKEY_CRASH_ON_INVALID_RECIPE, false);
×
195
        putGenericReference(REFKEY_CRASH_ON_MODCOMPAT_CRASH, false);
×
196
        putGenericReference(REFKEY_INFOBOOK_REWARDS, true);
×
197
    }
×
198

199
    /**
200
     * This is called only once to let the mod compatibilities register themselves.
201
     * @param modCompatLoader The loader.
202
     */
203
    protected void loadModCompats(ModCompatLoader modCompatLoader) {
204

205
    }
×
206

207
    /**
208
     * Get the value for a generic reference key.
209
     * The default keys can be found in {@link org.cyclops.cyclopscore.init.ModBase}.
210
     * @param key The key of a value.
211
     * @param <T> The type of value.
212
     * @return The value for the given key.
213
     */
214
    @SuppressWarnings("unchecked")
215
    public <T> T getReferenceValue(EnumReferenceKey<T> key) {
216
        if(!genericReference.containsKey(key)) throw new IllegalArgumentException("Could not find " + key + " as generic reference item.");
×
217
        return (T) genericReference.get(key);
×
218
    }
219

220
    /**
221
     * Log a new info message for this mod.
222
     * @param message The message to show.
223
     */
224
    public void log(String message) {
225
        log(Level.INFO, message);
×
226
    }
×
227

228
    /**
229
     * Log a new message of the given level for this mod.
230
     * @param level The level in which the message must be shown.
231
     * @param message The message to show.
232
     */
233
    public void log(Level level, String message) {
234
        loggerHelper.log(level, message);
×
235
    }
×
236

237
    /**
238
     * Called on the Forge setup lifecycle event.
239
     * @param event The setup event.
240
     */
241
    protected void setup(FMLCommonSetupEvent event) {
242
        log(Level.TRACE, "setup()");
×
243

244
        // Iterate over all configs again
245
        getConfigHandler().loadSetup();
×
246

247
        // Register proxy things
248
        ICommonProxy proxy = getProxy();
×
249
        if(proxy != null) {
×
250
            proxy.registerEventHooks();
×
251
            getPacketHandler().init();
×
252
            proxy.registerPacketHandlers(getPacketHandler());
×
253
            proxy.registerTickHandlers();
×
254
        }
255

256
        // Initialize the creative tab
257
        getDefaultItemGroup();
×
258
    }
×
259

260
    /**
261
     * Called on the Forge client setup lifecycle event.
262
     * @param event The setup event.
263
     */
264
    protected void setupClient(FMLClientSetupEvent event) {
265
        // Register proxy things
266
        ICommonProxy proxy = getProxy();
×
267
        if(proxy != null) {
×
268
            proxy.registerRenderers();
×
269
        }
270
    }
×
271

272
    protected void onRegisterKeyMappings(RegisterKeyMappingsEvent event) {
273
        ICommonProxy proxy = getProxy();
×
274
        if(proxy != null) {
×
275
            proxy.registerKeyBindings(getKeyRegistry(), event);
×
276
        }
277
    }
×
278

279
    /**
280
     * Load things after Forge registries have been created.
281
     * @param event The Forge registry creation event.
282
     */
283
    private void afterRegistriesCreated(NewRegistryEvent event) {
284
        getConfigHandler().loadForgeRegistries();
×
285
    }
×
286

287
    /**
288
     * Load things before Forge registries are being filled.
289
     * @param event The Forge registry filling event.
290
     */
291
    private void beforeRegistriedFilled(RegisterEvent event) {
292
        if (event.getRegistryKey().equals(ForgeRegistries.BLOCKS.getRegistryKey())) {
×
293
            // We only need to call this once, and the blocks event is emitted first.
294
            getConfigHandler().loadForgeRegistriesFilled();
×
295
        }
296
    }
×
297

298
    /**
299
     * Register the things that are related to when the server is starting.
300
     * @param event The Forge server starting event.
301
     */
302
    @SubscribeEvent
303
    protected void onServerStarting(ServerStartingEvent event) {
304

NEW
305
    }
×
306

307
    @SubscribeEvent
308
    protected void onRegisterCommands(RegisterCommandsEvent event) {
NEW
309
        event.getDispatcher().register(constructBaseCommand());
×
UNCOV
310
    }
×
311

312
    /**
313
     * Register the things that are related to when the server is about to start.
314
     * @param event The Forge server about to start event.
315
     */
316
    @SubscribeEvent
317
    protected void onServerAboutToStart(ServerAboutToStartEvent event) {
318
        for(WorldStorage worldStorage : worldStorages) {
×
319
            worldStorage.onAboutToStartEvent(event);
×
320
        }
×
321
    }
×
322

323
    /**
324
     * Register the things that are related to server starting.
325
     * @param event The Forge server started event.
326
     */
327
    @SubscribeEvent
328
    protected void onServerStarted(ServerStartedEvent event) {
329
        for(WorldStorage worldStorage : worldStorages) {
×
330
            worldStorage.onStartedEvent(event);
×
331
        }
×
332
    }
×
333

334
    /**
335
     * Register the things that are related to server stopping, like persistent storage.
336
     * @param event The Forge server stopping event.
337
     */
338
    @SubscribeEvent
339
    protected void onServerStopping(ServerStoppingEvent event) {
340
        for(WorldStorage worldStorage : worldStorages) {
×
341
            worldStorage.onStoppingEvent(event);
×
342
        }
×
343
    }
×
344

345
    /**
346
     * Register a new world storage type.
347
     * Make sure to call this at least before the event
348
     * {@link net.minecraftforge.event.server.ServerStartedEvent} is called.
349
     * @param worldStorage The world storage to register.
350
     */
351
    public void registerWorldStorage(WorldStorage worldStorage) {
352
        worldStorages.add(worldStorage);
×
353
    }
×
354

355
    @OnlyIn(Dist.CLIENT)
356
    protected abstract IClientProxy constructClientProxy();
357

358
    @OnlyIn(Dist.DEDICATED_SERVER)
359
    protected abstract ICommonProxy constructCommonProxy();
360

361
    /**
362
     * Construct an item group, will only be called once during the init event.
363
     * @return The default item group for items and blocks.
364
     */
365
    protected abstract CreativeModeTab constructDefaultCreativeModeTab();
366

367
    /**
368
     * Called when the configs should be registered.
369
     * @param configHandler The config handler to register to.
370
     */
371
    protected void onConfigsRegister(ConfigHandler configHandler) {
372

373
    }
×
374

375
    /**
376
     * @return The default item group for items and blocks.
377
     */
378
    public final CreativeModeTab getDefaultItemGroup() {
379
        if(defaultCreativeTab == null) {
×
380
            defaultCreativeTab = constructDefaultCreativeModeTab();
×
381
        }
382
        return defaultCreativeTab;
×
383
    }
384

385
    /**
386
     * @return The proxy for this mod.
387
     */
388
    public ICommonProxy getProxy() {
389
        return this.proxy;
×
390
    }
391

392
    @Override
393
    public String toString() {
394
        return getModId();
×
395
    }
396

397
    @Override
398
    public int hashCode() {
399
        return toString().hashCode();
×
400
    }
401

402
    @Override
403
    public boolean equals(Object object) {
404
        return object == this;
×
405
    }
406

407
    /**
408
     * Get the mod by id.
409
     * @param modId The mod id.
410
     * @return The mod instance or null.
411
     */
412
    public static ModBase get(String modId) {
413
        ModContainer modContainer = ModList.get().getModContainerById(modId).orElse(null);
×
414
        Object mod = modContainer.getMod();
×
415
        if (mod instanceof ModBase) {
×
416
            return (ModBase) mod;
×
417
        }
418
        return null;
×
419
    }
420

421
    /**
422
     * Unique references to values that can be registered inside a mod.
423
     * @param <T> The type of value.
424
     */
425
    @Data
×
426
    public static class EnumReferenceKey<T> {
427

428
        private final String key;
×
429
        private final Class<T> type;
×
430

431
        private EnumReferenceKey(String key, Class<T> type) {
×
432
            this.key = key;
×
433
            this.type = type;
×
434
        }
×
435

436
        public static <T> EnumReferenceKey<T> create(String key, Class<T> type) {
437
            return new EnumReferenceKey<>(key, type);
×
438
        }
439

440
    }
441

442
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc