package mhfc.net.common.system;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import cpw.mods.fml.common.event.FMLServerStartedEvent;
import mhfc.net.common.util.lib.MHFCReference;
import net.minecraft.command.ICommandSender;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ChatComponentText;
public class UpdateSystem {
public static enum UpdateStatus {
NEWUPDATE,
NOUPDATE,
OFFLINE,
FAILED;
}
public static class UpdateInfo {
public final UpdateStatus status;
public final String version;
public UpdateInfo(UpdateStatus status, String version) {
this.status = Objects.requireNonNull(status);
this.version = Objects.requireNonNull(version);
}
}
private static final String urlString = "https://raw.githubusercontent.com/Guild-Hall/MHFC/master/build.properties";
private static Future<UpdateInfo> updateInfo;
static {
RunnableFuture<UpdateInfo> infoGetter = new FutureTask<UpdateInfo>(new Callable<UpdateInfo>() {
@Override
public UpdateInfo call() {
return pollUpdate();
}
});
new Thread(infoGetter, "MHFC Updater").start();
updateInfo = infoGetter;
}
public static void init() {
/* Noop, used as static-init */}
private static UpdateInfo pollUpdate() {
String current = MHFCReference.getMetadata().version;
try (BufferedReader versionFile = new BufferedReader(new InputStreamReader(new URL(urlString).openStream()))) {
String newVersionStr = versionFile.readLine();
Matcher match = Pattern.compile("version\\s*=\\s*\\\"(.*?)\\\"").matcher(newVersionStr);
if (!match.matches())
return new UpdateInfo(UpdateStatus.FAILED, newVersionStr);
newVersionStr = match.group(1);
if (!current.equals(newVersionStr)) {
return new UpdateInfo(UpdateStatus.NEWUPDATE, newVersionStr);
}
return new UpdateInfo(UpdateStatus.NOUPDATE, current);
}
catch (IOException e) {
return new UpdateInfo(UpdateStatus.OFFLINE, current);
}
}
/**
* Gets or waits for the UpdateInfo that is available.
*
* @return infos about possibly available updates.
*/
public static UpdateInfo getUpdateInfo() {
try {
return updateInfo.get();
}
catch (InterruptedException e) {
return new UpdateInfo(UpdateStatus.FAILED, "UNKNOWN"); // Not likely
}
catch (ExecutionException e) {
return new UpdateInfo(UpdateStatus.FAILED, "UNKNOWN"); // impossible
}
}
public static void onServerStart(FMLServerStartedEvent sse) {
if (sse.getSide().isServer()) {
sendUpdateAsync(MinecraftServer.getServer());
}
}
public static void sendUpdateAsync(final ICommandSender finalConsole) {
new Thread(new Runnable() {
@Override
public void run() {
UpdateInfo info = UpdateSystem.getUpdateInfo(); // Blocks
notifyOfUpdate(finalConsole, info);
}
}, "MHFC Update Notifier").start();
}
private static void notifyOfUpdate(ICommandSender console, UpdateInfo info) {
switch (info.status) {
case NEWUPDATE:
console.addChatMessage(
new ChatComponentText(
ColorSystem.ENUMGOLD + "Hunter " + console.getCommandSenderName() + ", a new version ("
+ info.version + ") of Monster Hunter Frontier Craft is out!"
+ " Check out the facebook page or the mod thread."));
break;
case NOUPDATE:
console.addChatMessage(
new ChatComponentText(
ColorSystem.ENUMGOLD + "Welcome Hunter " + console.getCommandSenderName()
+ ", you're up to date, have fun hunting !!"));
break;
case OFFLINE:
console.addChatMessage(
new ChatComponentText(
ColorSystem.ENUMGOLD + "Hunter " + console.getCommandSenderName()
+ ", unable to check for updates automatically"));
console.addChatMessage(
new ChatComponentText(
"Make sure you frequently stop by on our facebook site or Minecraft forum thread!!"));
break;
default: // Should not happen?
console.addChatMessage(
new ChatComponentText(
ColorSystem.ENUMGOLD + "MHFC: There is no current Update System Atm please wait for the patch.."
+ " Version Info: " + info.version));
}
}
}