<commit_before>package codechicken.lib.model.loader.blockstate;

import codechicken.lib.util.ArrayUtils;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.gson.*;
import com.google.gson.stream.JsonReader;
import net.minecraft.client.renderer.block.model.ModelBlockDefinition;
import net.minecraft.client.renderer.block.model.ModelRotation;
import net.minecraft.client.renderer.block.model.Variant;
import net.minecraft.client.renderer.block.model.VariantList;
import net.minecraft.util.JsonUtils;
import net.minecraftforge.client.model.BlockStateLoader;
import net.minecraftforge.common.model.TRSRTransformation;
import org.apache.commons.io.IOUtils;

import java.io.Reader;
import java.io.StringReader;
import java.util.*;
import java.util.Map.Entry;

/**
 * Created by covers1624 on 17/11/2016.
 * TODO, ASM copy instructions from ModelBlockDefinition to bouncer method here, in case someone is doing the same thing as me.
 * TODO, Vanilla Predicate support inside json. Maybe allow variants inside predicates??
 * TODO, Allow all unhandled BlockState Json data to be passed to custom IModels.
 * TODO, Allow automatic assigning of IItemRenderer callbacks from json.
 * TODO, Allow the BlockBakery to assign blocks models from json.
 * TODO, Custom Sided particle system from json maybe / support for sided particles loaded from this loader.
 */
public class CCBlockStateLoader {

    public static final Gson GSON = new GsonBuilder().registerTypeAdapter(CCVariant.class, new CCVariant.Deserializer()).create();

    public static ModelBlockDefinition handleLoad(Reader reader, Gson vanillaGSON) {
        try {
            String json = IOUtils.toString(reader);
            ModelBlockDefinition cclDef = load(json);
            if (cclDef != null) {
                return cclDef;
            }
            return BlockStateLoader.load(new StringReader(json), vanillaGSON);
        } catch (Exception e) {
            Throwables.propagate(e);
        }
        return null;
    }

    public static ModelBlockDefinition load(String json) {
        try {
            JsonParser parser = new JsonParser();
            JsonReader reader = new JsonReader(new StringReader(json));
            reader.setLenient(true);
            JsonObject object = parser.parse(reader).getAsJsonObject();
            if (JsonUtils.hasField(object, "ccl_marker")) {

                String marker = JsonUtils.getString(object, "ccl_marker");
                List<String> variantSets = new ArrayList<>();
                for (JsonElement element : object.getAsJsonArray("variant_sets")) {
                    variantSets.add(element.getAsString());
                }

                String textureDomain = "";
                if (object.has("texture_domain")) {
                    textureDomain = object.get("texture_domain").getAsString();
                }

                CCVariant defaultVariant = null;
                if (object.has("defaults")) {
                    defaultVariant = GSON.fromJson(object.get("defaults"), CCVariant.class);
                }
                Map<String, Map<String, CCVariant>> variants = parseVariants(object.getAsJsonObject("variants"));

                Map<String, Map<String, Map<String, CCVariant>>> subModels = parseSubModels(object.getAsJsonObject("sub_model"));

                Map<String, CCVariant> compiledVariants = new LinkedHashMap<>();
                Map<String, Map<String, CCVariant>> compiledSubModelVariants = new LinkedHashMap<>();

                List<String> possibleCombos = new ArrayList<>();

                for (String variantSet : variantSets) {
                    Map<String, List<String>> variantValueMap = generateVariantValueMap(Arrays.asList(variantSet.split(",")), variants, subModels);
                    possibleCombos.addAll(generatePossibleCombos(variantValueMap));
                }

                for (String var : possibleCombos) {
                    Map<String, String> kvArray = ArrayUtils.convertKeyValueArrayToMap(var.split(","));
                    CCVariant finalVariant = new CCVariant();
                    if (defaultVariant != null) {
                        finalVariant = defaultVariant.copy();
                    }
                    compiledVariants.put(var, compileVariant(finalVariant.copy(), kvArray, variants));

                }
                for (Entry<String, Map<String, Map<String, CCVariant>>> subModelVariantEntry : subModels.entrySet()) {
                    Map<String, CCVariant> compiledVariants2 = new LinkedHashMap<>();
                    for (String var : possibleCombos) {
                        Map<String, String> kvArray = ArrayUtils.convertKeyValueArrayToMap(var.split(","));
                        CCVariant finalVariant = new CCVariant();
                        if (defaultVariant != null) {
                            finalVariant = defaultVariant.copy();
                        }
                        compiledVariants2.put(var, compileVariant(finalVariant.copy(), kvArray, subModelVariantEntry.getValue()));
                    }
                    compiledSubModelVariants.put(subModelVariantEntry.getKey(), compiledVariants2);
                }

                Map<String, VariantList> variantList = new HashMap<>();
                for (Entry<String, CCVariant> entry : compiledVariants.entrySet()) {
                    Map<String, CCVariant> subModelVariants = getSubModelsForKey(entry.getKey(), compiledSubModelVariants);
                    List<Variant> vars = new ArrayList<>();
                    CCVariant variant = entry.getValue();

                    boolean uvLock = variant.uvLock.or(false);
                    boolean smooth = variant.smooth.or(true);
                    boolean gui3d = variant.gui3d.or(true);
                    int weight = variant.weight.or(1);

                    if (variant.model != null && subModelVariants.size() == 0 && variant.textures.size() == 0 && variant.customData.size() == 0 && variant.state.orNull() instanceof ModelRotation) {
                        vars.add(new Variant(variant.model, ((ModelRotation) variant.state.get()), uvLock, weight));
                    } else if (subModelVariants.size() == 0) {
                        vars.add(new CCFinalVariant(variant.model, variant.state.or(TRSRTransformation.identity()), uvLock, smooth, gui3d, weight, variant.textures, textureDomain, variant.customData));
                    } else {
                        vars.add(new CCFinalMultiVariant(variant, textureDomain, subModelVariants));
                    }
                    variantList.put(entry.getKey(), new VariantList(vars));
                }
                return new ModelBlockDefinition(variantList, null);

            }
        } catch (Exception e) {
            e.printStackTrace();
            Throwables.propagate(e);
        }
        return null;
    }

