Skip to content

Commit acd210f

Browse files
committed
added update checks for my mods, turned fplib into a regular mod, added async lib
1 parent fd10586 commit acd210f

File tree

8 files changed

+204
-54
lines changed

8 files changed

+204
-54
lines changed

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ mixinPreinitConfig =
7676
coreModClass = internal.CoreLoadingPlugin
7777
# If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class
7878
# that is annotated with @Mod) you want this to be true. When in doubt: leave it on false!
79-
containsMixinsAndOrCoreModOnly = true
79+
containsMixinsAndOrCoreModOnly = false
8080

8181
# If enabled, you may use 'shadowImplementation' for dependencies. They will be integrated in your jar. It is your
8282
# responsibility check the licence and request permission for distribution, if required.

src/main/java/com/falsepattern/lib/internal/CoreLoadingPlugin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public String[] getASMTransformerClass() {
2020

2121
@Override
2222
public String getModContainerClass() {
23-
return Tags.GROUPNAME + ".internal.FalsePatternLib";
23+
return null;
2424
}
2525

2626
@Override

src/main/java/com/falsepattern/lib/internal/FalsePatternLib.java

Lines changed: 41 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,87 +2,84 @@
22

33
import com.falsepattern.lib.config.ConfigException;
44
import com.falsepattern.lib.config.ConfigurationManager;
5+
import com.falsepattern.lib.internal.proxy.CommonProxy;
6+
import com.falsepattern.lib.text.FormattedText;
57
import com.falsepattern.lib.updates.ModUpdateInfo;
68
import com.falsepattern.lib.updates.UpdateChecker;
7-
import com.falsepattern.lib.util.ResourceUtil;
8-
import com.google.common.eventbus.EventBus;
9-
import com.google.common.eventbus.Subscribe;
10-
import cpw.mods.fml.common.DummyModContainer;
11-
import cpw.mods.fml.common.LoadController;
12-
import cpw.mods.fml.common.Loader;
13-
import cpw.mods.fml.common.MetadataCollection;
9+
import cpw.mods.fml.common.*;
1410
import cpw.mods.fml.common.event.FMLConstructionEvent;
15-
import cpw.mods.fml.common.event.FMLInterModComms;
1611
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
1712
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
13+
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
14+
import cpw.mods.fml.relauncher.Side;
15+
import cpw.mods.fml.relauncher.SideOnly;
1816
import lombok.Getter;
19-
import lombok.SneakyThrows;
2017
import lombok.val;
18+
import net.minecraft.client.entity.EntityPlayerSP;
19+
import net.minecraft.client.resources.I18n;
20+
import net.minecraft.event.ClickEvent;
2121
import net.minecraft.launchwrapper.Launch;
22+
import net.minecraft.util.ChatComponentText;
23+
import net.minecraft.util.ChatStyle;
24+
import net.minecraft.util.EnumChatFormatting;
25+
import net.minecraft.util.IChatComponent;
26+
import net.minecraftforge.common.MinecraftForge;
27+
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
2228
import org.apache.logging.log4j.LogManager;
2329
import org.apache.logging.log4j.Logger;
2430

31+
import java.util.ArrayList;
2532
import java.util.List;
2633
import java.util.concurrent.ExecutionException;
34+
import java.util.concurrent.ExecutorService;
35+
import java.util.concurrent.Executors;
2736
import java.util.concurrent.Future;
37+
import java.util.concurrent.atomic.AtomicBoolean;
2838

2939
/**
3040
* Utility class used by FalsePatternLib's internal code. This can change between versions without notice, so do not use
3141
* this in your code!
3242
*/
3343
@SuppressWarnings("UnstableApiUsage")
34-
public class FalsePatternLib extends DummyModContainer {
44+
@Mod(modid = Tags.MODID,
45+
name = Tags.MODNAME,
46+
version = Tags.VERSION,
47+
acceptedMinecraftVersions = "[1.7.10]",
48+
acceptableRemoteVersions = "*")
49+
public class FalsePatternLib {
3550
@Getter private static final Logger log = LogManager.getLogger(Tags.MODNAME);
3651

3752
@Getter private static final boolean developerEnvironment =
3853
(boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment");
3954

40-
private Future<List<ModUpdateInfo>> updateCheckFuture;
55+
@Getter
56+
private static final ExecutorService asyncWorker = Executors.newSingleThreadExecutor((runnable) -> {
57+
Thread thread = new Thread(runnable);
58+
thread.setDaemon(true);
59+
thread.setName(Tags.MODNAME + " Async Worker");
60+
return thread;
61+
});
62+
63+
@SidedProxy(clientSide = Tags.GROUPNAME + ".internal.proxy.ClientProxy", serverSide = Tags.GROUPNAME + ".internal.proxy.CommonProxy")
64+
private static CommonProxy proxy;
4165

4266
public FalsePatternLib() {
43-
super(MetadataCollection.from(ResourceUtil.getResourceFromJar("/mcmod.info", FalsePatternLib.class), Tags.MODID)
44-
.getMetadataForId(Tags.MODID, null));
4567
log.info("Version " + Tags.VERSION + " initialized!");
4668
}
4769

48-
@SuppressWarnings("UnstableApiUsage")
49-
@Subscribe
70+
@Mod.EventHandler
5071
public void construct(FMLConstructionEvent e) {
51-
ConfigurationManager.init();
52-
try {
53-
ConfigurationManager.registerConfig(LibraryConfig.class);
54-
} catch (ConfigException ex) {
55-
getLog().error("Failed to register " + Tags.MODNAME + " config!", ex);
56-
}
72+
proxy.construct(e);
5773
}
5874

59-
@Subscribe
75+
@Mod.EventHandler
6076
public void preInit(FMLPreInitializationEvent e) {
61-
if (LibraryConfig.ENABLE_UPDATE_CHECKER) {
62-
getLog().info("Launching asynchronous update check. I'll check back on it during postInit.");
63-
updateCheckFuture = UpdateChecker.fetchUpdatesAsync("https://falsepattern.com/mc/versions.json");
64-
}
77+
proxy.preInit(e);
6578
}
6679

67-
@Subscribe
80+
@Mod.EventHandler
6881
public void postInit(FMLPostInitializationEvent e) {
69-
if (updateCheckFuture != null && !updateCheckFuture.isCancelled()) {
70-
try {
71-
val updates = updateCheckFuture.get();
72-
if (updates != null)
73-
for (val update: updates)
74-
update.log(getLog());
75-
} catch (InterruptedException | ExecutionException ex) {
76-
getLog().warn("Error while checking updates", ex);
77-
}
78-
79-
}
82+
proxy.postInit(e);
8083
}
8184

82-
@SuppressWarnings("UnstableApiUsage")
83-
@Override
84-
public boolean registerBus(EventBus bus, LoadController controller) {
85-
bus.register(this);
86-
return true;
87-
}
8885
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.falsepattern.lib.internal.proxy;
2+
3+
import com.falsepattern.lib.internal.FalsePatternLib;
4+
import com.falsepattern.lib.text.FormattedText;
5+
import cpw.mods.fml.common.Loader;
6+
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
7+
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
8+
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
9+
import cpw.mods.fml.relauncher.Side;
10+
import cpw.mods.fml.relauncher.SideOnly;
11+
import lombok.val;
12+
import net.minecraft.client.entity.EntityPlayerSP;
13+
import net.minecraft.client.resources.I18n;
14+
import net.minecraft.event.ClickEvent;
15+
import net.minecraft.util.IChatComponent;
16+
import net.minecraftforge.common.MinecraftForge;
17+
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
18+
19+
import java.util.ArrayList;
20+
import java.util.List;
21+
import java.util.concurrent.Future;
22+
23+
@SideOnly(Side.CLIENT)
24+
public class ClientProxy extends CommonProxy {
25+
private Future<List<IChatComponent>> chatFuture;
26+
27+
@Override
28+
public void preInit(FMLPreInitializationEvent e) {
29+
super.preInit(e);
30+
MinecraftForge.EVENT_BUS.register(this);
31+
}
32+
33+
@Override
34+
public void postInit(FMLPostInitializationEvent e) {
35+
super.postInit(e);
36+
chatFuture = FalsePatternLib.getAsyncWorker().submit(() -> {
37+
long start = System.nanoTime();
38+
val updates = updatesFuture.get();
39+
if (updates == null || updates.size() == 0) return null;
40+
val updateText = new ArrayList<IChatComponent>(FormattedText.parse(I18n.format("falsepatternlib.chat.updatesavailable")).toChatText());
41+
val mods = Loader.instance().getIndexedModList();
42+
for (val update : updates) {
43+
val mod = mods.get(update.modID);
44+
updateText.addAll(FormattedText.parse(I18n.format("falsepatternlib.chat.modname", mod.getName())).toChatText());
45+
updateText.addAll(FormattedText.parse(I18n.format("falsepatternlib.chat.currentversion", update.currentVersion)).toChatText());
46+
updateText.addAll(FormattedText.parse(I18n.format("falsepatternlib.chat.latestversion", update.latestVersion)).toChatText());
47+
if (!update.updateURL.isEmpty()) {
48+
val pre = FormattedText.parse(I18n.format("falsepatternlib.chat.updateurlpre")).toChatText();
49+
val link = FormattedText.parse(I18n.format("falsepatternlib.chat.updateurl")).toChatText();
50+
val post = FormattedText.parse(I18n.format("falsepatternlib.chat.updateurlpost")).toChatText();
51+
pre.get(pre.size() - 1).appendSibling(link.get(0));
52+
link.get(link.size() - 1).appendSibling(post.get(0));
53+
for (val l: link) {
54+
l.getChatStyle().setChatClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, update.updateURL));
55+
}
56+
link.remove(0);
57+
post.remove(0);
58+
updateText.addAll(pre);
59+
updateText.addAll(link);
60+
updateText.addAll(post);
61+
}
62+
}
63+
long end = System.nanoTime();
64+
FalsePatternLib.getLog().info("Constructed in {} ms", (end - start) / 1000000L);
65+
return updateText;
66+
});
67+
}
68+
69+
@SubscribeEvent
70+
public void onSinglePlayer(EntityJoinWorldEvent e) {
71+
if (chatFuture == null ||
72+
!(e.entity instanceof EntityPlayerSP)) return;
73+
val player = (EntityPlayerSP) e.entity;
74+
try {
75+
for (val line: chatFuture.get()) {
76+
player.addChatMessage(line);
77+
}
78+
chatFuture = null;
79+
} catch (Exception ex) {
80+
FalsePatternLib.getLog().warn(ex);
81+
}
82+
}
83+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.falsepattern.lib.internal.proxy;
2+
3+
import com.falsepattern.lib.config.ConfigException;
4+
import com.falsepattern.lib.config.ConfigurationManager;
5+
import com.falsepattern.lib.internal.FalsePatternLib;
6+
import com.falsepattern.lib.internal.LibraryConfig;
7+
import com.falsepattern.lib.internal.Tags;
8+
import com.falsepattern.lib.updates.ModUpdateInfo;
9+
import com.falsepattern.lib.updates.UpdateChecker;
10+
import cpw.mods.fml.common.event.FMLConstructionEvent;
11+
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
12+
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
13+
import lombok.val;
14+
import lombok.var;
15+
import net.minecraftforge.common.MinecraftForge;
16+
17+
import java.util.List;
18+
import java.util.concurrent.ExecutionException;
19+
import java.util.concurrent.Future;
20+
21+
public class CommonProxy {
22+
23+
protected Future<List<ModUpdateInfo>> updatesFuture;
24+
25+
public void construct(FMLConstructionEvent e) {
26+
ConfigurationManager.init();
27+
}
28+
29+
public void preInit(FMLPreInitializationEvent e) {
30+
try {
31+
ConfigurationManager.registerConfig(LibraryConfig.class);
32+
} catch (ConfigException ex) {
33+
FalsePatternLib.getLog().error("Failed to register " + Tags.MODNAME + " config!", ex);
34+
}
35+
if (LibraryConfig.ENABLE_UPDATE_CHECKER) {
36+
FalsePatternLib.getLog().info("Launching asynchronous update check.");
37+
val updateCheckFuture = UpdateChecker.fetchUpdatesAsync("https://falsepattern.com/mc/versions.json");
38+
updatesFuture = FalsePatternLib.getAsyncWorker().submit(() -> {
39+
if (!updateCheckFuture.isCancelled()) {
40+
try {
41+
var updates = updateCheckFuture.get();
42+
if (updates != null && updates.size() > 0) {
43+
for (val update:updates) {
44+
update.log(FalsePatternLib.getLog());
45+
}
46+
} else if (updates == null) {
47+
FalsePatternLib.getLog().warn("Unknown error while checking updates");
48+
} else {
49+
FalsePatternLib.getLog().info("All FalsePattern mods up to date!");
50+
updates = null;
51+
}
52+
return updates;
53+
} catch (InterruptedException | ExecutionException ex) {
54+
FalsePatternLib.getLog().warn("Error while checking updates", ex);
55+
}
56+
}
57+
return null;
58+
});
59+
}
60+
}
61+
62+
public void postInit(FMLPostInitializationEvent e) {
63+
64+
}
65+
66+
67+
}

src/main/java/com/falsepattern/lib/updates/UpdateChecker.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,14 @@
2727
@StableAPI(since = "0.8.0")
2828
public class UpdateChecker {
2929
private static final AtomicInteger jsonLibraryLoaded = new AtomicInteger(0);
30-
private static final ExecutorService asyncExecutor = Executors.newSingleThreadExecutor((runnable) -> {
31-
Thread thread = new Thread(runnable);
32-
thread.setDaemon(true);
33-
thread.setName(Tags.MODNAME + " Asynchronous Update Check Thread");
34-
return thread;
35-
});
3630
/**
3731
* Same this as {@link #fetchUpdates(String)}, but defers the check to a different thread. Useful for asynchronous
3832
* update checks, if you don't want to block loading.
3933
* @param url The URL to check
4034
* @return A future that will contain the update info about mods that were both available on the URL and installed
4135
*/
4236
public static Future<List<ModUpdateInfo>> fetchUpdatesAsync(String url) {
43-
return asyncExecutor.submit(() -> fetchUpdates(url));
37+
return FalsePatternLib.getAsyncWorker().submit(() -> fetchUpdates(url));
4438
}
4539

4640
/**
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
config.falsepatternlib.updatecheck=Enable update checks
22
config.falsepatternlib.updatecheck.tooltip=Used to control whether FalsePatternLib should check for outdated mods.
33
config.falsepatternlib.disableinternet=FalsePatternLib Offline Mode
4-
config.falsepatternlib.disableinternet.tooltip=Used to control whether FalsePatternLib should be allowed to use the internet. If this is enabled, update checks and library downloads will be completely blocked.
4+
config.falsepatternlib.disableinternet.tooltip=Used to control whether FalsePatternLib should be allowed to use the internet. If this is enabled, update checks and library downloads will be completely blocked.
5+
falsepatternlib.chat.updatesavailable=§4Outdated mods detected! §r
6+
falsepatternlib.chat.modname=§b§l[%s]§r
7+
falsepatternlib.chat.currentversion= Current Version: §6%s§r
8+
falsepatternlib.chat.latestversion= Latest Version: §2%s§r
9+
falsepatternlib.chat.updateurlpre= Click
10+
falsepatternlib.chat.updateurl= §n§o§dHERE§r
11+
falsepatternlib.chat.updateurlpost= to visit update page
12+
falsepatternlib.chat.updateavailablefor=§1§l[%s]§r Current version: §6%s§r Latest version: §2%s§r

src/main/resources/pack.mcmeta

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

0 commit comments

Comments
 (0)