161 lines
6.1 KiB
Java
161 lines
6.1 KiB
Java
/*
|
|
* Minecraft Forge
|
|
* Copyright (c) 2016-2020.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation version 2.1
|
|
* of the License.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
package net.minecraftforge.fml.network;
|
|
|
|
import com.google.common.collect.ImmutableMap;
|
|
import com.google.gson.JsonArray;
|
|
import com.google.gson.JsonDeserializationContext;
|
|
import com.google.gson.JsonElement;
|
|
import com.google.gson.JsonObject;
|
|
import com.google.gson.JsonSerializationContext;
|
|
import com.google.gson.JsonSyntaxException;
|
|
import net.minecraft.util.JSONUtils;
|
|
import net.minecraft.util.ResourceLocation;
|
|
import net.minecraftforge.fml.ExtensionPoint;
|
|
import net.minecraftforge.fml.ModList;
|
|
import org.apache.commons.lang3.tuple.Pair;
|
|
import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.function.Supplier;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.StreamSupport;
|
|
|
|
import static net.minecraftforge.fml.network.FMLNetworkConstants.NETWORK;
|
|
|
|
/**
|
|
* {
|
|
* "fmlNetworkVersion" : FMLNETVERSION,
|
|
* "channels": [
|
|
* {
|
|
* "res": "fml:handshake",
|
|
* "version": "1.2.3.4",
|
|
* "required": true
|
|
* }
|
|
* ],
|
|
* "mods": [
|
|
* {
|
|
* "modid": "modid",
|
|
* "modmarker": "<somestring>"
|
|
* }
|
|
* ]
|
|
* }
|
|
*
|
|
*/
|
|
public class FMLStatusPing {
|
|
private static final Logger LOGGER = LogManager.getLogger();
|
|
|
|
private transient Map<ResourceLocation, Pair<String, Boolean>> channels;
|
|
private transient Map<String, String> mods;
|
|
private transient int fmlNetworkVer;
|
|
private transient boolean patched;
|
|
public FMLStatusPing() {
|
|
this.channels = NetworkRegistry.buildChannelVersionsForListPing();
|
|
this.mods = new HashMap<>();
|
|
ModList.get().forEachModContainer((modid, mc) ->
|
|
mods.put(modid, mc.getCustomExtension(ExtensionPoint.DISPLAYTEST).
|
|
map(Pair::getLeft).map(Supplier::get).orElse(FMLNetworkConstants.IGNORESERVERONLY)));
|
|
this.fmlNetworkVer = FMLNetworkConstants.FMLNETVERSION;
|
|
this.patched = true;
|
|
}
|
|
|
|
private FMLStatusPing(Map<ResourceLocation, Pair<String, Boolean>> deserialized, Map<String,String> modMarkers, int fmlNetVer) {
|
|
this.channels = ImmutableMap.copyOf(deserialized);
|
|
this.mods = modMarkers;
|
|
this.fmlNetworkVer = fmlNetVer;
|
|
this.patched = false;
|
|
}
|
|
private FMLStatusPing(Map<ResourceLocation, Pair<String, Boolean>> deserialized, Map<String,String> modMarkers, int fmlNetVer, boolean p) {
|
|
this.channels = ImmutableMap.copyOf(deserialized);
|
|
this.mods = modMarkers;
|
|
this.fmlNetworkVer = fmlNetVer;
|
|
this.patched = p;
|
|
}
|
|
|
|
public static class Serializer {
|
|
public static FMLStatusPing deserialize(JsonObject forgeData, JsonDeserializationContext ctx) {
|
|
try {
|
|
final Map<ResourceLocation, Pair<String, Boolean>> channels = StreamSupport.stream(JSONUtils.getJsonArray(forgeData, "channels").spliterator(), false).
|
|
map(JsonElement::getAsJsonObject).
|
|
collect(Collectors.toMap(jo -> new ResourceLocation(JSONUtils.getString(jo, "res")),
|
|
jo -> Pair.of(JSONUtils.getString(jo, "version"), JSONUtils.getBoolean(jo, "required")))
|
|
);
|
|
|
|
final Map<String, String> mods = StreamSupport.stream(JSONUtils.getJsonArray(forgeData, "mods").spliterator(), false).
|
|
map(JsonElement::getAsJsonObject).
|
|
collect(Collectors.toMap(jo -> JSONUtils.getString(jo, "modId"), jo->JSONUtils.getString(jo, "modmarker")));
|
|
|
|
final int remoteFMLVersion = JSONUtils.getInt(forgeData, "fmlNetworkVersion");
|
|
|
|
return new FMLStatusPing(channels, mods, remoteFMLVersion, JSONUtils.hasField(forgeData, "keithPatch"));
|
|
} catch (JsonSyntaxException e) {
|
|
LOGGER.debug(NETWORK, "Encountered an error parsing status ping data", e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static JsonObject serialize(FMLStatusPing forgeData, JsonSerializationContext ctx) {
|
|
JsonObject obj = new JsonObject();
|
|
JsonArray channels = new JsonArray();
|
|
forgeData.channels.forEach((namespace, version) -> {
|
|
JsonObject mi = new JsonObject();
|
|
mi.addProperty("res", namespace.toString());
|
|
mi.addProperty("version", version.getLeft());
|
|
mi.addProperty("required", version.getRight());
|
|
channels.add(mi);
|
|
});
|
|
|
|
obj.add("channels", channels);
|
|
|
|
JsonArray modTestValues = new JsonArray();
|
|
forgeData.mods.forEach((modId, value) -> {
|
|
JsonObject mi = new JsonObject();
|
|
mi.addProperty("modId", modId);
|
|
mi.addProperty("modmarker", value);
|
|
modTestValues.add(mi);
|
|
});
|
|
obj.add("mods", modTestValues);
|
|
obj.addProperty("fmlNetworkVersion", forgeData.fmlNetworkVer);
|
|
if (forgeData.patched)
|
|
obj.addProperty("keithPatch", true);
|
|
return obj;
|
|
}
|
|
}
|
|
|
|
public Map<ResourceLocation, Pair<String, Boolean>> getRemoteChannels() {
|
|
return this.channels;
|
|
}
|
|
|
|
public Map<String,String> getRemoteModData() {
|
|
return mods;
|
|
}
|
|
|
|
public int getFMLNetworkVersion() {
|
|
return fmlNetworkVer;
|
|
}
|
|
|
|
public boolean isPatchAdvertised() {
|
|
return patched;
|
|
}
|
|
|
|
}
|