    public static Map<String, Map<String, CCVariant>> parseVariants(JsonObject variantElement) {
        Map<String, Map<String, CCVariant>> variants = new LinkedHashMap<>();
        for (Entry<String, JsonElement> variantsEntry : variantElement.entrySet()) {
            String variantName = variantsEntry.getKey();
            Map<String, CCVariant> variantValues = variants.computeIfAbsent(variantName, k -> new LinkedHashMap<>());
            for (Entry<String, JsonElement> variantEntry : variantsEntry.getValue().getAsJsonObject().entrySet()) {
                String variantValue = variantEntry.getKey();
                CCVariant variant = GSON.fromJson(variantEntry.getValue(), CCVariant.class);
                variantValues.put(variantValue, variant);
            }
        }
        return variants;
    }
<commit_msg>Fixl CCL throwing useless blockstate errors in the console..<commit_after>package codechicken.lib.model.loader.blockstate;

import codechicken.lib.util.ArrayUtils;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.gson.*;
import com.google.gson.stream.JsonReader;
import net.minecraft.client.renderer.block.model.ModelBlockDefinition;
import net.minecraft.client.renderer.block.model.ModelRotation;
import net.minecraft.client.renderer.block.model.Variant;
import net.minecraft.client.renderer.block.model.VariantList;
import net.minecraft.util.JsonUtils;
import net.minecraftforge.client.model.BlockStateLoader;
import net.minecraftforge.common.model.TRSRTransformation;
import org.apache.commons.io.IOUtils;

import java.io.Reader;
import java.io.StringReader;
import java.util.*;
import java.util.Map.Entry;

/**
 * Created by covers1624 on 17/11/2016.
 * TODO, ASM copy instructions from ModelBlockDefinition to bouncer method here, in case someone is doing the same thing as me.
 * TODO, Vanilla Predicate support inside json. Maybe allow variants inside predicates??
 * TODO, Allow all unhandled BlockState Json data to be passed to custom IModels.
 * TODO, Allow automatic assigning of IItemRenderer callbacks from json.
 * TODO, Allow the BlockBakery to assign blocks models from json.
 * TODO, Custom Sided particle system from json maybe / support for sided particles loaded from this loader.
 */
public class CCBlockStateLoader {

    public static final Gson GSON = new GsonBuilder().registerTypeAdapter(CCVariant.class, new CCVariant.Deserializer()).create();

    public static ModelBlockDefinition handleLoad(Reader reader, Gson vanillaGSON) {
        try {
            String json = IOUtils.toString(reader);
            ModelBlockDefinition cclDef = load(json);
            if (cclDef != null) {
                return cclDef;
            }
            return BlockStateLoader.load(new StringReader(json), vanillaGSON);
        } catch (Exception e) {
            Throwables.propagate(e);
        }
        return null;
    }

