diff --git a/gradle.properties b/gradle.properties index 0248697c..2bb2cfae 100644 --- a/gradle.properties +++ b/gradle.properties @@ -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 \ No newline at end of file +modmenu_version=3.0.1 \ No newline at end of file diff --git a/src/main/java/ru/bclib/BCLib.java b/src/main/java/ru/bclib/BCLib.java index f80d8a0d..1077f5be 100644 --- a/src/main/java/ru/bclib/BCLib.java +++ b/src/main/java/ru/bclib/BCLib.java @@ -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; diff --git a/src/main/java/ru/bclib/api/ModIntegrationAPI.java b/src/main/java/ru/bclib/api/ModIntegrationAPI.java index 4b5db5d0..b36eec68 100644 --- a/src/main/java/ru/bclib/api/ModIntegrationAPI.java +++ b/src/main/java/ru/bclib/api/ModIntegrationAPI.java @@ -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; diff --git a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java index 274783f8..6529f8e6 100644 --- a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java @@ -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> 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> modifications, Biome biome) { + private static void applyModificationsAndUpdateFeatures(List> modifications, Biome biome) { ResourceLocation biomeID = getBiomeID(biome); - modifications.forEach(consumer -> { - consumer.accept(biomeID, 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. diff --git a/src/main/java/ru/bclib/api/dataexchange/handler/autosync/HelloClient.java b/src/main/java/ru/bclib/api/dataexchange/handler/autosync/HelloClient.java index 9c693c2d..6cac3961 100644 --- a/src/main/java/ru/bclib/api/dataexchange/handler/autosync/HelloClient.java +++ b/src/main/java/ru/bclib/api/dataexchange/handler/autosync/HelloClient.java @@ -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; - } + size = buf.readInt(); + canDownload = buf.readBoolean(); modVersion.put(id, new OfferedModInfo(version, size, canDownload)); } @@ -213,15 +205,13 @@ 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); - autoSynFolders.add(desc); - } - - serverPublishedModInfo = buf.readBoolean(); + final int folderCount = buf.readInt(); + for (int i = 0; i < folderCount; i++) { + SyncFolderDescriptor desc = SyncFolderDescriptor.deserialize(buf); + autoSynFolders.add(desc); } + + serverPublishedModInfo = buf.readBoolean(); } @Environment(EnvType.CLIENT) @@ -333,11 +323,14 @@ public class HelloClient extends DataHandler.FromServer { @Environment(EnvType.CLIENT) private void processModFileSync(final List filesToRequest, final Set mismatchingMods) { for (Entry 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)); } diff --git a/src/main/java/ru/bclib/blocks/BaseLeavesBlock.java b/src/main/java/ru/bclib/blocks/BaseLeavesBlock.java index 46b8ce93..9955fbad 100644 --- a/src/main/java/ru/bclib/blocks/BaseLeavesBlock.java +++ b/src/main/java/ru/bclib/blocks/BaseLeavesBlock.java @@ -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 getDrops(BlockState state, LootContext.Builder builder) { + return BaseLeavesBlock.getLeaveDrops(this, this.sapling, builder, 16, 16); + } + + public static List 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 diff --git a/src/main/java/ru/bclib/gui/screens/ModListScreen.java b/src/main/java/ru/bclib/gui/screens/ModListScreen.java index 4a923aad..e4d06201 100644 --- a/src/main/java/ru/bclib/gui/screens/ModListScreen.java +++ b/src/main/java/ru/bclib/gui/screens/ModListScreen.java @@ -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,7 +115,10 @@ public class ModListScreen extends BCLibScreen { final String modVer = data.version(); final int size = data.size(); if (!modVer.equals(mod.getVersion())) { - state = data.canDownload()?STATE_VERSION:STATE_VERSION_NOT_OFFERED; + 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]"; diff --git a/src/main/java/ru/bclib/integration/modmenu/ModIntegration.java b/src/main/java/ru/bclib/integration/ModIntegration.java similarity index 96% rename from src/main/java/ru/bclib/integration/modmenu/ModIntegration.java rename to src/main/java/ru/bclib/integration/ModIntegration.java index 9f196e41..e1d93576 100644 --- a/src/main/java/ru/bclib/integration/modmenu/ModIntegration.java +++ b/src/main/java/ru/bclib/integration/ModIntegration.java @@ -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; diff --git a/src/main/java/ru/bclib/mixin/common/BiomeSourceMixin.java b/src/main/java/ru/bclib/mixin/common/BiomeSourceMixin.java index 1ea16ead..d407b585 100644 --- a/src/main/java/ru/bclib/mixin/common/BiomeSourceMixin.java +++ b/src/main/java/ru/bclib/mixin/common/BiomeSourceMixin.java @@ -22,7 +22,7 @@ public abstract class BiomeSourceMixin implements BiomeSourceAccessor { @Mutable @Shadow @Final private List 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); } } diff --git a/src/main/java/ru/bclib/mixin/common/MainMixin.java b/src/main/java/ru/bclib/mixin/common/MainMixin.java index ba203f35..09592d6e 100644 --- a/src/main/java/ru/bclib/mixin/common/MainMixin.java +++ b/src/main/java/ru/bclib/mixin/common/MainMixin.java @@ -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 optionUniverse = parser.accepts("universe").withRequiredArg().defaultsTo(".", new String[0]); + ArgumentAcceptingOptionSpec optionUniverse = parser.accepts("universe").withRequiredArg().defaultsTo(".", (String[])new String[0]); ArgumentAcceptingOptionSpec 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]); diff --git a/src/main/java/ru/bclib/mixin/common/NoiseGeneratorSettingsMixin.java b/src/main/java/ru/bclib/mixin/common/NoiseGeneratorSettingsMixin.java index 808f7cf6..d5f6deba 100644 --- a/src/main/java/ru/bclib/mixin/common/NoiseGeneratorSettingsMixin.java +++ b/src/main/java/ru/bclib/mixin/common/NoiseGeneratorSettingsMixin.java @@ -50,6 +50,11 @@ public class NoiseGeneratorSettingsMixin implements SurfaceRuleProvider { } private void bclib_setCustomRules(List rules) { + if (rules.size()==0){ + bclib_clearCustomRules(); + return; + } + RuleSource org = getOriginalSurfaceRule(); if (org instanceof SurfaceRules.SequenceRuleSource sequenceRule){ List 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()]))); } diff --git a/src/main/java/ru/bclib/util/BlocksHelper.java b/src/main/java/ru/bclib/util/BlocksHelper.java index 6bf7c8b1..f2257e37 100644 --- a/src/main/java/ru/bclib/util/BlocksHelper.java +++ b/src/main/java/ru/bclib/util/BlocksHelper.java @@ -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 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); diff --git a/src/main/java/ru/bclib/util/ModUtil.java b/src/main/java/ru/bclib/util/ModUtil.java index 94ab1097..7c1d2d40 100644 --- a/src/main/java/ru/bclib/util/ModUtil.java +++ b/src/main/java/ru/bclib/util/ModUtil.java @@ -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()); - 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()); + 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()); } } diff --git a/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java b/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java index a95763df..c689dcb8 100644 --- a/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java +++ b/src/main/java/ru/bclib/world/generator/BCLibEndBiomeSource.java @@ -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"; + } } diff --git a/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java b/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java index 78bb50e3..01365eba 100644 --- a/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java +++ b/src/main/java/ru/bclib/world/generator/BCLibNetherBiomeSource.java @@ -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"; + } } diff --git a/src/main/resources/assets/bclib/lang/zh_cn.json b/src/main/resources/assets/bclib/lang/zh_cn.json new file mode 100644 index 00000000..a4634b50 --- /dev/null +++ b/src/main/resources/assets/bclib/lang/zh_cn.json @@ -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": "继续并标记为已修复" +}