Add truncation to FMLStatusPing to work around protocol limits (#7818)

This commit is contained in:
Take Weiland authored and GitHub committed 2021-06-16 19:23:20 -07:00
1 parent 33499db93f
commit 29f175743b
4 files changed
+42 -5

No files matched your search

@@ -128,7 +128,7 @@ public class ClientHooks
if (fmlver > FMLNetworkConstants.FMLNETVERSION) {
extraReason = "fml.menu.multiplayer.clientoutdated";
}
target.forgeData = new ExtendedServerListData("FML", extraServerMods.isEmpty() && fmlNetMatches && channelsMatch && modsMatch, mods.size(), extraReason);
target.forgeData = new ExtendedServerListData("FML", extraServerMods.isEmpty() && fmlNetMatches && channelsMatch && modsMatch, mods.size(), extraReason, packet.getForgeData().isTruncated());
} else {
target.forgeData = new ExtendedServerListData("VANILLA", NetworkRegistry.canConnectToVanillaServer(),0, null);
}
@@ -154,6 +154,10 @@ public class ClientHooks
tooltip = ForgeI18n.parseMessage("fml.menu.multiplayer.incompatible");
}
}
if (target.forgeData.truncated)
{
tooltip += "\n" + ForgeI18n.parseMessage("fml.menu.multiplayer.truncated");
}
break;
case "VANILLA":
if (target.forgeData.isCompatible) {
@@ -24,12 +24,19 @@ public class ExtendedServerListData {
public final boolean isCompatible;
public int numberOfMods;
public String extraReason;
public final boolean truncated;
public ExtendedServerListData(String type, boolean isCompatible, int num, String extraReason)
{
this(type, isCompatible, num, extraReason, false);
}
public ExtendedServerListData(String type, boolean isCompatible, int num, String extraReason, boolean truncated)
{
this.type = type;
this.isCompatible = isCompatible;
this.numberOfMods = num;
this.extraReason = extraReason;
this.truncated = truncated;
}
}
@@ -63,10 +63,15 @@ import static net.minecraftforge.fml.network.FMLNetworkConstants.NETWORK;
*/
public class FMLStatusPing {
private static final Logger LOGGER = LogManager.getLogger();
private static final int CHANNEL_TRUNCATE_LIMIT = 150;
private static final int MOD_TRUNCATE_LIMIT = 150;
private static volatile boolean warnedAboutTruncation = false;
private transient Map<ResourceLocation, Pair<String, Boolean>> channels;
private transient Map<String, String> mods;
private transient int fmlNetworkVer;
private transient boolean truncated;
public FMLStatusPing() {
this.channels = NetworkRegistry.buildChannelVersionsForListPing();
this.mods = new HashMap<>();
@@ -74,12 +79,14 @@ public class FMLStatusPing {
mods.put(modid, mc.getCustomExtension(ExtensionPoint.DISPLAYTEST).
map(Pair::getLeft).map(Supplier::get).orElse(FMLNetworkConstants.IGNORESERVERONLY)));
this.fmlNetworkVer = FMLNetworkConstants.FMLNETVERSION;
this.truncated = false;
}
private FMLStatusPing(Map<ResourceLocation, Pair<String, Boolean>> deserialized, Map<String,String> modMarkers, int fmlNetVer) {
private FMLStatusPing(Map<ResourceLocation, Pair<String, Boolean>> deserialized, Map<String,String> modMarkers, int fmlNetVer, boolean truncated) {
this.channels = ImmutableMap.copyOf(deserialized);
this.mods = modMarkers;
this.fmlNetworkVer = fmlNetVer;
this.truncated = truncated;
}
public static class Serializer {
@@ -96,7 +103,8 @@ public class FMLStatusPing {
collect(Collectors.toMap(jo -> JSONUtils.getAsString(jo, "modId"), jo->JSONUtils.getAsString(jo, "modmarker")));
final int remoteFMLVersion = JSONUtils.getAsInt(forgeData, "fmlNetworkVersion");
return new FMLStatusPing(channels, mods, remoteFMLVersion);
final boolean truncated = JSONUtils.getAsBoolean(forgeData, "truncated", false);
return new FMLStatusPing(channels, mods, remoteFMLVersion, truncated);
} catch (JsonSyntaxException e) {
LOGGER.debug(NETWORK, "Encountered an error parsing status ping data", e);
return null;
@@ -106,7 +114,17 @@ public class FMLStatusPing {
public static JsonObject serialize(FMLStatusPing forgeData, JsonSerializationContext ctx) {
JsonObject obj = new JsonObject();
JsonArray channels = new JsonArray();
forgeData.channels.forEach((namespace, version) -> {
boolean truncated = forgeData.channels.size() > CHANNEL_TRUNCATE_LIMIT || forgeData.mods.size() > MOD_TRUNCATE_LIMIT;
if (truncated && !warnedAboutTruncation)
{
warnedAboutTruncation = true;
LOGGER.warn("Heuristically truncating mod and/or network channel list in server status ping packet. Compatibility report " +
"in the multiplayer screen may be inaccurate.");
}
forgeData.channels.entrySet().stream().limit(CHANNEL_TRUNCATE_LIMIT).forEach(entry -> {
ResourceLocation namespace = entry.getKey();
Pair<String, Boolean> version = entry.getValue();
JsonObject mi = new JsonObject();
mi.addProperty("res", namespace.toString());
mi.addProperty("version", version.getLeft());
@@ -117,7 +135,9 @@ public class FMLStatusPing {
obj.add("channels", channels);
JsonArray modTestValues = new JsonArray();
forgeData.mods.forEach((modId, value) -> {
forgeData.mods.entrySet().stream().limit(MOD_TRUNCATE_LIMIT).forEach(entry -> {
String modId = entry.getKey();
String value = entry.getValue();
JsonObject mi = new JsonObject();
mi.addProperty("modId", modId);
mi.addProperty("modmarker", value);
@@ -125,6 +145,7 @@ public class FMLStatusPing {
});
obj.add("mods", modTestValues);
obj.addProperty("fmlNetworkVersion", forgeData.fmlNetworkVer);
obj.addProperty("truncated", truncated);
return obj;
}
}
@@ -141,4 +162,8 @@ public class FMLStatusPing {
return fmlNetworkVer;
}
public boolean isTruncated()
{
return truncated;
}
}