Skip to content

Commit

Permalink
Add status checker
Browse files Browse the repository at this point in the history
  • Loading branch information
adam committed Mar 21, 2024
1 parent 3d2d6b5 commit 96dc726
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 4 deletions.
7 changes: 7 additions & 0 deletions common/src/main/java/com/adamcalculator/dynamicpack/Mod.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@
import java.util.Set;

public class Mod {
public static final String VERSION_NAME_MOD = "1.0.13";
public static final String VERSION_NAME_BRANCH = "mc1.20.1";
public static final String VERSION_NAME = VERSION_NAME_MOD + "-" + VERSION_NAME_BRANCH;
public static final long VERSION_BUILD = 14;


// NOTE: for increase contact to mod developer.
public static final long DYNAMIC_PACK_HTTPS_FILE_SIZE_LIMIT = megabyte(8); // kb -> mb -> 5MB (for files in resourcepack)
public static final long MODRINTH_HTTPS_FILE_SIZE_LIMIT = megabyte(1024); // 1 GB (for .zip files from modrinth)
public static final long MOD_MODTINTH_API_LIMIT = megabyte(8); // 8 MB of api
public static final long GZIP_LIMIT = megabyte(50); // 50 MB of .gz file
public static final long MOD_FILES_LIMIT = megabyte(8);
public static final String MODRINTH_URL = "https://modrinth.com/mod/dynamicpack";

private static final Set<String> ALLOWED_HOSTS = new HashSet<>();
static {
Expand Down
17 changes: 17 additions & 0 deletions common/src/main/java/com/adamcalculator/dynamicpack/pack/Pack.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.adamcalculator.dynamicpack.DynamicPackModBase;
import com.adamcalculator.dynamicpack.PackUtil;
import com.adamcalculator.dynamicpack.status.StatusChecker;
import com.adamcalculator.dynamicpack.sync.PackSyncProgress;
import com.adamcalculator.dynamicpack.util.AFiles;
import com.adamcalculator.dynamicpack.util.Out;
Expand Down Expand Up @@ -50,6 +51,12 @@ public boolean isSyncing() {
return isSyncing;
}

// See StatusChecker for this.
// Developer can block network for specify version in dynamicpack.status.v1.json by security questions
public boolean isNetworkBlocked() {
return StatusChecker.isBlockUpdating(remoteTypeStr);
}

public boolean isZip() {
if (location.isDirectory()) {
return false;
Expand Down Expand Up @@ -84,6 +91,7 @@ public long getLatestUpdated() {
}

public boolean checkIsUpdateAvailable() throws IOException {
checkNetwork();
return cachedUpdateAvailable = remote.checkUpdateAvailable();
}

Expand All @@ -108,6 +116,9 @@ private void sync0(PackSyncProgress progress, boolean manually) throws Exception
progress.done(false);
return;
}

checkNetwork();

if (!checkIsUpdateAvailable() && !manually) {
progress.textLog("update not available");
progress.done(false);
Expand All @@ -124,6 +135,12 @@ private void sync0(PackSyncProgress progress, boolean manually) throws Exception
progress.done(reloadRequired);
}

private void checkNetwork() {
if (isNetworkBlocked()) {
throw new SecurityException("Network is blocked for remote_type: " + remoteTypeStr + " in dynamicpack.status.v1.json by security questions!");
}
}

private void checkSafePackMinecraftMeta() throws IOException {
PackUtil.openPackFileSystem(location, path -> {
Path mcmeta = path.resolve(DynamicPackModBase.MINECRAFT_META);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.adamcalculator.dynamicpack.status;

import com.adamcalculator.dynamicpack.Mod;
import com.adamcalculator.dynamicpack.util.Out;
import com.adamcalculator.dynamicpack.util.Urls;
import org.json.JSONObject;

public class StatusChecker {
private static final String URL = "https://adamcalculator.github.io/DynamicPack/dynamicpack.status.v1.json";


private static boolean isUpdateAvailable = false;
private static boolean isFormatActual = true;
private static boolean isSafe = true;
private static boolean isChecked = false;

public static void check() throws Exception {
Out.println("Checking status...");
String s = Urls.parseContent(URL, 1024 * 1024 * 128);
JSONObject j = new JSONObject(s);
JSONObject lat = j.getJSONObject("latest_version");
isUpdateAvailable = lat.getLong("build") > Mod.VERSION_BUILD;
isSafe = lat.getLong("safe") <= Mod.VERSION_BUILD;
isFormatActual = lat.getLong("format") <= Mod.VERSION_BUILD;

isChecked = true;
Out.println(String.format("Status checked! isSafe=%s, isFormatActual=%s, isUpdateAvailable=%s", isSafe, isFormatActual, isUpdateAvailable));
}

public static boolean isBlockUpdating(String remoteType) {
if (remoteType.equals("modrinth")) {
return false;
}
return !isSafe();
}


public static boolean isModUpdateAvailable() {
return isUpdateAvailable;
}

public static boolean isSafe() {
return isSafe;
}

public static boolean isFormatActual() {
return isFormatActual;
}

public static boolean isChecked() {
return isChecked;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.adamcalculator.dynamicpack.sync;

import com.adamcalculator.dynamicpack.status.StatusChecker;
import com.adamcalculator.dynamicpack.util.Out;

import java.util.function.Supplier;

public class SyncThread extends Thread {
Expand All @@ -10,6 +13,9 @@ public class SyncThread extends Thread {

public SyncThread(Supplier<SyncingTask> taskSupplier) {
super("SyncThread" + (counter++));
if (counter > 1) {
Out.warn("Multiple SyncThread's is bad behavior...");
}
this.taskSupplier = taskSupplier;
}

Expand All @@ -27,6 +33,11 @@ public void run() {


private void startSync() {
try {
StatusChecker.check();
} catch (Exception e) {
Out.error("Error while check status!", e);
}
taskSupplier.get().run();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public static void println(Object o) {
System.out.println(o);
return;
}
LOGGER.warn(o + "");
LOGGER.info(o + "");
}

public static void error(String s, Exception e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
package com.adamcalculator.dynamicpack;

import com.adamcalculator.dynamicpack.pack.Pack;
import com.adamcalculator.dynamicpack.status.StatusChecker;
import com.adamcalculator.dynamicpack.sync.SyncThread;
import com.adamcalculator.dynamicpack.sync.SyncingTask;
import com.adamcalculator.dynamicpack.sync.state.StateDownloading;
import com.adamcalculator.dynamicpack.sync.state.StateFileDeleted;
import com.adamcalculator.dynamicpack.sync.state.SyncProgressState;
import com.adamcalculator.dynamicpack.util.Out;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.SharedConstants;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.toast.SystemToast;
import net.minecraft.client.toast.ToastManager;
import net.minecraft.resource.metadata.PackResourceMetadataReader;
import net.minecraft.text.ClickEvent;
import net.minecraft.text.HoverEvent;
import net.minecraft.text.Style;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.JsonHelper;

public class FabricDynamicMod extends DynamicPackModBase implements ClientModInitializer {
private static final boolean SHOW_STATE = false;
private SystemToast toast = null;
private long toastUpdated = 0;

Expand All @@ -40,6 +47,37 @@ public void setToastContent(Text title, Text text) {
public void onInitializeClient() {
var gameDir = FabricLoader.getInstance().getGameDir().toFile();
init(gameDir);

ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> {
ClientPlayerEntity player = client.player;
Text download = Text.translatable("dynamicpack.status_checker.download")
.fillStyle(Style.EMPTY
.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.translatable("dynamicpack.status_checker.download.hover", Text.literal(Mod.MODRINTH_URL).formatted(Formatting.UNDERLINE, Formatting.AQUA))))
.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, Mod.MODRINTH_URL))
)
.formatted(Formatting.YELLOW, Formatting.UNDERLINE);


if (player == null) {
Out.warn("player == null on world join");

} else if (!StatusChecker.isSafe()) {
player.sendMessage(Text.translatable("dynamicpack.status_checker.not_safe", download));
setToastContent(Text.translatable("dynamicpack.status_checker.not_safe.toast.title"),
Text.translatable("dynamicpack.status_checker.not_safe.toast.description"));

} else if (!StatusChecker.isFormatActual()) {
player.sendMessage(Text.translatable("dynamicpack.status_checker.format_not_actual", download));

} else if (StatusChecker.isModUpdateAvailable()) {
Out.println("DynamicPack mod update available: " + Mod.MODRINTH_URL);

} else if (!StatusChecker.isChecked()) {
Out.warn("StatusChecker isChecked = false :(");
} else {
Out.println("Mod in actual state in current date!");
}
});
}

@Override
Expand Down
8 changes: 7 additions & 1 deletion src/main/resources/assets/dynamicpack/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,11 @@
"dynamicpack.toast.pack.state.unknown.description": "Processing...",
"dynamicpack.screen.pack.description": "This resource pack support DynamicPack features!",
"dynamicpack.screen.pack.remote_type": "Remote type: %s",
"dynamicpack.screen.pack.latestUpdated": "Latest updated at: %s"
"dynamicpack.screen.pack.latestUpdated": "Latest updated at: %s",
"dynamicpack.status_checker.not_safe": "Security update available for DynamicPack mod! This message should not be ignored, since the update has fixed possible vulnerabilities: %s",
"dynamicpack.status_checker.not_safe.toast.title": "DynamicPack",
"dynamicpack.status_checker.not_safe.toast.description": "Security update available",
"dynamicpack.status_checker.format_not_actual": "Dynamic pack format update available! Perhaps resource pack developers will use it, and then without updating the mod they will stop working: %s",
"dynamicpack.status_checker.download": "Download!",
"dynamicpack.status_checker.download.hover": "Click for go to %s"
}
8 changes: 7 additions & 1 deletion src/main/resources/assets/dynamicpack/lang/ru_ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,11 @@
"dynamicpack.toast.pack.state.unknown.description": "Обработка...",
"dynamicpack.screen.pack.description": "Этот ресурспак поддерживает возможности мода DynamicPack!",
"dynamicpack.screen.pack.remote_type": "Тип: %s",
"dynamicpack.screen.pack.latestUpdated": "Обновлён: %s"
"dynamicpack.screen.pack.latestUpdated": "Обновлён: %s",
"dynamicpack.status_checker.not_safe": "Доступно обновление безопасности для мода DynamicPack! Это сообщение не стоит игнорировать, поскольку в обновлении были исправлены возможные уязвимости: %s",
"dynamicpack.status_checker.not_safe.toast.title": "DynamicPack",
"dynamicpack.status_checker.not_safe.toast.description": "Доступно обновление безопасности",
"dynamicpack.status_checker.format_not_actual": "Доступно обновление формата динамических паков! Возможно разработчики ресурспаков будут его использовать, и тогда без обновления мода они работать перестанут: %s",
"dynamicpack.status_checker.download": "Загрузить!",
"dynamicpack.status_checker.download.hover": "Нажмите чтобы перейти %s"
}

0 comments on commit 96dc726

Please sign in to comment.