    public static ModelBlockDefinition load(String json) {
        try {
            JsonParser parser = new JsonParser();
            JsonReader reader = new JsonReader(new StringReader(json));
            reader.setLenient(true);
            JsonObject object = parser.parse(reader).getAsJsonObject();
            if (JsonUtils.hasField(object, "ccl_marker")) {

                String marker = JsonUtils.getString(object, "ccl_marker");
                List<String> variantSets = new ArrayList<>();
                for (JsonElement element : object.getAsJsonArray("variant_sets")) {
                    variantSets.add(element.getAsString());
                }

                String textureDomain = "";
                if (object.has("texture_domain")) {
                    textureDomain = object.get("texture_domain").getAsString();
                }

                CCVariant defaultVariant = null;
                if (object.has("defaults")) {
                    defaultVariant = GSON.fromJson(object.get("defaults"), CCVariant.class);
                }
                Map<String, Map<String, CCVariant>> variants = parseVariants(object.getAsJsonObject("variants"));

                Map<String, Map<String, Map<String, CCVariant>>> subModels = parseSubModels(object.getAsJsonObject("sub_model"));

                Map<String, CCVariant> compiledVariants = new LinkedHashMap<>();
                Map<String, Map<String, CCVariant>> compiledSubModelVariants = new LinkedHashMap<>();

                List<String> possibleCombos = new ArrayList<>();

                for (String variantSet : variantSets) {
                    Map<String, List<String>> variantValueMap = generateVariantValueMap(Arrays.asList(variantSet.split(",")), variants, subModels);
                    possibleCombos.addAll(generatePossibleCombos(variantValueMap));
                }

                for (String var : possibleCombos) {
                    Map<String, String> kvArray = ArrayUtils.convertKeyValueArrayToMap(var.split(","));
                    CCVariant finalVariant = new CCVariant();
                    if (defaultVariant != null) {
                        finalVariant = defaultVariant.copy();
                    }
                    compiledVariants.put(var, compileVariant(finalVariant.copy(), kvArray, variants));

                }
                for (Entry<String, Map<String, Map<String, CCVariant>>> subModelVariantEntry : subModels.entrySet()) {
                    Map<String, CCVariant> compiledVariants2 = new LinkedHashMap<>();
                    for (String var : possibleCombos) {
                        Map<String, String> kvArray = ArrayUtils.convertKeyValueArrayToMap(var.split(","));
                        CCVariant finalVariant = new CCVariant();
                        if (defaultVariant != null) {
                            finalVariant = defaultVariant.copy();
                        }
                        compiledVariants2.put(var, compileVariant(finalVariant.copy(), kvArray, subModelVariantEntry.getValue()));
                    }
                    compiledSubModelVariants.put(subModelVariantEntry.getKey(), compiledVariants2);
                }

                Map<String, VariantList> variantList = new HashMap<>();
                for (Entry<String, CCVariant> entry : compiledVariants.entrySet()) {
                    Map<String, CCVariant> subModelVariants = getSubModelsForKey(entry.getKey(), compiledSubModelVariants);
                    List<Variant> vars = new ArrayList<>();
                    CCVariant variant = entry.getValue();

                    boolean uvLock = variant.uvLock.or(false);
                    boolean smooth = variant.smooth.or(true);
                    boolean gui3d = variant.gui3d.or(true);
                    int weight = variant.weight.or(1);

                    if (variant.model != null && subModelVariants.size() == 0 && variant.textures.size() == 0 && variant.customData.size() == 0 && variant.state.orNull() instanceof ModelRotation) {
                        vars.add(new Variant(variant.model, ((ModelRotation) variant.state.get()), uvLock, weight));
                    } else if (subModelVariants.size() == 0) {
                        vars.add(new CCFinalVariant(variant.model, variant.state.or(TRSRTransformation.identity()), uvLock, smooth, gui3d, weight, variant.textures, textureDomain, variant.customData));
                    } else {
                        vars.add(new CCFinalMultiVariant(variant, textureDomain, subModelVariants));
                    }
                    variantList.put(entry.getKey(), new VariantList(vars));
                }
                return new ModelBlockDefinition(variantList, null);

            }
        } catch (Exception e) {
            Throwables.propagate(e);
        }
        return null;
    }

    public static Map<String, Map<String, CCVariant>> parseVariants(JsonObject variantElement) {
        Map<String, Map<String, CCVariant>> variants = new LinkedHashMap<>();
        for (Entry<String, JsonElement> variantsEntry : variantElement.entrySet()) {
            String variantName = variantsEntry.getKey();
            Map<String, CCVariant> variantValues = variants.computeIfAbsent(variantName, k -> new LinkedHashMap<>());
            for (Entry<String, JsonElement> variantEntry : variantsEntry.getValue().getAsJsonObject().entrySet()) {
                String variantValue = variantEntry.getKey();
                CCVariant variant = GSON.fromJson(variantEntry.getValue(), CCVariant.class);
                variantValues.put(variantValue, variant);
            }
        }
        return variants;
    }

{'fraction_non_alphanumeric': 0.10313265437669202, 'fraction_numerical': 0.0029650638133298956, 'mean_word_length': 2.3488020720915173, 'pattern_counts': {'":': 0, '<': 79, '<?xml version=': 0, '>': 81, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6819133', 'n_tokens_mistral': 3933, 'n_tokens_neox': 3787, 'n_words': 871}