com.skcraft.launcher.creator.util.ModInfoReader.java Source code

Java tutorial

Introduction

Here is the source code for com.skcraft.launcher.creator.util.ModInfoReader.java

Source

/*
 * SK's Minecraft Launcher
 * Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
 * Please see LICENSE.txt for license information.
 */

package com.skcraft.launcher.creator.util;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
import com.google.common.io.CharStreams;
import com.google.common.io.Closer;
import lombok.Data;
import lombok.extern.java.Log;

import java.io.*;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * Reads the mod information file from a mod .jar, with support for both Forge
 * and LiteLoader.
 */
@Log
public class ModInfoReader {

    private static final String FORGE_INFO_FILENAME = "mcmod.info";
    private static final String LITELOADER_INFO_FILENAME = "litemod.json";
    private final ObjectMapper mapper = new ObjectMapper();

    /**
     * Detect the mods listed in the given .jar
     *
     * @param file The file
     * @return A list of detected mods
     */
    public List<? extends ModInfo> detectMods(File file) {
        Closer closer = Closer.create();

        try {
            FileInputStream fis = closer.register(new FileInputStream(file));
            BufferedInputStream bis = closer.register(new BufferedInputStream(fis));
            ZipInputStream zis = closer.register(new ZipInputStream(bis));

            ZipEntry entry;
            while ((entry = zis.getNextEntry()) != null) {
                if (entry.getName().equalsIgnoreCase(FORGE_INFO_FILENAME)) {
                    List<ForgeModInfo> mods;
                    String content = CharStreams.toString(new InputStreamReader(zis, Charsets.UTF_8));

                    try {
                        mods = mapper.readValue(content, ForgeModManifest.class).getMods();
                    } catch (JsonMappingException | JsonParseException e) {
                        mods = mapper.readValue(content, new TypeReference<List<ForgeModInfo>>() {
                        });
                    }

                    if (mods != null) {
                        // Ignore "examplemod"
                        return Collections.unmodifiableList(
                                mods.stream().filter(info -> !info.getModId().equals("examplemod"))
                                        .collect(Collectors.toList()));
                    } else {
                        return Collections.emptyList();
                    }

                } else if (entry.getName().equalsIgnoreCase(LITELOADER_INFO_FILENAME)) {
                    String content = CharStreams.toString(new InputStreamReader(zis, Charsets.UTF_8));
                    return new ImmutableList.Builder<ModInfo>()
                            .add(mapper.readValue(content, LiteLoaderModInfo.class)).build();
                }
            }

            return Collections.emptyList();
        } catch (JsonMappingException e) {
            log.log(Level.WARNING, "Unknown format " + FORGE_INFO_FILENAME + " file in " + file.getAbsolutePath(),
                    e);
            return Collections.emptyList();
        } catch (JsonParseException e) {
            log.log(Level.WARNING, "Corrupt " + FORGE_INFO_FILENAME + " file in " + file.getAbsolutePath(), e);
            return Collections.emptyList();
        } catch (IOException e) {
            log.log(Level.WARNING, "Failed to read " + file.getAbsolutePath(), e);
            return Collections.emptyList();
        } finally {
            try {
                closer.close();
            } catch (IOException ignored) {
            }
        }
    }

    public interface ModInfo {

        String getModId();

        String getName();

        String getDescription();

        String getVersion();

        String getGameVersion();

        String getUrl();

    }

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    private static class ForgeModInfo implements ModInfo {

        @JsonProperty("modid")
        private String modId;
        private String name;
        private String description;
        private String version;
        @JsonProperty("mcversion")
        private String gameVersion;
        private String url;
        private String updateUrl;
        private List<String> authorList;
        private String credits;
        private List<String> dependencies;

    }

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    private static class ForgeModManifest {

        @JsonProperty("modListVersion")
        private int version;
        @JsonProperty("modList")
        private List<ForgeModInfo> mods;

    }

    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    private static class LiteLoaderModInfo implements ModInfo {

        private String name;
        private String version;
        @JsonProperty("mcversion")
        private String gameVersion;
        private String revision;
        private String author;
        private String description;

        @JsonIgnore
        @Override
        public String getModId() {
            return null;
        }

        @Override
        public String getUrl() {
            return null;
        }

    }

}