2018-03-25 15:59:43 +00:00
|
|
|
/*
|
|
|
|
* Minecraft Forge
|
|
|
|
* Copyright (c) 2018.
|
|
|
|
*
|
|
|
|
* 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.loading.moddiscovery;
|
|
|
|
|
2018-04-07 15:48:43 +00:00
|
|
|
import net.minecraftforge.fml.loading.IModLanguageProvider;
|
|
|
|
|
|
|
|
import javax.swing.text.html.Option;
|
2018-04-07 22:15:32 +00:00
|
|
|
import java.nio.file.Files;
|
2018-03-25 15:59:43 +00:00
|
|
|
import java.nio.file.Path;
|
|
|
|
import java.util.List;
|
2018-04-07 15:48:43 +00:00
|
|
|
import java.util.Map;
|
2018-03-25 15:59:43 +00:00
|
|
|
import java.util.Objects;
|
2018-04-07 15:48:43 +00:00
|
|
|
import java.util.Optional;
|
2018-03-25 15:59:43 +00:00
|
|
|
import java.util.concurrent.CompletableFuture;
|
|
|
|
import java.util.concurrent.ExecutionException;
|
|
|
|
import java.util.function.Consumer;
|
2018-04-07 15:48:43 +00:00
|
|
|
import java.util.function.Function;
|
2018-03-25 15:59:43 +00:00
|
|
|
import java.util.jar.Attributes;
|
|
|
|
import java.util.jar.Manifest;
|
2018-04-07 15:48:43 +00:00
|
|
|
import java.util.stream.Collectors;
|
2018-03-25 15:59:43 +00:00
|
|
|
|
2018-04-07 03:58:48 +00:00
|
|
|
import static net.minecraftforge.fml.Logging.LOADING;
|
|
|
|
import static net.minecraftforge.fml.Logging.SCAN;
|
2018-03-25 15:59:43 +00:00
|
|
|
import static net.minecraftforge.fml.Logging.fmlLog;
|
|
|
|
|
|
|
|
public class ModFile
|
|
|
|
{
|
|
|
|
private static final Manifest DEFAULTMANIFEST;
|
|
|
|
static {
|
|
|
|
DEFAULTMANIFEST = new Manifest();
|
|
|
|
DEFAULTMANIFEST.getMainAttributes().putValue("FMLModType", "MOD");
|
|
|
|
}
|
|
|
|
|
2018-04-07 22:15:32 +00:00
|
|
|
|
2018-04-07 15:48:43 +00:00
|
|
|
public void claimLanguage(String modId, IModLanguageProvider.IModLanguageLoader loader)
|
|
|
|
{
|
|
|
|
this.modInfoMap.get(modId).setLoader(loader);
|
|
|
|
}
|
|
|
|
|
2018-03-25 15:59:43 +00:00
|
|
|
public enum Type {
|
|
|
|
MOD, LIBRARY, LANGPROVIDER
|
|
|
|
}
|
|
|
|
private final Path filePath;
|
|
|
|
private final Type modFileType;
|
|
|
|
private final Manifest manifest;
|
|
|
|
private List<ModInfo> modInfos;
|
2018-04-07 15:48:43 +00:00
|
|
|
private Map<String, ModInfo> modInfoMap;
|
2018-03-25 15:59:43 +00:00
|
|
|
private final IModLocator locator;
|
|
|
|
private ScanResult fileScanResult;
|
|
|
|
private CompletableFuture<ScanResult> futureScanResult;
|
|
|
|
private List<CoreModFile> coreMods;
|
2018-04-07 22:15:32 +00:00
|
|
|
private Path accessTransformer;
|
2018-03-25 15:59:43 +00:00
|
|
|
|
|
|
|
private static final Attributes.Name TYPE = new Attributes.Name("FMLModType");
|
|
|
|
|
|
|
|
public ModFile(final Path file, final IModLocator locator) {
|
|
|
|
this.locator = locator;
|
|
|
|
this.filePath = file;
|
|
|
|
manifest = locator.findManifest(file).orElse(DEFAULTMANIFEST);
|
2018-04-07 03:58:48 +00:00
|
|
|
if (manifest != DEFAULTMANIFEST) fmlLog.debug(SCAN,"Mod file {} has a manifest", file);
|
|
|
|
else fmlLog.debug(SCAN,"Mod file {} is missing a manifest", file);
|
2018-04-07 15:48:43 +00:00
|
|
|
final Optional<String> value = Optional.ofNullable(manifest.getMainAttributes().getValue(TYPE));
|
|
|
|
modFileType = Type.valueOf(value.orElse("MOD"));
|
2018-03-25 15:59:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public Type getType() {
|
|
|
|
return modFileType;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Path getFilePath() {
|
|
|
|
return filePath;
|
|
|
|
}
|
|
|
|
|
|
|
|
public List<ModInfo> getModInfos() {
|
|
|
|
return modInfos;
|
|
|
|
}
|
|
|
|
|
2018-04-07 22:15:32 +00:00
|
|
|
public Optional<Path> getAccessTransformer() {
|
|
|
|
return Optional.ofNullable(Files.exists(accessTransformer) ? accessTransformer : null);
|
|
|
|
}
|
2018-03-25 15:59:43 +00:00
|
|
|
public void identifyMods() {
|
|
|
|
this.modInfos = ModFileParser.readModList(this);
|
2018-04-07 03:58:48 +00:00
|
|
|
this.modInfos.forEach(mi-> fmlLog.debug(LOADING,"Found mod {} for language {}", mi.getModId(), mi.getModLoader()));
|
2018-04-07 15:48:43 +00:00
|
|
|
this.modInfoMap = this.modInfos.stream().collect(Collectors.toMap(ModInfo::getModId, Function.identity()));
|
2018-03-25 15:59:43 +00:00
|
|
|
this.coreMods = ModFileParser.getCoreMods(this);
|
2018-04-07 03:58:48 +00:00
|
|
|
this.coreMods.forEach(mi-> fmlLog.debug(LOADING,"Found coremod {}", mi.getPath()));
|
2018-04-07 22:15:32 +00:00
|
|
|
this.accessTransformer = locator.findPath(this, "META-INF", "accesstransformer.cfg");
|
2018-03-25 15:59:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public List<CoreModFile> getCoreMods() {
|
|
|
|
return coreMods;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run in an executor thread to harvest the class and annotation list
|
|
|
|
*/
|
|
|
|
public ScanResult compileContent() {
|
|
|
|
return new Scanner(this).scan();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void scanFile(Consumer<Path> pathConsumer) {
|
|
|
|
locator.scanFile(this, pathConsumer);
|
|
|
|
}
|
|
|
|
public void setFutureScanResult(CompletableFuture<ScanResult> future)
|
|
|
|
{
|
|
|
|
this.futureScanResult = future;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ScanResult getScanResult() {
|
|
|
|
if (this.futureScanResult != null) {
|
|
|
|
try {
|
|
|
|
this.futureScanResult.get();
|
|
|
|
} catch (InterruptedException | ExecutionException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return this.fileScanResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setScanResult(final ScanResult scanResult, final Throwable throwable) {
|
|
|
|
this.futureScanResult = null;
|
|
|
|
this.fileScanResult = scanResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return "Mod File: " + Objects.toString(this.filePath);
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getFileName() {
|
|
|
|
return getFilePath().getFileName().toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
public IModLocator getLocator() {
|
|
|
|
return locator;
|
|
|
|
}
|
|
|
|
}
|