refactor: migrate to Stonecutter for multi-version management

Replace 20 separate mc-* submodules and common module with a single
Stonecutter-managed source tree using preprocessor comments. This
eliminates massive code duplication while preserving all version-specific
behavior across 1.19.4 through 1.21.11.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
This commit is contained in:
AlexProgrammerDE
2026-03-01 10:06:02 +01:00
co-authored by Claude Opus 4.6
parent d2676ac1d2
commit 0a3b019962
190 changed files with 261 additions and 4513 deletions
@@ -0,0 +1,29 @@
package net.blockhost.anarchymod;
//? if <1.20.5 {
/*import io.netty.buffer.Unpooled;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.minecraft.network.FriendlyByteBuf;
*///?} else {
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
//?}
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
public class AnarchyMod implements ClientModInitializer {
@Override
public void onInitializeClient() {
//? if >=1.20.5 {
PayloadTypeRegistry.playC2S().register(JoinPayload.TYPE, JoinPayload.CODEC);
//?}
ClientPlayConnectionEvents.JOIN.register((listener, sender, client) -> {
if (client.getCurrentServer() != null && Domains.contains(client.getCurrentServer().ip))
//? if <1.20.5 {
/*ClientPlayNetworking.send(JoinPayload.ID, new FriendlyByteBuf(Unpooled.buffer()));
*///?} else {
sender.sendPacket(new JoinPayload());
//?}
});
}
}
@@ -0,0 +1,88 @@
package net.blockhost.anarchymod;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.logging.Logger;
public class Domains {
private static final Logger LOGGER = Logger.getLogger("AnarchyMod-Domains");
private static final String DOMAINS_URL = "https://www.6b6t.org/api/anarchy-mod.json";
private static final Set<String> DEFAULT = Set.of(
"*.6b6t.org", "*.10b10t.org", "*.6b6t.cc", "*.6b6t.me",
"*.7b7t.me", "*.8b8t.org", "*.alacity.net",
"*.anarchypvp.pw", "*.l2x9.org", "*.simpleanarchy.org"
);
private static final Set<String> domains = new HashSet<>();
private static final Gson gson = new Gson();
static {
DEFAULT.forEach(d -> domains.add(d.toLowerCase(Locale.ROOT)));
loadRemote();
}
private static void loadRemote() {
try {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(DOMAINS_URL))
.timeout(Duration.ofSeconds(15))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonObject json = gson.fromJson(response.body(), JsonObject.class);
JsonArray array = json.getAsJsonArray("domains");
if (array == null) return;
array.forEach(element ->
domains.add(element.getAsString().toLowerCase(Locale.ROOT))
);
} catch (Throwable t) {
LOGGER.warning("Failed to load domains from remote, using defaults: " + t.getMessage());
}
}
public static boolean contains(String input) {
if (input == null) return false;
String domain = input.toLowerCase(Locale.ROOT);
if (domain.startsWith("*.")) {
domain = domain.substring(2);
}
int semiColon = domain.indexOf(':');
if (semiColon != -1) {
domain = domain.substring(0, semiColon);
}
for (String entry : domains) {
if (entry.startsWith("*.")) {
String base = entry.substring(2);
if (domain.equals(base) || domain.endsWith("." + base)) {
return true;
}
} else {
if (domain.equals(entry)) {
return true;
}
}
}
return false;
}
}
@@ -0,0 +1,45 @@
package net.blockhost.anarchymod;
//? if <1.20.5 {
/*import net.minecraft.resources.ResourceLocation;
public class JoinPayload {
public static final ResourceLocation ID = new ResourceLocation("anarchymod", "join");
}
*///?} else {
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
//? if >=1.21.11 {
import net.minecraft.resources.Identifier;
//? } else {
/*import net.minecraft.resources.ResourceLocation;
*///?}
public class JoinPayload implements CustomPacketPayload {
//? if >=1.21.11 {
public static final Identifier ID = Identifier.fromNamespaceAndPath("anarchymod", "join");
//? } elif >=1.21.7 {
/*public static final ResourceLocation ID = ResourceLocation.fromNamespaceAndPath("anarchymod", "join");
*///?} else {
/*public static final ResourceLocation ID = ResourceLocation.tryBuild("anarchymod", "join");
*///?}
public static final StreamCodec<FriendlyByteBuf, JoinPayload> CODEC =
StreamCodec.of(
(payload, buf) -> {
},
buf -> new JoinPayload()
);
public static final Type<JoinPayload> TYPE =
new Type<>(ID);
@Override
public Type<? extends CustomPacketPayload> type() {
return TYPE;
}
}
//?}
@@ -0,0 +1,20 @@
package net.blockhost.anarchymod.mixin;
import com.mojang.patchy.BlockedServers;
import net.blockhost.anarchymod.Domains;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(BlockedServers.class)
public class BlockedServersMixin {
@Inject(method = "isBlockedServerHostName", at = @At("RETURN"), cancellable = true, remap = false)
public void isBlockedServerHostName(String server, CallbackInfoReturnable<Boolean> cir) {
boolean contains = Domains.contains(server);
if (contains) {
cir.setReturnValue(false);
}
}
}
@@ -0,0 +1,34 @@
package net.blockhost.anarchymod.mixin;
import net.blockhost.anarchymod.Domains;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.client.multiplayer.ServerList;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.List;
@Mixin(ServerList.class)
public class ServerListMixin {
@Shadow
@Final
private List<ServerData> serverList;
@Inject(method = "load", at = @At("RETURN"))
public void afterLoad(CallbackInfo ci) {
if (serverList.stream().noneMatch(data -> Domains.contains(data.ip))) {
//? if <1.20.2 {
/*serverList.add(0, new ServerData("6b6t", "6b6t.org", false));
*///? } elif <1.20.5 {
/*serverList.add(0, new ServerData("6b6t", "6b6t.org", ServerData.Type.OTHER));
*///?} else {
serverList.addFirst(new ServerData("6b6t", "6b6t.org", ServerData.Type.OTHER));
//?}
}
}
}