Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
f756673128
16 changed files with 230 additions and 96 deletions
|
@ -8,13 +8,13 @@ loom_version=0.10-SNAPSHOT
|
|||
# check these on https://fabricmc.net/versions.html
|
||||
minecraft_version= 1.18.1
|
||||
loader_version= 0.12.12
|
||||
fabric_version = 0.44.0+1.18
|
||||
fabric_version = 0.46.2+1.18
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 1.3.0
|
||||
mod_version = 1.3.1
|
||||
maven_group = ru.bclib
|
||||
archives_base_name = bclib
|
||||
|
||||
# Dependencies
|
||||
patchouli_version = 50-FABRIC
|
||||
modmenu_version=3.0.0
|
||||
modmenu_version=3.0.1
|
|
@ -17,6 +17,7 @@ import ru.bclib.recipes.CraftingRecipes;
|
|||
import ru.bclib.registry.BaseBlockEntities;
|
||||
import ru.bclib.registry.BaseRegistry;
|
||||
import ru.bclib.util.Logger;
|
||||
import ru.bclib.util.ModUtil;
|
||||
import ru.bclib.world.generator.BCLibEndBiomeSource;
|
||||
import ru.bclib.world.generator.BCLibNetherBiomeSource;
|
||||
import ru.bclib.world.generator.GeneratorOptions;
|
||||
|
|
|
@ -2,7 +2,7 @@ package ru.bclib.api;
|
|||
|
||||
import com.google.common.collect.Lists;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import ru.bclib.integration.modmenu.ModIntegration;
|
||||
import ru.bclib.integration.ModIntegration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
|
@ -501,8 +501,11 @@ public class BiomeAPI {
|
|||
.worldGenSettings()
|
||||
.dimensions()
|
||||
.stream()
|
||||
.filter(dim->dim.generator().getSettings()==settings)
|
||||
.map(dim->((NoiseGeneratorSettingsProvider)dim.generator()).bclib_getNoiseGeneratorSettings()).findFirst().orElse(null);;
|
||||
.map(dim->dim.generator())
|
||||
.filter(gen->(gen instanceof NoiseGeneratorSettingsProvider) && gen.getSettings()==settings)
|
||||
.map(gen->((NoiseGeneratorSettingsProvider)gen).bclib_getNoiseGeneratorSettings())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
// Datapacks (like Amplified Nether)will change the GeneratorSettings upon load, so we will
|
||||
// only use the default Setting for Nether/End if we were unable to find a settings object
|
||||
|
@ -515,14 +518,11 @@ public class BiomeAPI {
|
|||
}
|
||||
|
||||
List<BiConsumer<ResourceLocation, Biome>> modifications = MODIFICATIONS.get(level.dimension());
|
||||
if (modifications == null) {
|
||||
biomes.forEach(biome -> sortBiomeFeatures(biome));
|
||||
} else {
|
||||
biomes.forEach(biome -> {
|
||||
applyModificationsToBiome(modifications, biome);
|
||||
});
|
||||
for (Biome biome : biomes) {
|
||||
applyModificationsAndUpdateFeatures(modifications, biome);
|
||||
}
|
||||
|
||||
|
||||
if (generator != null) {
|
||||
final SurfaceRuleProvider provider = SurfaceRuleProvider.class.cast(generator);
|
||||
// Multiple Biomes can use the same generator. So we need to keep track of all Biomes that are
|
||||
|
@ -548,11 +548,13 @@ public class BiomeAPI {
|
|||
((BiomeSourceAccessor) source).bclRebuildFeatures();
|
||||
}
|
||||
|
||||
private static void applyModificationsToBiome(List<BiConsumer<ResourceLocation, Biome>> modifications, Biome biome) {
|
||||
private static void applyModificationsAndUpdateFeatures(List<BiConsumer<ResourceLocation, Biome>> modifications, Biome biome) {
|
||||
ResourceLocation biomeID = getBiomeID(biome);
|
||||
if (modifications!=null) {
|
||||
modifications.forEach(consumer -> {
|
||||
consumer.accept(biomeID, biome);
|
||||
});
|
||||
}
|
||||
|
||||
final BCLBiome bclBiome = BiomeAPI.getBiome(biome);
|
||||
if (bclBiome != null) {
|
||||
|
@ -658,7 +660,7 @@ public class BiomeAPI {
|
|||
/**
|
||||
* For internal use only!
|
||||
*
|
||||
* Adds new features to existing biome. Called from {@link #applyModificationsToBiome(List, Biome)} when the Biome is
|
||||
* Adds new features to existing biome. Called from {@link #applyModificationsAndUpdateFeatures(List, Biome)} when the Biome is
|
||||
* present in any {@link BiomeSource}
|
||||
* @param biome {@link Biome} to add features in.
|
||||
* @param featureMap Map of {@link ConfiguredFeature} to add.
|
||||
|
|
|
@ -177,8 +177,6 @@ public class HelloClient extends DataHandler.FromServer {
|
|||
protected void deserializeIncomingDataOnClient(FriendlyByteBuf buf, PacketSender responseSender) {
|
||||
//read BCLibVersion (=protocol version)
|
||||
bclibVersion = ModUtil.convertModVersion(buf.readInt());
|
||||
final boolean protocolVersion_0_4_1 = ModUtil.isLargerOrEqualVersion(bclibVersion, "0.4.1");
|
||||
|
||||
|
||||
//read Plugin Versions
|
||||
modVersion = new ServerModMap();
|
||||
|
@ -189,14 +187,8 @@ public class HelloClient extends DataHandler.FromServer {
|
|||
final int size;
|
||||
final boolean canDownload;
|
||||
//since v0.4.1 we also send the size of the mod-File
|
||||
if (protocolVersion_0_4_1) {
|
||||
size = buf.readInt();
|
||||
canDownload = buf.readBoolean();
|
||||
}
|
||||
else {
|
||||
size = 0;
|
||||
canDownload = true;
|
||||
}
|
||||
modVersion.put(id, new OfferedModInfo(version, size, canDownload));
|
||||
}
|
||||
|
||||
|
@ -213,7 +205,6 @@ public class HelloClient extends DataHandler.FromServer {
|
|||
|
||||
autoSynFolders = new ArrayList<>(1);
|
||||
//since v0.4.1 we also send the sync folders
|
||||
if (protocolVersion_0_4_1) {
|
||||
final int folderCount = buf.readInt();
|
||||
for (int i = 0; i < folderCount; i++) {
|
||||
SyncFolderDescriptor desc = SyncFolderDescriptor.deserialize(buf);
|
||||
|
@ -222,7 +213,6 @@ public class HelloClient extends DataHandler.FromServer {
|
|||
|
||||
serverPublishedModInfo = buf.readBoolean();
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
private void processAutoSyncFolder(final List<AutoSyncID> filesToRequest, final List<AutoSyncID.ForDirectFileRequest> filesToRemove) {
|
||||
|
@ -333,11 +323,14 @@ public class HelloClient extends DataHandler.FromServer {
|
|||
@Environment(EnvType.CLIENT)
|
||||
private void processModFileSync(final List<AutoSyncID> filesToRequest, final Set<String> mismatchingMods) {
|
||||
for (Entry<String, OfferedModInfo> e : modVersion.entrySet()) {
|
||||
final String localVersion = ModUtil.getModVersion(e.getKey());
|
||||
final String localVersion = ModUtil.convertModVersion(ModUtil.convertModVersion(ModUtil.getModVersion(e.getKey())));
|
||||
final OfferedModInfo serverInfo = e.getValue();
|
||||
final boolean requestMod = !serverInfo.version.equals(localVersion) && serverInfo.size > 0 && serverInfo.canDownload;
|
||||
|
||||
BCLib.LOGGER.info(" - " + e.getKey() + " (client=" + localVersion + ", server=" + serverInfo.version + ", size=" + PathUtil.humanReadableFileSize(serverInfo.size) + (requestMod ? ", requesting" : "") + (serverInfo.canDownload ? "" :", not offered")+ ")");
|
||||
ModInfo nfo = ModUtil.getModInfo(e.getKey());
|
||||
final boolean clientOnly = nfo!=null && nfo.metadata.getEnvironment()==ModEnvironment.CLIENT;
|
||||
final boolean requestMod = !clientOnly && !serverInfo.version.equals(localVersion) && serverInfo.size > 0 && serverInfo.canDownload;
|
||||
|
||||
BCLib.LOGGER.info(" - " + e.getKey() + " (client=" + localVersion + ", server=" + serverInfo.version + ", size=" + PathUtil.humanReadableFileSize(serverInfo.size) + (requestMod ? ", requesting" : "") + (serverInfo.canDownload ? "" :", not offered") + (clientOnly?", client only":"")+ ")");
|
||||
if (requestMod) {
|
||||
filesToRequest.add(new AutoSyncID.ForModFileRequest(e.getKey(), serverInfo.version));
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import net.minecraft.world.item.Item;
|
|||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.item.enchantment.Enchantments;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.LeavesBlock;
|
||||
|
@ -71,21 +72,25 @@ public class BaseLeavesBlock extends LeavesBlock implements BlockModelProvider,
|
|||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||
return BaseLeavesBlock.getLeaveDrops(this, this.sapling, builder, 16, 16);
|
||||
}
|
||||
|
||||
public static List<ItemStack> getLeaveDrops(ItemLike leaveBlock, Block sapling, LootContext.Builder builder, int fortuneRate, int dropRate) {
|
||||
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
|
||||
if (tool != null) {
|
||||
if (BaseShearsItem.isShear(tool) || EnchantmentHelper.getItemEnchantmentLevel(
|
||||
Enchantments.SILK_TOUCH,
|
||||
tool
|
||||
) > 0) {
|
||||
return Collections.singletonList(new ItemStack(this));
|
||||
return Collections.singletonList(new ItemStack(leaveBlock));
|
||||
}
|
||||
int fortune = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.BLOCK_FORTUNE, tool);
|
||||
if (MHelper.RANDOM.nextInt(16) <= fortune) {
|
||||
if (MHelper.RANDOM.nextInt(fortuneRate) <= fortune) {
|
||||
return Lists.newArrayList(new ItemStack(sapling));
|
||||
}
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
return MHelper.RANDOM.nextInt(16) == 0 ? Lists.newArrayList(new ItemStack(sapling)) : Lists.newArrayList();
|
||||
return MHelper.RANDOM.nextInt(dropRate) == 0 ? Lists.newArrayList(new ItemStack(sapling)) : Lists.newArrayList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -76,6 +76,7 @@ public class ModListScreen extends BCLibScreen {
|
|||
final int STATE_OK = 6;
|
||||
final int STATE_SERVER_MISSING_CLIENT_MOD = 5;
|
||||
final int STATE_MISSING_NOT_OFFERED = 4;
|
||||
final int STATE_VERSION_CLIENT_ONLY = 7;
|
||||
final int STATE_VERSION_NOT_OFFERED = 3;
|
||||
final int STATE_VERSION = 2;
|
||||
final int STATE_SERVER_MISSING = 1;
|
||||
|
@ -114,6 +115,9 @@ public class ModListScreen extends BCLibScreen {
|
|||
final String modVer = data.version();
|
||||
final int size = data.size();
|
||||
if (!modVer.equals(mod.getVersion())) {
|
||||
if (mod.metadata.getEnvironment() == ModEnvironment.CLIENT)
|
||||
state = STATE_VERSION_CLIENT_ONLY;
|
||||
else
|
||||
state = data.canDownload()?STATE_VERSION:STATE_VERSION_NOT_OFFERED;
|
||||
serverVersion = modVer;
|
||||
serverSize = size;
|
||||
|
@ -150,10 +154,12 @@ public class ModListScreen extends BCLibScreen {
|
|||
|
||||
int color = GridLayout.COLOR_RED;
|
||||
final String typeText;
|
||||
if (state==STATE_VERSION || state==STATE_VERSION_NOT_OFFERED) {
|
||||
if (state==STATE_VERSION || state==STATE_VERSION_NOT_OFFERED || state==STATE_VERSION_CLIENT_ONLY) {
|
||||
typeText = "[VERSION]";
|
||||
if (state == STATE_VERSION_NOT_OFFERED) {
|
||||
color = GridLayout.COLOR_YELLOW;
|
||||
} else if (state == STATE_VERSION_CLIENT_ONLY) {
|
||||
color = GridLayout.COLOR_DARK_GREEN;
|
||||
}
|
||||
} else if (state==STATE_MISSING || state==STATE_MISSING_NOT_OFFERED) {
|
||||
typeText = "[MISSING]";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package ru.bclib.integration.modmenu;
|
||||
package ru.bclib.integration;
|
||||
|
||||
import net.fabricmc.fabric.api.tag.TagFactory;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
|
@ -22,7 +22,7 @@ public abstract class BiomeSourceMixin implements BiomeSourceAccessor {
|
|||
@Mutable @Shadow @Final private List<StepFeatureData> featuresPerStep;
|
||||
|
||||
public void bclRebuildFeatures(){
|
||||
BCLib.LOGGER.info("Rebuilding features in BiomeSource " + this.getClass());
|
||||
BCLib.LOGGER.info("Rebuilding features in BiomeSource " + this);
|
||||
featuresPerStep = buildFeaturesPerStep(this.possibleBiomes().stream().toList(), true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package ru.bclib.mixin.common;
|
||||
|
||||
import joptsimple.AbstractOptionSpec;
|
||||
import joptsimple.ArgumentAcceptingOptionSpec;
|
||||
import joptsimple.NonOptionArgumentSpec;
|
||||
import joptsimple.OptionParser;
|
||||
import joptsimple.OptionSet;
|
||||
import joptsimple.OptionSpecBuilder;
|
||||
import net.minecraft.server.Main;
|
||||
import net.minecraft.server.dedicated.DedicatedServerSettings;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
|
@ -23,8 +26,25 @@ abstract public class MainMixin {
|
|||
@Inject(method="main", at=@At(value="INVOKE", target="Lnet/minecraft/world/level/storage/LevelStorageSource;createDefault(Ljava/nio/file/Path;)Lnet/minecraft/world/level/storage/LevelStorageSource;"))
|
||||
private static void bclib_callServerFix(String[] args, CallbackInfo ci){
|
||||
OptionParser parser = new OptionParser();
|
||||
ArgumentAcceptingOptionSpec<String> optionUniverse = parser.accepts("universe").withRequiredArg().defaultsTo(".", new String[0]);
|
||||
ArgumentAcceptingOptionSpec<String> optionUniverse = parser.accepts("universe").withRequiredArg().defaultsTo(".", (String[])new String[0]);
|
||||
ArgumentAcceptingOptionSpec<String> optionWorld = parser.accepts("world").withRequiredArg();
|
||||
|
||||
//this is only for compat reasons, we do not need to read thise options in our mixin, but it seems to cause
|
||||
//errors if they are not defined
|
||||
parser.accepts("nogui");
|
||||
parser.accepts("initSettings", "Initializes 'server.properties' and 'eula.txt', then quits");
|
||||
parser.accepts("demo");
|
||||
parser.accepts("bonusChest");
|
||||
parser.accepts("forceUpgrade");
|
||||
parser.accepts("eraseCache");
|
||||
parser.accepts("safeMode", "Loads level with vanilla datapack only");
|
||||
parser.accepts("help").forHelp();
|
||||
parser.accepts("singleplayer").withRequiredArg();
|
||||
parser.accepts("port").withRequiredArg().ofType(Integer.class).defaultsTo(-1, (Integer[])new Integer[0]);
|
||||
parser.accepts("serverId").withRequiredArg();
|
||||
parser.accepts("jfrProfile");
|
||||
parser.nonOptions();
|
||||
|
||||
OptionSet options = parser.parse(args);
|
||||
|
||||
Path settingPath = Paths.get("server.properties", new String[0]);
|
||||
|
|
|
@ -50,6 +50,11 @@ public class NoiseGeneratorSettingsMixin implements SurfaceRuleProvider {
|
|||
}
|
||||
|
||||
private void bclib_setCustomRules(List<RuleSource> rules) {
|
||||
if (rules.size()==0){
|
||||
bclib_clearCustomRules();
|
||||
return;
|
||||
}
|
||||
|
||||
RuleSource org = getOriginalSurfaceRule();
|
||||
if (org instanceof SurfaceRules.SequenceRuleSource sequenceRule){
|
||||
List<RuleSource> currentSequence = sequenceRule.sequence();
|
||||
|
@ -58,6 +63,7 @@ public class NoiseGeneratorSettingsMixin implements SurfaceRuleProvider {
|
|||
} else {
|
||||
rules.add(org);
|
||||
}
|
||||
|
||||
setSurfaceRule(SurfaceRules.sequence(rules.toArray(new RuleSource[rules.size()])));
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,8 @@ public class BlocksHelper {
|
|||
public static final Direction[] HORIZONTAL = makeHorizontal();
|
||||
public static final Direction[] DIRECTIONS = Direction.values();
|
||||
|
||||
private static final MutableBlockPos POS = new MutableBlockPos();
|
||||
private static final ThreadLocal<MutableBlockPos> TL_POS = ThreadLocal.withInitial(() -> new MutableBlockPos());
|
||||
|
||||
protected static final BlockState AIR = Blocks.AIR.defaultBlockState();
|
||||
protected static final BlockState WATER = Blocks.WATER.defaultBlockState();
|
||||
|
||||
|
@ -76,6 +77,7 @@ public class BlocksHelper {
|
|||
}
|
||||
|
||||
public static int downRayRep(LevelAccessor world, BlockPos pos, int maxDist) {
|
||||
final MutableBlockPos POS = TL_POS.get();
|
||||
POS.set(pos);
|
||||
for (int j = 1; j < maxDist && (world.getBlockState(POS)).getMaterial().isReplaceable(); j++) {
|
||||
POS.setY(POS.getY() - 1);
|
||||
|
@ -84,6 +86,7 @@ public class BlocksHelper {
|
|||
}
|
||||
|
||||
public static int raycastSqr(LevelAccessor world, BlockPos pos, int dx, int dy, int dz, int maxDist) {
|
||||
final MutableBlockPos POS = TL_POS.get();
|
||||
POS.set(pos);
|
||||
for (int j = 1; j < maxDist && (world.getBlockState(POS)).getMaterial().isReplaceable(); j++) {
|
||||
POS.move(dx, dy, dz);
|
||||
|
|
|
@ -62,53 +62,31 @@ public class ModUtil {
|
|||
|
||||
mods = new HashMap<>();
|
||||
org.apache.logging.log4j.Logger logger = LogManager.getFormatterLogger("BCLib|ModLoader");
|
||||
PathUtil.fileWalker(PathUtil.MOD_FOLDER.toFile(), false, (file -> {
|
||||
try {
|
||||
URI uri = URI.create("jar:" + file.toUri());
|
||||
FileSystem fs = FileSystems.getFileSystem(uri);
|
||||
if (fs!=null) {
|
||||
try {
|
||||
Path modMetaFile = fs.getPath("fabric.mod.json");
|
||||
if (modMetaFile != null) {
|
||||
try (InputStream is = Files.newInputStream(modMetaFile)) {
|
||||
//ModMetadata mc = ModMetadataParser.parseMetadata(is, uri.toString(), new LinkedList<String>());
|
||||
ModMetadata mc = readJSON(is, uri.toString());
|
||||
if (mc!=null){
|
||||
mods.put(mc.getId(), new ModInfo(mc, file));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
BCLib.LOGGER.error(e.getMessage());
|
||||
}
|
||||
}));
|
||||
PathUtil.fileWalker(PathUtil.MOD_FOLDER.toFile(), false, (ModUtil::accept));
|
||||
|
||||
return mods;
|
||||
}
|
||||
|
||||
private static ModMetadata readJSON(InputStream is, String sourceFile) throws IOException {
|
||||
try (com.google.gson.stream.JsonReader reader = new JsonReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
|
||||
JsonObject data = new JsonParser().parse(reader).getAsJsonObject();
|
||||
JsonObject data = new JsonParser().parse(reader)
|
||||
.getAsJsonObject();
|
||||
Version ver;
|
||||
try {
|
||||
ver = new SemanticVersionImpl(data.get("version").getAsString(), false);
|
||||
ver = new SemanticVersionImpl(data.get("version")
|
||||
.getAsString(), false);
|
||||
}
|
||||
catch (VersionParsingException e) {
|
||||
BCLib.LOGGER.error("Unable to parse Version in " + sourceFile);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (data.get("id") == null){
|
||||
if (data.get("id") == null) {
|
||||
BCLib.LOGGER.error("Unable to read ID in " + sourceFile);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (data.get("name") == null){
|
||||
if (data.get("name") == null) {
|
||||
BCLib.LOGGER.error("Unable to read name in " + sourceFile);
|
||||
return null;
|
||||
}
|
||||
|
@ -118,6 +96,7 @@ public class ModUtil {
|
|||
public Version getVersion() {
|
||||
return ver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "fabric";
|
||||
|
@ -125,7 +104,8 @@ public class ModUtil {
|
|||
|
||||
@Override
|
||||
public String getId() {
|
||||
return data.get("id").getAsString();
|
||||
return data.get("id")
|
||||
.getAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -136,35 +116,44 @@ public class ModUtil {
|
|||
@Override
|
||||
public ModEnvironment getEnvironment() {
|
||||
JsonElement env = data.get("environment");
|
||||
if (env==null) {
|
||||
if (env == null) {
|
||||
BCLib.LOGGER.warning("No environment specified in " + sourceFile);
|
||||
//return ModEnvironment.UNIVERSAL;
|
||||
}
|
||||
final String environment = env==null?"":env.getAsString().toLowerCase(Locale.ROOT);
|
||||
final String environment = env == null ? "" : env.getAsString()
|
||||
.toLowerCase(Locale.ROOT);
|
||||
|
||||
if (environment.isEmpty() || environment.equals("*") || environment.equals("common")) {
|
||||
if (environment.isEmpty() || environment.equals("*") || environment.equals("\"*\"") || environment.equals("common")) {
|
||||
JsonElement entrypoints = data.get("entrypoints");
|
||||
boolean hasClient = true;
|
||||
|
||||
//check if there is an actual client entrypoint
|
||||
if (entrypoints!=null && entrypoints.isJsonObject()){
|
||||
JsonElement client = entrypoints.getAsJsonObject().get("client");
|
||||
if (client!=null && client.isJsonArray()){
|
||||
hasClient = client.getAsJsonArray().size() > 0;
|
||||
} else if (client==null || !client.isJsonPrimitive()){
|
||||
if (entrypoints != null && entrypoints.isJsonObject()) {
|
||||
JsonElement client = entrypoints.getAsJsonObject()
|
||||
.get("client");
|
||||
if (client != null && client.isJsonArray()) {
|
||||
hasClient = client.getAsJsonArray()
|
||||
.size() > 0;
|
||||
}
|
||||
else if (client == null || !client.isJsonPrimitive()) {
|
||||
hasClient = false;
|
||||
} else if (!client.getAsJsonPrimitive().isString()){
|
||||
}
|
||||
else if (!client.getAsJsonPrimitive()
|
||||
.isString()) {
|
||||
hasClient = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasClient == false) return ModEnvironment.SERVER;
|
||||
//if (hasClient == false) return ModEnvironment.SERVER;
|
||||
return ModEnvironment.UNIVERSAL;
|
||||
} else if (environment.equals("client")) {
|
||||
}
|
||||
else if (environment.equals("client")) {
|
||||
return ModEnvironment.CLIENT;
|
||||
} else if (environment.equals("server")) {
|
||||
}
|
||||
else if (environment.equals("server")) {
|
||||
return ModEnvironment.SERVER;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
BCLib.LOGGER.error("Unable to read environment in " + sourceFile);
|
||||
return ModEnvironment.UNIVERSAL;
|
||||
}
|
||||
|
@ -201,7 +190,8 @@ public class ModUtil {
|
|||
|
||||
@Override
|
||||
public String getName() {
|
||||
return data.get("name").getAsString();
|
||||
return data.get("name")
|
||||
.getAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -325,13 +315,16 @@ public class ModUtil {
|
|||
}
|
||||
try {
|
||||
int res = 0;
|
||||
final String semanticVersionPattern = "(\\d+)\\.(\\d+)\\.(\\d+)\\D*";
|
||||
final String semanticVersionPattern = "(\\d+)\\.(\\d+)(\\.(\\d+))?\\D*";
|
||||
final Matcher matcher = Pattern.compile(semanticVersionPattern)
|
||||
.matcher(version);
|
||||
if (matcher.find()) {
|
||||
if (matcher.groupCount() > 0) res = (Integer.parseInt(matcher.group(1)) & 0xFF) << 22;
|
||||
if (matcher.groupCount() > 1) res |= (Integer.parseInt(matcher.group(2)) & 0xFF) << 14;
|
||||
if (matcher.groupCount() > 2) res |= Integer.parseInt(matcher.group(3)) & 0x3FFF;
|
||||
if (matcher.groupCount() > 0)
|
||||
res = matcher.group(1) == null ? 0 : ((Integer.parseInt(matcher.group(1)) & 0xFF) << 22);
|
||||
if (matcher.groupCount() > 1)
|
||||
res |= matcher.group(2) == null ? 0 : ((Integer.parseInt(matcher.group(2)) & 0xFF) << 14);
|
||||
if (matcher.groupCount() > 3)
|
||||
res |= matcher.group(4) == null ? 0 : Integer.parseInt(matcher.group(4)) & 0x3FFF;
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -376,6 +369,44 @@ public class ModUtil {
|
|||
return convertModVersion(v1) >= convertModVersion(v2);
|
||||
}
|
||||
|
||||
private static void accept(Path file) {
|
||||
try {
|
||||
URI uri = URI.create("jar:" + file.toUri());
|
||||
|
||||
FileSystem fs;
|
||||
// boolean doClose = false;
|
||||
try {
|
||||
fs = FileSystems.getFileSystem(uri);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// doClose = true;
|
||||
fs = FileSystems.newFileSystem(file);
|
||||
}
|
||||
if (fs != null) {
|
||||
try {
|
||||
Path modMetaFile = fs.getPath("fabric.mod.json");
|
||||
if (modMetaFile != null) {
|
||||
try (InputStream is = Files.newInputStream(modMetaFile)) {
|
||||
//ModMetadata mc = ModMetadataParser.parseMetadata(is, uri.toString(), new LinkedList<String>());
|
||||
ModMetadata mc = readJSON(is, uri.toString());
|
||||
if (mc != null) {
|
||||
mods.put(mc.getId(), new ModInfo(mc, file));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
BCLib.LOGGER.error("Error for " + uri + ": " + e.toString());
|
||||
}
|
||||
//if (doClose) fs.close();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
BCLib.LOGGER.error("Error for " + file.toUri() + ": " + e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ModInfo {
|
||||
public final ModMetadata metadata;
|
||||
public final Path jarPath;
|
||||
|
@ -416,7 +447,9 @@ public class ModUtil {
|
|||
}
|
||||
|
||||
public String getVersion() {
|
||||
if (metadata == null) return "0.0.0";
|
||||
if (metadata == null) {
|
||||
return "0.0.0";
|
||||
}
|
||||
return versionToString(metadata.getVersion());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,4 +191,9 @@ public class BCLibEndBiomeSource extends BCLBiomeSource {
|
|||
public static void register() {
|
||||
Registry.register(Registry.BIOME_SOURCE, BCLib.makeID("end_biome_source"), CODEC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BCLib - The End BiomeSource";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,4 +153,9 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource {
|
|||
this.biomeMap = mapConstructor.apply(seed, GeneratorOptions.getBiomeSizeNether(), BiomeAPI.NETHER_BIOME_PICKER);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BCLib - Nether BiomeSource";
|
||||
}
|
||||
}
|
||||
|
|
55
src/main/resources/assets/bclib/lang/zh_cn.json
Normal file
55
src/main/resources/assets/bclib/lang/zh_cn.json
Normal file
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
"message.bclib.anvil_damage": "§c损坏",
|
||||
"bclib.datafixer.backupWarning.title": "发现了一个不兼容的世界",
|
||||
"bclib.datafixer.backupWarning.message": "自从上次加载这个世界以来,一些安装的MOD的内部结构确实发生了变化。\n\n我们可以自动为您更改世界。如果继续而不应用更改,则世界可能无法正确加载,在着之前,您应该创建一个备份.",
|
||||
"bclib.datafixer.backupWarning.backup": "创建备份",
|
||||
"bclib.datafixer.backupWarning.nofixes": "忽略错误",
|
||||
"bclib.datafixer.backupWarning.fix": "应用修复",
|
||||
"title.bclib.bclibmissmatch": "版本不匹配",
|
||||
"message.bclib.bclibmissmatch": "服务器上的BCLib版本与此客户端不匹配。这将导致非常严重的问题。\n\n是否要从服务器自动下载BCLib版本?\n\nBCLib将在安装新版本之前,将旧版本移动到Mods文件夹的子目录中.",
|
||||
"title.bclib.syncfiles": "不匹配数据",
|
||||
"message.bclib.syncfiles": "服务器上的某些内容与客户端上的版本不匹配。\n是否要用服务器上的数据替换所选内容?",
|
||||
"message.bclib.syncfiles.mods": "同步Mods",
|
||||
"message.bclib.syncfiles.configs": "同步配置",
|
||||
"message.bclib.syncfiles.folders": "同步文件夹和文件",
|
||||
"message.bclib.syncfiles.delete": "删除不需要的文件",
|
||||
"title.bclib.confirmrestart": "需要重新启动",
|
||||
"message.bclib.confirmrestart": "请求的内容已同步。你现在需要重新启动Minecraft.",
|
||||
"title.link.bclib.discord": "Discord",
|
||||
"title.bclib.modmenu.main": "BCLib设置",
|
||||
"title.bclib.progress": "改进",
|
||||
"title.bclib.filesync.progress": "文件传输",
|
||||
"message.bclib.filesync.progress": "正在将文件内容与服务器同步",
|
||||
"message.bclib.filesync.progress.stage.empty": "",
|
||||
|
||||
"title.config.bclib.client.auto_sync.enabled": "启用自动同步",
|
||||
"title.config.bclib.client.auto_sync.acceptConfigs": "接受下载的配置文件",
|
||||
"title.config.bclib.client.auto_sync.acceptFiles": "接受下载的文件",
|
||||
"title.config.bclib.client.auto_sync.acceptMods": "接受下载的MOD",
|
||||
"title.config.bclib.client.auto_sync.displayModInfo": "当服务器端MOD与客户端不同时显示警告",
|
||||
"title.config.bclib.client.auto_sync.debugHashes": "将自动同步调试哈希打印到日志",
|
||||
|
||||
"title.config.bclib.generator.options.useOldBiomeGenerator": "使用旧版1.17生物群落生成器",
|
||||
"title.config.bclib.main.patches.applyPatches": "加载时自动应用修复补丁",
|
||||
"title.config.bclib.main.patches.repairBiomesOnLoad": "将生物群系固定在水平荷载上",
|
||||
"title.config.bclib.client.ui.suppressExperimentalDialogOnLoad": "禁用加载时的实验警告",
|
||||
|
||||
"title.bclib.syncfiles.modInfo": "模组信息",
|
||||
"title.bclib.syncfiles.modlist": "模组列表",
|
||||
"message.bclib.syncfiles.modlist": "以下显示已安装的MOD的状态 \n\n将同步本地不存在或服务器上版本不同的所有MOD",
|
||||
"title.bclib.modmissmatch": "Mod版本冲突",
|
||||
"message.bclib.modmissmatch": "此客户端上的某些MOD与服务器上的MOD版本不匹配。\n可能导致奇怪的游戏行为或崩溃。请确保您使用与服务器相同的mod版本",
|
||||
|
||||
"message.bclib.datafixer.progress.waitbackup": "正在等待备份完成。这可能需要一段时间!",
|
||||
"message.bclib.datafixer.progress.reading": "读取数据",
|
||||
"message.bclib.datafixer.progress.players": "固定玩家",
|
||||
"message.bclib.datafixer.progress.level": "将修复补丁应用于level.dat",
|
||||
"message.bclib.datafixer.progress.worlddata": "修补自定义世界数据",
|
||||
"message.bclib.datafixer.progress.regions": "修复所有区域",
|
||||
"message.bclib.datafixer.progress.saving": "保存补丁状态",
|
||||
"title.bclib.datafixer.progress": "修复世界",
|
||||
"message.bclib.datafixer.progress": "将所有修复补丁应用于您的世界",
|
||||
"title.bclib.datafixer.error": "修复世界时的错误",
|
||||
"message.bclib.datafixer.error": "修复世界时出现了错误,请还原备份并修复以下错误,然后重试",
|
||||
"title.bclib.datafixer.error.continue": "继续并标记为已修复"
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue