diff --git a/bukkit/compatibility/legacy/src/main/java/net/momirealms/craftengine/bukkit/compatibility/legacy/slimeworld/LegacySlimeFormatStorageAdaptor.java b/bukkit/compatibility/legacy/src/main/java/net/momirealms/craftengine/bukkit/compatibility/legacy/slimeworld/LegacySlimeFormatStorageAdaptor.java index 872e50bf8..982f91c5e 100644 --- a/bukkit/compatibility/legacy/src/main/java/net/momirealms/craftengine/bukkit/compatibility/legacy/slimeworld/LegacySlimeFormatStorageAdaptor.java +++ b/bukkit/compatibility/legacy/src/main/java/net/momirealms/craftengine/bukkit/compatibility/legacy/slimeworld/LegacySlimeFormatStorageAdaptor.java @@ -2,8 +2,10 @@ package net.momirealms.craftengine.bukkit.compatibility.legacy.slimeworld; import com.infernalsuite.aswm.api.events.LoadSlimeWorldEvent; import com.infernalsuite.aswm.api.world.SlimeWorld; +import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.world.World; import net.momirealms.craftengine.core.world.WorldManager; +import net.momirealms.craftengine.core.world.chunk.storage.CachedStorage; import net.momirealms.craftengine.core.world.chunk.storage.DefaultStorageAdaptor; import net.momirealms.craftengine.core.world.chunk.storage.WorldDataStorage; import org.bukkit.Bukkit; @@ -22,7 +24,8 @@ public class LegacySlimeFormatStorageAdaptor extends DefaultStorageAdaptor imple @EventHandler public void onWorldLoad(LoadSlimeWorldEvent event) { org.bukkit.World world = Bukkit.getWorld(event.getSlimeWorld().getName()); - this.worldManager.loadWorld(this.worldManager.createWorld(this.worldManager.wrap(world), new LegacySlimeWorldDataStorage(event.getSlimeWorld()))); + this.worldManager.loadWorld(this.worldManager.createWorld(this.worldManager.wrap(world), + Config.enableChunkCache() ? new CachedStorage<>(new LegacySlimeWorldDataStorage(event.getSlimeWorld())) : new LegacySlimeWorldDataStorage(event.getSlimeWorld()))); } public LegacySlimeFormatStorageAdaptor(WorldManager worldManager, int version) { diff --git a/bukkit/compatibility/legacy/src/main/java/net/momirealms/craftengine/bukkit/compatibility/legacy/slimeworld/LegacySlimeWorldDataStorage.java b/bukkit/compatibility/legacy/src/main/java/net/momirealms/craftengine/bukkit/compatibility/legacy/slimeworld/LegacySlimeWorldDataStorage.java index 74acc1e05..4feff8a93 100644 --- a/bukkit/compatibility/legacy/src/main/java/net/momirealms/craftengine/bukkit/compatibility/legacy/slimeworld/LegacySlimeWorldDataStorage.java +++ b/bukkit/compatibility/legacy/src/main/java/net/momirealms/craftengine/bukkit/compatibility/legacy/slimeworld/LegacySlimeWorldDataStorage.java @@ -42,7 +42,7 @@ public class LegacySlimeWorldDataStorage implements WorldDataStorage { } @Override - public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk, boolean immediately) { + public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk) { SlimeChunk slimeChunk = getWorld().getChunk(pos.x, pos.z); if (slimeChunk == null) return; CompoundTag nbt = DefaultChunkSerializer.serialize(chunk); diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/slimeworld/SlimeFormatStorageAdaptor.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/slimeworld/SlimeFormatStorageAdaptor.java index b01a6e1c1..2c02934a8 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/slimeworld/SlimeFormatStorageAdaptor.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/slimeworld/SlimeFormatStorageAdaptor.java @@ -3,9 +3,11 @@ package net.momirealms.craftengine.bukkit.compatibility.slimeworld; import com.infernalsuite.asp.api.AdvancedSlimePaperAPI; import com.infernalsuite.asp.api.events.LoadSlimeWorldEvent; import com.infernalsuite.asp.api.world.SlimeWorld; +import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.util.ReflectionUtils; import net.momirealms.craftengine.core.world.World; import net.momirealms.craftengine.core.world.WorldManager; +import net.momirealms.craftengine.core.world.chunk.storage.CachedStorage; import net.momirealms.craftengine.core.world.chunk.storage.DefaultStorageAdaptor; import net.momirealms.craftengine.core.world.chunk.storage.WorldDataStorage; import org.bukkit.Bukkit; @@ -24,7 +26,8 @@ public class SlimeFormatStorageAdaptor extends DefaultStorageAdaptor implements @EventHandler public void onWorldLoad(LoadSlimeWorldEvent event) { org.bukkit.World world = Bukkit.getWorld(event.getSlimeWorld().getName()); - this.worldManager.loadWorld(this.worldManager.createWorld(this.worldManager.wrap(world), new SlimeWorldDataStorage(event.getSlimeWorld(), this))); + this.worldManager.loadWorld(this.worldManager.createWorld(this.worldManager.wrap(world), + Config.enableChunkCache() ? new CachedStorage<>(new SlimeWorldDataStorage(event.getSlimeWorld(), this)) : new SlimeWorldDataStorage(event.getSlimeWorld(), this))); } public SlimeFormatStorageAdaptor(WorldManager worldManager) { diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/slimeworld/SlimeWorldDataStorage.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/slimeworld/SlimeWorldDataStorage.java index ae6703087..663689520 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/slimeworld/SlimeWorldDataStorage.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/slimeworld/SlimeWorldDataStorage.java @@ -44,7 +44,7 @@ public class SlimeWorldDataStorage implements WorldDataStorage { @SuppressWarnings("unchecked") @Override - public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk, boolean immediately) { + public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk) { SlimeChunk slimeChunk = getWorld().getChunk(pos.x, pos.z); if (slimeChunk == null) return; CompoundTag nbt = DefaultChunkSerializer.serialize(chunk); diff --git a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/FastAsyncWorldEditDelegate.java b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/FastAsyncWorldEditDelegate.java index 9127b6c7b..fc51538cf 100644 --- a/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/FastAsyncWorldEditDelegate.java +++ b/bukkit/compatibility/src/main/java/net/momirealms/craftengine/bukkit/compatibility/worldedit/FastAsyncWorldEditDelegate.java @@ -31,6 +31,7 @@ import net.momirealms.craftengine.core.world.SectionPos; import net.momirealms.craftengine.core.world.chunk.CEChunk; import net.momirealms.craftengine.core.world.chunk.CESection; import org.bukkit.Bukkit; +import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.lang.reflect.Method; @@ -143,7 +144,8 @@ public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent { } @Override - protected Operation commitBefore() { + public @Nullable Operation commit() { + Operation operation = super.commit(); saveAllChunks(); List chunks = new ArrayList<>(this.brokenChunks); this.brokenChunks.clear(); @@ -155,7 +157,7 @@ public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent { if (loaded == null) continue; injectLevelChunk(chunkSource, loaded); } - return super.commitBefore(); + return operation; } private void processBlocks(Iterable region, Pattern pattern) { @@ -196,7 +198,7 @@ public class FastAsyncWorldEditDelegate extends AbstractDelegateExtent { try { for (CEChunk ceChunk : this.chunksToSave) { CraftEngine.instance().debug(() -> "Saving chunk " + ceChunk.chunkPos()); - this.ceWorld.worldDataStorage().writeChunkAt(ceChunk.chunkPos(), ceChunk, true); + this.ceWorld.worldDataStorage().writeChunkAt(ceChunk.chunkPos(), ceChunk); } this.chunksToSave.clear(); } catch (IOException e) { diff --git a/bukkit/loader/src/main/resources/config.yml b/bukkit/loader/src/main/resources/config.yml index b25083cec..297be7fe4 100644 --- a/bukkit/loader/src/main/resources/config.yml +++ b/bukkit/loader/src/main/resources/config.yml @@ -345,8 +345,9 @@ light-system: force-update-light: false chunk-system: - # Unloaded chunks may be loaded soon. Delaying serialization can improve performance, especially for those double-dimension mob farms. - delay-serialization: 20 # seconds -1 = disable + # With cache system, those frequently load/unload chunks would consume fewer resources on serialization + # Enabling this option will increase memory consumption to a certain extent + cache-system: true # 1 = NONE | Compression Speed | Decompress Speed | Compression Ratio | Memory Usage | # 2 = DEFLATE | Medium-Slow Medium Moderate Low | # 3 = GZIP | Medium-Slow Medium Moderate Low | @@ -356,11 +357,11 @@ chunk-system: # Settings for injection injection: # Requires a restart to apply - # SECTION: Inject the LevelChunkSection (Faster, but may conflict with some plugins) + # SECTION: Inject the LevelChunkSection (Faster & Experimental) since 0.0.53 # PALETTE: Inject the PalettedContainer target: PALETTE # Enables faster injection method - # Note: May not work with certain server forks that alter chunk saving behavior + # Note: May not work with certain server forks that alter chunk class structure (In most cases it won't conflict) use-fast-method: false # Auto-convert custom blocks -> vanilla blocks when unloading chunks # diff --git a/bukkit/loader/src/main/resources/translations/en.yml b/bukkit/loader/src/main/resources/translations/en.yml index 2d63d9711..ff18b0826 100644 --- a/bukkit/loader/src/main/resources/translations/en.yml +++ b/bukkit/loader/src/main/resources/translations/en.yml @@ -1,7 +1,6 @@ # Don't change this lang-version: "${lang_version}" -# Commands exception.invalid_syntax: "Invalid syntax. Correct syntax: " exception.invalid_argument: "Invalid argument. Reason: " exception.invalid_sender: " is not allowed to execute that command. Must be of type " @@ -70,6 +69,8 @@ warning.config.type.float: "Issue found in file - Failed to load warning.config.type.double: "Issue found in file - Failed to load '': Cannot cast '' to double type for option ''." warning.config.type.quaternionf: "Issue found in file - Failed to load '': Cannot cast '' to Quaternionf type for option ''." warning.config.type.vector3f: "Issue found in file - Failed to load '': Cannot cast '' to Vector3f type for option ''." +warning.config.number.missing_type: "Issue found in file - The config '' is missing the required 'type' argument for number argument." +warning.config.number.invalid_type: "Issue found in file - The config '' is using an invalid number argument type ''." warning.config.number.missing_argument: "Issue found in file - The config '' is missing the argument for 'number'." warning.config.number.invalid_format: "Issue found in file - The config '' is using an invalid number format ''." warning.config.number.fixed.missing_value: "Issue found in file - The config '' is missing the required 'value' argument for 'constant' number." @@ -223,7 +224,7 @@ warning.config.block.behavior.sapling.missing_stage: "Issue found in fil warning.config.block.behavior.sapling.missing_feature: "Issue found in file - The block '' is missing the required 'feature' argument for 'sapling_block' behavior." warning.config.block.behavior.strippable.missing_stripped: "Issue found in file - The block '' is missing the required 'stripped' argument for 'strippable_block' behavior." warning.config.block.event.condition.missing_type: "Issue found in file - The block '' is missing the required 'type' argument for event condition." -warning.config.block.event.condition.invalid_type: "Issue found in file - The block '' is using an invalid 'type' argument for event condition." +warning.config.block.event.condition.invalid_type: "Issue found in file - The block '' is using an invalid 'type' argument '' for event condition." warning.config.model.generation.missing_parent: "Issue found in file - The config '' is missing the required 'parent' argument in 'generation' section." warning.config.model.generation.conflict: "Issue found in file - Failed to generate model for '' as two or more configurations attempt to generate different json models with the same path: ''." warning.config.model.generation.texture.invalid: "Issue found in file - The config '' has a texture '' with path '' that contains illegal characters. Please read https://minecraft.wiki/w/Resource_location#Legal_characters." @@ -249,8 +250,6 @@ warning.config.loot_table.entry.exp.missing_count: "Issue found in file warning.config.loot_table.entry.item.missing_item: "Issue found in file - '' has a misconfigured loot table, entry 'item' is missing the required 'item' argument." warning.config.loot_table.condition.missing_type: "Issue found in file - '' has a misconfigured loot table, one of the conditions is missing the required 'type' argument." warning.config.loot_table.condition.invalid_type: "Issue found in file - '' has a misconfigured loot table, one of the conditions is using an invalid condition type ''." -warning.config.loot_table.number.missing_type: "Issue found in file - '' has a misconfigured loot table, one of the numbers is missing the required 'type' argument." -warning.config.loot_table.number.invalid_type: "Issue found in file - '' has a misconfigured loot table, one of the numbers is using an invalid number type ''." warning.config.host.missing_type: "Issue found in config.yml at 'resource-pack.delivery.hosting' - Missing required 'type' argument for host." warning.config.host.invalid_type: "Issue found in config.yml at 'resource-pack.delivery.hosting' - Host type '' is invalid. Please read https://mo-mi.gitbook.io/xiaomomi-plugins/craftengine/plugin-wiki/craftengine/resource-pack/host." warning.config.host.external.missing_url: "Issue found in config.yml at 'resource-pack.delivery.hosting' - Missing required 'url' argument for external host." diff --git a/bukkit/loader/src/main/resources/translations/tr.yml b/bukkit/loader/src/main/resources/translations/tr.yml index 427920624..def783519 100644 --- a/bukkit/loader/src/main/resources/translations/tr.yml +++ b/bukkit/loader/src/main/resources/translations/tr.yml @@ -1,50 +1,50 @@ # Don't change this lang-version: "${lang_version}" -exception.invalid_syntax: "Geçersiz sözdizimi. Doğru sözdizimi: " -exception.invalid_argument: "Geçersiz argüman. Sebep: " -exception.invalid_sender: " bu komutu çalıştırma izni yok. türünde olmalı" -exception.unexpected: "Bu komutu gerçekleştirmeye çalışırken dahili bir hata oluştu" -exception.no_permission: "Üzgünüm, bu komutu kullanma izniniz yok" +exception.invalid_syntax: "Geçersiz sözdizimi. Doğru kullanım: " +exception.invalid_argument: "Geçersiz argüman. Neden: " +exception.invalid_sender: " bu komutu çalıştırmaya yetkili değil. türünde olmalı" +exception.unexpected: "Bu komutu gerçekleştirirken dahili bir hata oluştu" +exception.no_permission: "Üzgünüm, ancak bu komutu kullanma izniniz yok" exception.no_such_command: "Bilinmeyen komut." argument.entity.notfound.player: "" argument.entity.notfound.entity: "" -argument.parse.failure.time: "'' geçerli bir zaman formatı değil" -argument.parse.failure.material: "'' geçerli bir materyal adı değil" +argument.parse.failure.time: "'' geçerli bir zaman biçimi değil" +argument.parse.failure.material: "'' geçerli bir malzeme adı değil" argument.parse.failure.enchantment: "'' geçerli bir büyü değil" -argument.parse.failure.offlineplayer: "'' için oyuncu bulunamadı" -argument.parse.failure.player: "'' için oyuncu bulunamadı" +argument.parse.failure.offlineplayer: "'' girişi için oyuncu bulunamadı" +argument.parse.failure.player: "'' girişi için oyuncu bulunamadı" argument.parse.failure.world: "'' geçerli bir Minecraft dünyası değil" argument.parse.failure.location.invalid_format: "'' geçerli bir konum değil. Gerekli format: ' " -argument.parse.failure.location.mixed_local_absolute: "Yerel ve mutlak koordinatlar karıştırılamaz. (ya tüm koordinatlar '^' kullanmalı ya da hiçbiri kullanmamalı)" -argument.parse.failure.namespacedkey.namespace: "Geçersiz ad alanı ''. [a-z0-9._-] olmalı" +argument.parse.failure.location.mixed_local_absolute: "Yerel ve mutlak koordinatlar karıştırılamaz. (ya tüm koordinatlar '^' kullanır ya da hiçbiri kullanmaz)" +argument.parse.failure.namespacedkey.namespace: "Geçersiz isim alanı ''. [a-z0-9._-] olmalı" argument.parse.failure.namespacedkey.key: "Geçersiz anahtar ''. [a-z0-9/._-] olmalı" -argument.parse.failure.namespacedkey.need_namespace: "Geçersiz girdi '', açık bir ad alanı gerektirir" -argument.parse.failure.boolean: "'' değerinden boolean değeri ayrıştırılamadı" -argument.parse.failure.number: "'' ile aralığında geçerli bir sayı değil" +argument.parse.failure.namespacedkey.need_namespace: "Geçersiz giriş '', açık bir isim alanı gerektirir" +argument.parse.failure.boolean: "'' ifadesinden boolean değeri ayrıştırılamadı" +argument.parse.failure.number: "'', ile aralığında geçerli bir sayı değil" argument.parse.failure.char: "'' geçerli bir karakter değil" -argument.parse.failure.string: "'' türünde geçerli bir dize değil" +argument.parse.failure.string: "'', türünde geçerli bir metin değil" argument.parse.failure.uuid: "'' geçerli bir UUID değil" argument.parse.failure.enum: "'' şunlardan biri değil: " -argument.parse.failure.regex: "'' şununla eşleşmiyor: ''" +argument.parse.failure.regex: "'', '' ile eşleşmiyor" argument.parse.failure.flag.unknown: "Bilinmeyen bayrak ''" -argument.parse.failure.flag.duplicate_flag: "Yinelenen bayrak ''" +argument.parse.failure.flag.duplicate_flag: "Tekrarlanan bayrak ''" argument.parse.failure.flag.no_flag_started: "Hiçbir bayrak başlatılmadı. '' ile ne yapılacağı bilinmiyor" argument.parse.failure.flag.missing_argument: "'' için eksik argüman" argument.parse.failure.flag.no_permission: "'' kullanma izniniz yok" argument.parse.failure.color: "'' geçerli bir renk değil" -argument.parse.failure.duration: "'' bir süre formatı değil" +argument.parse.failure.duration: "'' bir süre biçimi değil" argument.parse.failure.aggregate.missing: "Eksik bileşen ''" argument.parse.failure.aggregate.failure: "Geçersiz bileşen '': " -argument.parse.failure.either: "'' için veya çözümlenemedi" -argument.parse.failure.namedtextcolor: "'' geçerli bir metin rengi adı değil" -command.reload.config.success: "Yapılandırmalar ms içinde yeniden yüklendi. (Asenkron: ms | Senkron: ms)" -command.reload.config.failure: "Yapılandırma yeniden yükleme başarısız oldu. Konsol günlüklerini kontrol edin." +argument.parse.failure.either: "'' ifadesinden veya çözümlenemedi" +argument.parse.failure.namedtextcolor: "'' adlandırılmış bir metin rengi değil" +command.reload.config.success: "Yapılandırmalar ms içinde yeniden yüklendi. (Eşzamansız: ms | Eşzamanlı: ms)" +command.reload.config.failure: "Yapılandırma yeniden yüklemesi başarısız oldu. Konsol günlüklerini kontrol edin." command.reload.pack.success: "Kaynak paketi ms içinde yeniden yüklendi." -command.reload.pack.failure: "Kaynak paketi yeniden yükleme başarısız oldu. Konsol günlüklerini kontrol edin." -command.reload.all.success: "Yeniden yükleme ms içinde tamamlandı. (Asenkron: ms | Senkron: ms | Paket: ms)" +command.reload.pack.failure: "Kaynak paketi yeniden yüklemesi başarısız oldu. Konsol günlüklerini kontrol edin." +command.reload.all.success: "Yeniden yükleme ms içinde tamamlandı. (Eşzamansız: ms | Eşzamanlı: ms | Paket: ms)" command.reload.all.failure: "Yeniden yükleme başarısız oldu. Konsol günlüklerini kontrol edin." -command.item.get.success: " alındı" +command.item.get.success: " adet alındı" command.item.get.failure.not_exist: "'>" command.item.give.success.single: "':'':''>" command.item.give.success.multiple: "':'':''>" @@ -53,91 +53,219 @@ command.search_recipe.not_found: "Bu eşya için tarif bulunamadı" command.search_usage.not_found: "Bu eşya için kullanım bulunamadı" command.search_recipe.no_item: "Bu komutu çalıştırmadan önce lütfen bir eşya tutun" command.search_usage.no_item: "Bu komutu çalıştırmadan önce lütfen bir eşya tutun" -command.totem_animation.failure.not_totem: "Eşya '' minecraft:totem_of_undying değil" -command.resource.enable.success: " kaynağı etkinleştirildi. Değişiklikleri uygulamak için /ce reload all çalıştırın" +command.totem_animation.failure.not_totem: "'' eşyası minecraft:totem_of_undying değil" +command.resource.enable.success: " kaynağı etkinleştirildi. Değişiklikleri uygulamak için /ce reload all komutunu çalıştırın" command.resource.enable.failure.unknown: "Bilinmeyen kaynak " -command.resource.disable.success: " kaynağı devre dışı bırakıldı. Değişiklikleri uygulamak için /ce reload all çalıştırın" +command.resource.disable.success: " kaynağı devre dışı bırakıldı. Değişiklikleri uygulamak için /ce reload all komutunu çalıştırın" command.resource.disable.failure.unknown: "Bilinmeyen kaynak " command.resource.list: "Etkin kaynaklar(): Devre dışı kaynaklar(): " command.upload.failure.not_supported: "Mevcut barındırma yöntemi '' kaynak paketlerinin yüklenmesini desteklemiyor." -command.upload.on_progress: "Yükleme süreci başlatıldı. Daha fazla bilgi için konsolu kontrol edin." +command.upload.on_progress: "Yükleme işlemi başlatıldı. Daha fazla bilgi için konsola bakın." command.send_resource_pack.success.single: "Kaynak paketi kişisine gönderildi." command.send_resource_pack.success.multiple: "Kaynak paketleri oyuncuya gönderildi." - -# Outdated, needs update -#warning.config.image.duplicated: " dosyasında sorun - '' görseli yineleniyor." -#warning.config.image.lack_height: " dosyasında sorun - '' görseli gerekli 'height' argümanı eksik." -#warning.config.image.height_smaller_than_ascent: " dosyasında sorun - '' görseli bitmap görsel kuralını ihlal ediyor: 'height' 'ascent'ten düşük olmamalı." -#warning.config.image.no_file: " dosyasında sorun - '' görseli gerekli 'file' argümanı eksik." -#warning.config.image.invalid_resource_location: " dosyasında sorun - '' görselinin 'file' argümanı [] yasal karakterler içeriyor. Lütfen https://minecraft.wiki/w/Resource_location#Legal_characters adresini okuyun" -#warning.config.image.invalid_font_name: " dosyasında sorun - '' görselinin 'font' argümanı [] yasal karakterler içeriyor. Lütfen https://minecraft.wiki/w/Resource_location#Legal_characters adresini okuyun" -#warning.config.image.lack_char: " dosyasında sorun - '' görseli gerekli 'char' argümanı eksik." -#warning.config.image.codepoint_in_use: " dosyasında sorun - '' görseli fontunda başka bir görsel olan '' tarafından kullanılmış bir karakter[()] kullanıyor." -#warning.config.image.invalid_codepoint_grid: " dosyasında sorun - '' görseli geçersiz bir 'chars' kod noktası ızgarasına sahip." -#warning.config.image.file_not_exist: " dosyasında sorun - '' görseli için '' PNG dosyası bulunamadı." -#warning.config.recipe.duplicated: " dosyasında sorun - Yinelenen tarif ''." -#warning.config.i18n.unknown_locale: " dosyasında sorun - Bilinmeyen yerel ayar ''." -#warning.config.template.duplicated: " dosyasında sorun - Yinelenen şablon ''." -#warning.config.vanilla_loot.type_not_exist: " dosyasında sorun - '' vanilla ganimeti için 'type' ayarlanmamış." -#warning.config.vanilla_loot.block.invalid_target: " dosyasında sorun - '' vanilla ganimetinde geçersiz blok hedefi []." -#warning.config.sound.duplicated: " dosyasında sorun - Yinelenen ses ''." -#warning.config.jukebox_song.duplicated: " dosyasında sorun - Yinelenen müzik kutusu şarkısı ''." -#warning.config.furniture.duplicated: " dosyasında sorun - Yinelenen mobilya ''." -#warning.config.furniture.lack_placement: " dosyasında sorun - '' mobilyası gerekli 'placement' argümanı eksik." -#warning.config.furniture.element.lack_item: " dosyasında sorun - '' mobilyasının elementlerinden biri için gerekli 'item' argümanı eksik." -#warning.config.item.duplicated: " dosyasında sorun - Yinelenen eşya ''." -#warning.config.item.lack_material: " dosyasında sorun - '' eşyası gerekli 'material' argümanı eksik." -#warning.config.item.invalid_material: " dosyasında sorun - '' eşyası geçersiz bir materyal türü olan '' kullanıyor." -#warning.config.item.bad_custom_model_data_value: " dosyasında sorun - '' eşyası çok büyük bir özel model verisi [] kullanıyor. 16.777.216'dan düşük bir değer kullanılması önerilir." -#warning.config.item.custom_model_data_conflict: " dosyasında sorun - '' eşyası '' eşyası tarafından zaten kullanılmış bir özel model verisi [] kullanıyor" -#warning.config.item.lack_model_id: " dosyasında sorun - '' eşyası gerekli 'custom-model-data' veya 'item-model' argümanı eksik." -#warning.config.block.duplicated: " dosyasında sorun - Yinelenen blok ''." -#warning.config.block.lack_state: " dosyasında sorun - '' bloğu gerekli 'state' argümanı eksik." -#warning.config.block.state.lack_real_id: " dosyasında sorun - '' bloğu 'state' için gerekli 'id' argümanı eksik." -#warning.config.block.state.lack_state: " dosyasında sorun - '' bloğu 'state' için gerekli 'state' argümanı eksik." -#warning.config.block.state.lack_properties: " dosyasında sorun - '' bloğu 'states' için gerekli 'properties' bölümü eksik." -#warning.config.block.state.lack_appearances: " dosyasında sorun - '' bloğu 'states' için gerekli 'appearances' bölümü eksik." -#warning.config.block.state.lack_variants: " dosyasında sorun - '' bloğu 'states' için gerekli 'variants' bölümü eksik." -#warning.config.block.state.variant.lack_appearance: " dosyasında sorun - '' bloğu '' varyantı için gerekli 'appearance' argümanı eksik." -#warning.config.block.state.variant.invalid_appearance: " dosyasında sorun - '' bloğunda '' varyantının var olmayan bir görünüm olan '' kullandığı hatası var." -#warning.config.block.state.invalid_state: " dosyasında sorun - '' bloğu geçersiz bir vanilla blok durumu olan '' kullanıyor." -#warning.config.block.state.unavailable_state: " dosyasında sorun - '' bloğu kullanılamayan bir vanilla blok durumu olan '' kullanıyor." -#warning.config.block.state.invalid_vanilla_state_id: " dosyasında sorun - '' bloğu mevcut slot aralığı '0~' dışında bir vanilla blok durumu '' kullanıyor." -#warning.config.block.state.conflict: " dosyasında sorun - '' bloğu '' tarafından zaten kullanılmış bir vanilla blok durumu '' kullanıyor." -#warning.config.block.state.bind_real_state: " dosyasında sorun - '' bloğu '' için gerçek blok durumu bağlanamadı çünkü durum '' tarafından kullanılıyor." -#warning.config.block.state.invalid_property_structure: " dosyasında sorun - '' bloğunda geçersiz bir özellik yapısı '' var." -#warning.config.block.state.invalid_property: " dosyasında sorun - '' bloğu için '' özelliği oluşturulamadı: ." -#warning.config.block.state.no_model_set: " dosyasında sorun - '' bloğu gerekli 'model' veya 'models' argümanı eksik." -#warning.config.block.state.invalid_real_state_id: " dosyasında sorun - '' bloğu mevcut slot aralığı '0~' dışında bir gerçek blok durumu '' kullanıyor. Eğer slotlar tükenmişse 'additional-real-blocks.yml' içine daha fazla gerçek durum eklemeyi düşünün." -#warning.config.block.state.model.lack_path: " dosyasında sorun - '' bloğu 'model' için gerekli 'path' seçeneği eksik." -#warning.config.block.state.model.invalid_resource_location: " dosyasında sorun - '' bloğunun 'path' argümanı [] yasal karakterler içeriyor. Lütfen https://minecraft.wiki/w/Resource_location#Legal_characters adresini okuyun" -#warning.config.model.generation.conflict: " dosyasında sorun - '' için model oluşturulamadı çünkü iki veya daha fazla yapılandırma aynı yolla farklı json modelleri oluşturmaya çalışıyor: ''" -#warning.config.model.generation.texture.invalid_resource_location: " dosyasında sorun - '' yapılandırmasının '' doku argümanı [] yasal karakterler içeriyor. Lütfen https://minecraft.wiki/w/Resource_location#Legal_characters adresini okuyun" -#warning.config.model.generation.parent.invalid_resource_location: " dosyasında sorun - '' yapılandırmasının parent argümanı [] yasal karakterler içeriyor. Lütfen https://minecraft.wiki/w/Resource_location#Legal_characters adresini okuyun" -#warning.config.emoji.lack_keywords: " dosyasında sorun - '' emojisi gerekli 'keywords' argümanı eksik." -#warning.config.emoji.duplicated: " dosyasında sorun - Yinelenen emoji ''." -#warning.config.emoji.invalid_image: " dosyasında sorun - '' emojisi geçersiz bir 'image' argümanı '' kullanıyor." -#warning.config.advancement.duplicated: " dosyasında sorun - Yinelenen ilerleme ''." -#warning.config.host.lack_type: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - Host için gerekli 'type' argümanı eksik." -#warning.config.host.invalid_type: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - Host 'type' [] geçersiz. Lütfen https://mo-mi.gitbook.io/xiaomomi-plugins/craftengine/plugin-wiki/craftengine/resource-pack/host adresini okuyun" -#warning.config.host.external.lack_url: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - Harici host için gerekli 'url' argümanı eksik." -#warning.config.host.alist.lack_api_url: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - Alist host için gerekli 'api-url' argümanı eksik." -#warning.config.host.alist.lack_username: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - Alist host için gerekli 'username' argümanı veya 'CE_ALIST_USERNAME' ortam değişkeni eksik." -#warning.config.host.alist.lack_password: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - Alist host için gerekli 'password' argümanı veya 'CE_ALIST_PASSWORD' ortam değişkeni eksik." -#warning.config.host.alist.lack_upload_path: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - Alist host için gerekli 'upload-path' argümanı eksik." -#warning.config.host.dropbox.lack_app_key: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - Dropbox host için gerekli 'app-key' argümanı veya 'CE_DROPBOX_APP_KEY' ortam değişkeni eksik." -#warning.config.host.dropbox.lack_app_secret: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - Dropbox host için gerekli 'app-secret' argümanı veya 'CE_DROPBOX_APP_SECRET' ortam değişkeni eksik." -#warning.config.host.dropbox.lack_refresh_token: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - Dropbox host için gerekli 'refresh-token' argümanı veya 'CE_DROPBOX_REFRESH_TOKEN' ortam değişkeni eksik." -#warning.config.host.dropbox.lack_upload_path: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - Dropbox host için gerekli 'upload-path' argümanı eksik." -#warning.config.host.lobfile.lack_api_key: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - Lobfile host için gerekli 'api-key' argümanı eksik." -#warning.config.host.onedrive.lack_client_id: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - OneDrive host için gerekli 'client-id' argümanı veya 'CE_ONEDRIVE_CLIENT_ID' ortam değişkeni eksik." -#warning.config.host.onedrive.lack_client_secret: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - OneDrive host için gerekli 'client-secret' argümanı veya 'CE_ONEDRIVE_CLIENT_SECRET' ortam değişkeni eksik." -#warning.config.host.onedrive.lack_refresh_token: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - OneDrive host için gerekli 'refresh-token' argümanı veya 'CE_ONEDRIVE_REFRESH_TOKEN' ortam değişkeni eksik." -#warning.config.host.onedrive.lack_upload_path: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - OneDrive host için gerekli 'upload-path' argümanı eksik." -#warning.config.host.s3.lack_endpoint: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - S3 host için gerekli 'endpoint' argümanı eksik." -#warning.config.host.s3.lack_bucket: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - S3 host için gerekli 'bucket' argümanı eksik." -#warning.config.host.s3.lack_access_key_id: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - S3 host için gerekli 'access-key-id' argümanı veya 'CE_S3_ACCESS_KEY_ID' ortam değişkeni eksik." -#warning.config.host.s3.lack_access_key_secret: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - S3 host için gerekli 'access-key-secret' argümanı veya 'CE_S3_ACCESS_KEY_SECRET' ortam değişkeni eksik." -#warning.config.host.s3.lack_upload_path: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - S3 host için gerekli 'upload-path' argümanı eksik." -#warning.config.host.self.lack_ip: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - Self host için gerekli 'ip' argümanı eksik." -#warning.config.host.self.invalid_port: "config.yml dosyasında 'resource-pack.delivery.hosting' konumunda sorun - Self host için geçersiz 'port' []." \ No newline at end of file +warning.config.pack.duplicated_files: "Yinelenen dosyalar bulundu. Lütfen config.yml 'resource-pack.duplicated-files-handler' bölümünden bunları çözün." +warning.config.type.int: " dosyasında sorun bulundu - '' yüklenemedi: '' değeri '' seçeneği için tamsayı türüne dönüştürülemiyor." +warning.config.type.float: " dosyasında sorun bulundu - '' yüklenemedi: '' değeri '' seçeneği için ondalık türüne dönüştürülemiyor." +warning.config.type.double: " dosyasında sorun bulundu - '' yüklenemedi: '' değeri '' seçeneği için double türüne dönüştürülemiyor." +warning.config.type.quaternionf: " dosyasında sorun bulundu - '' yüklenemedi: '' değeri '' seçeneği için Quaternionf türüne dönüştürülemiyor." +warning.config.type.vector3f: " dosyasında sorun bulundu - '' yüklenemedi: '' değeri '' seçeneği için Vector3f türüne dönüştürülemiyor." +warning.config.structure.not_section: " dosyasında sorun bulundu - '' yapılandırması bir yapılandırma bölümü olması beklenirken aslında bir '' türündedir." +warning.config.image.duplicate: " dosyasında sorun bulundu - Yinelenen resim ''. Diğer dosyalarda aynı yapılandırmanın olup olmadığını kontrol edin." +warning.config.image.missing_height: " dosyasında sorun bulundu - '' resmi gerekli 'height' argümanı eksik." +warning.config.image.height_ascent_conflict: " dosyasında sorun bulundu - '' resmi bitmap resim kuralını ihlal ediyor: 'height' argümanı '', 'ascent' argümanı '' değerinden düşük olmamalı." +warning.config.image.missing_file: " dosyasında sorun bulundu - '' resmi gerekli 'file' argümanı eksik." +warning.config.image.invalid_file_chars: " dosyasında sorun bulundu - '' resmi, yasak karakterler içeren '' 'file' argümanına sahip. Lütfen https://minecraft.wiki/w/Resource_location#Legal_characters sayfasını okuyun." +warning.config.image.invalid_font_chars: " dosyasında sorun bulundu - '' resmi, yasak karakterler içeren '' 'font' argümanına sahip. Lütfen https://minecraft.wiki/w/Resource_location#Legal_characters sayfasını okuyun." +warning.config.image.missing_char: " dosyasında sorun bulundu - '' resmi gerekli 'char' argümanı eksik." +warning.config.image.codepoint_conflict: " dosyasında sorun bulundu - '' resmi, yazı tipinde başka bir resim '' tarafından kullanılmış olan '()' karakterini kullanıyor." +warning.config.image.invalid_codepoint_grid: " dosyasında sorun bulundu - '' resminin geçersiz bir 'chars' kod noktası ızgarası var." +warning.config.image.file_not_found: " dosyasında sorun bulundu - '' resmi için '' PNG dosyası bulunamadı." +warning.config.image.invalid_hex_value: " dosyasında sorun bulundu - '' resmi, geçerli bir onaltılık (16 tabanlı) değer olmayan '' unicode karakterini kullanıyor." +warning.config.recipe.duplicate: " dosyasında sorun bulundu - Yinelenen tarif ''. Diğer dosyalarda aynı yapılandırmanın olup olmadığını kontrol edin." +warning.config.recipe.missing_type: " dosyasında sorun bulundu - '' tarifi gerekli 'type' argümanı eksik." +warning.config.recipe.invalid_type: " dosyasında sorun bulundu - '' tarifi geçersiz bir tarif türü '' kullanıyor." +warning.config.recipe.invalid_item: " dosyasında sorun bulundu - '' tarifi geçersiz bir eşya '' kullanıyor." +warning.config.recipe.missing_ingredient: " dosyasında sorun bulundu - '' pişirme tarifi gerekli 'ingredient' argümanı eksik." +warning.config.recipe.missing_result: " dosyasında sorun bulundu - '' tarifi gerekli 'result' argümanı eksik." +warning.config.recipe.result.missing_id: " dosyasında sorun bulundu - '' tarifi, tarif sonucu için gerekli 'id' argümanı eksik." +warning.config.recipe.crafting.invalid_category: " dosyasında sorun bulundu - '' üretim tarifi geçersiz bir kategori '' kullanıyor. İzin verilen kategoriler: []." +warning.config.recipe.cooking.invalid_category: " dosyasında sorun bulundu - '' pişirme tarifi geçersiz bir kategori '' kullanıyor. İzin verilen kategoriler: []." +warning.config.recipe.shaped.missing_pattern: " dosyasında sorun bulundu - '' şekilli tarifi gerekli 'pattern' argümanı eksik." +warning.config.recipe.shaped.invalid_pattern: " dosyasında sorun bulundu - '' şekilli tarifi geçersiz bir desen '' kullanıyor." +warning.config.recipe.shaped.invalid_symbol: " dosyasında sorun bulundu - '' şekilli tarifi, desende geçersiz bir sembol '' kullanıyor." +warning.config.recipe.smithing_transform.post_processor.missing_type: " dosyasında sorun bulundu - '' demircilik dönüşüm tarifi, işlem sonrası işleyicilerinden biri için gerekli 'type' argümanı eksik." +warning.config.recipe.smithing_transform.post_processor.invalid_type: " dosyasında sorun bulundu - '' demircilik dönüşüm tarifi geçersiz bir işlem sonrası işleyici türü '' kullanıyor." +warning.config.recipe.smithing_transform.post_processor.keep_component.missing_components: " dosyasında sorun bulundu - '' demircilik dönüşüm tarifi, 'keep_components' işlem sonrası işleyicisi için gerekli 'components' argümanı eksik." +warning.config.recipe.smithing_transform.post_processor.keep_component.missing_tags: " dosyasında sorun bulundu - '' demircilik dönüşüm tarifi, 'keep_tags' işlem sonrası işleyicisi için gerekli 'tags' argümanı eksik." +warning.config.i18n.unknown_locale: " dosyasında sorun bulundu - Bilinmeyen yerel ayar ''." +warning.config.template.duplicate: " dosyasında sorun bulundu - Yinelenen şablon ''. Diğer dosyalarda aynı yapılandırmanın olup olmadığını kontrol edin." +warning.config.template.argument.self_increase_int.invalid_range: " dosyasında sorun bulundu - '' şablonu, 'self_increase_int' argümanında 'to' '' değerinden daha büyük bir 'from' '' değeri kullanıyor." +warning.config.template.argument.list.invalid_type: " dosyasında sorun bulundu - '' şablonu, argüman olarak bir 'List' bekleyen bir 'list' argümanı kullanıyor, ancak giriş argümanı bir '' türünde." +warning.config.vanilla_loot.missing_type: " dosyasında sorun bulundu - '' vanilya ganimeti gerekli 'type' argümanı eksik." +warning.config.vanilla_loot.invalid_type: " dosyasında sorun bulundu - '' vanilya ganimeti geçersiz bir tür '' kullanıyor. İzin verilen türler: []." +warning.config.vanilla_loot.block.invalid_target: " dosyasında sorun bulundu - '' vanilya ganimetinde geçersiz blok hedefi ''." +warning.config.sound.duplicate: " dosyasında sorun bulundu - Yinelenen ses ''. Diğer dosyalarda aynı yapılandırmanın olup olmadığını kontrol edin." +warning.config.sound.missing_sounds: " dosyasında sorun bulundu - '' sesi gerekli 'sounds' argümanı eksik." +warning.config.sound.missing_name: " dosyasında sorun bulundu - '' sesi gerekli 'name' argümanı eksik." +warning.config.jukebox_song.duplicate: " dosyasında sorun bulundu - Yinelenen müzik çalar şarkısı ''. Diğer dosyalarda aynı yapılandırmanın olup olmadığını kontrol edin." +warning.config.jukebox_song.missing_sound: " dosyasında sorun bulundu - '' müzik çalar şarkısı gerekli 'sound' argümanı eksik." +warning.config.furniture.duplicate: " dosyasında sorun bulundu - Yinelenen mobilya ''. Diğer dosyalarda aynı yapılandırmanın olup olmadığını kontrol edin." +warning.config.furniture.missing_placement: " dosyasında sorun bulundu - '' mobilyası gerekli 'placement' argümanı eksik." +warning.config.furniture.element.missing_item: " dosyasında sorun bulundu - '' mobilyası, elementlerinden biri için gerekli 'item' argümanı eksik." +warning.config.furniture.settings.unknown: " dosyasında sorun bulundu - '' mobilyası bilinmeyen bir ayar türü '' kullanıyor." +warning.config.furniture.hitbox.invalid_type: " dosyasında sorun bulundu - '' mobilyası geçersiz bir hitbox türü '' kullanıyor." +warning.config.furniture.hitbox.custom.invalid_entity: " dosyasında sorun bulundu - '' mobilyası, geçersiz varlık türü '' olan özel bir hitbox kullanıyor." +warning.config.item.duplicate: " dosyasında sorun bulundu - Yinelenen eşya ''. Diğer dosyalarda aynı yapılandırmanın olup olmadığını kontrol edin." +warning.config.item.settings.unknown: " dosyasında sorun bulundu - '' eşyası bilinmeyen bir ayar türü '' kullanıyor." +warning.config.item.missing_material: " dosyasında sorun bulundu - '' eşyası gerekli 'material' argümanı eksik." +warning.config.item.invalid_material: " dosyasında sorun bulundu - '' eşyası geçersiz bir malzeme türü '' kullanıyor." +warning.config.item.bad_custom_model_data: " dosyasında sorun bulundu - '' eşyası çok büyük bir özel model verisi '' kullanıyor. 16.777.216'dan düşük bir değer kullanmanız önerilir." +warning.config.item.custom_model_data_conflict: " dosyasında sorun bulundu - '' eşyası, '' eşyası tarafından işgal edilmiş bir özel model verisi '' kullanıyor." +warning.config.item.missing_model_id: " dosyasında sorun bulundu - '' eşyası gerekli 'custom-model-data' veya 'item-model' argümanı eksik." +warning.config.item.behavior.missing_type: " dosyasında sorun bulundu - '' eşyası, eşya davranışı için gerekli 'type' argümanı eksik." +warning.config.item.behavior.invalid_type: " dosyasında sorun bulundu - '' eşyası geçersiz bir eşya davranış türü '' kullanıyor." +warning.config.item.behavior.block.missing_block: " dosyasında sorun bulundu - '' eşyası, 'block_item' davranışı için gerekli 'block' argümanı eksik." +warning.config.item.behavior.furniture.missing_furniture: " dosyasında sorun bulundu - '' eşyası, 'furniture_item' davranışı için gerekli 'furniture' argümanı eksik." +warning.config.item.behavior.liquid_collision.missing_block: " dosyasında sorun bulundu - '' eşyası, 'liquid_collision_block_item' davranışı için gerekli 'block' argümanı eksik." +warning.config.item.model.invalid_type: " dosyasında sorun bulundu - '' eşyası geçersiz bir model türü '' kullanıyor." +warning.config.item.model.tint.missing_type: " dosyasında sorun bulundu - '' eşyası, renk tonu için gerekli 'type' argümanı eksik." +warning.config.item.model.tint.invalid_type: " dosyasında sorun bulundu - '' eşyası geçersiz bir renk tonu türü '' kullanıyor." +warning.config.item.model.tint.constant.missing_value: " dosyasında sorun bulundu - '' eşyası, sabit renk tonu için gerekli 'value' argümanı eksik." +warning.config.item.model.tint.grass.invalid_temp: " dosyasında sorun bulundu - '' eşyası, çimen renk tonu için 0 ile 1 arasında olması beklenen geçersiz bir sıcaklık '' kullanıyor." +warning.config.item.model.tint.grass.invalid_downfall: " dosyasında sorun bulundu - '' eşyası, çimen renk tonu için 0 ile 1 arasında olması beklenen geçersiz bir yağış '' kullanıyor." +warning.config.item.model.tint.invalid_value: " dosyasında sorun bulundu - '' eşyası geçersiz bir renk tonu '' kullanıyor." +warning.config.item.model.base.missing_path: " dosyasında sorun bulundu - '' eşyası, 'minecraft:model' modeli için gerekli 'path' argümanı eksik." +warning.config.item.model.base.invalid_path: " dosyasında sorun bulundu - '' eşyasının, yasak karakterler içeren geçersiz bir 'path' argümanı '' var. Lütfen https://minecraft.wiki/w/Resource_location#Legal_characters sayfasını okuyun." +warning.config.item.model.condition.missing_property: " dosyasında sorun bulundu - '' eşyası, 'minecraft:condition' modeli için gerekli 'property' argümanı eksik." +warning.config.item.model.condition.invalid_property: " dosyasında sorun bulundu - '' eşyası, 'minecraft:condition' modeli için geçersiz bir özellik '' kullanıyor." +warning.config.item.model.condition.missing_on_true: " dosyasında sorun bulundu - '' eşyası, 'minecraft:condition' modeli için gerekli 'on-true' argümanı eksik." +warning.config.item.model.condition.missing_on_false: " dosyasında sorun bulundu - '' eşyası, 'minecraft:condition' modeli için gerekli 'on-false' argümanı eksik." +warning.config.item.model.condition.keybind.missing: " dosyasında sorun bulundu - '' eşyası, 'minecraft:keybind_down' özelliği için gerekli 'keybind' argümanı eksik." +warning.config.item.model.condition.has_component.missing_component: " dosyasında sorun bulundu - '' eşyası, 'minecraft:has_component' özelliği için gerekli 'component' argümanı eksik." +warning.config.item.model.composite.missing_models: " dosyasında sorun bulundu - '' eşyası, 'minecraft:composite' modeli için gerekli 'models' argümanı eksik." +warning.config.item.model.range_dispatch.missing_property: " dosyasında sorun bulundu - '' eşyası, 'minecraft:range_dispatch' modeli için gerekli 'property' argümanı eksik." +warning.config.item.model.range_dispatch.invalid_property: " dosyasında sorun bulundu - '' eşyası, 'minecraft:range_dispatch' modeli için geçersiz bir özellik '' kullanıyor." +warning.config.item.model.range_dispatch.missing_entries: " dosyasında sorun bulundu - '' eşyası, 'minecraft:composite' modeli için gerekli 'entries' argümanı eksik." +warning.config.item.model.range_dispatch.entry.missing_model: " dosyasında sorun bulundu - '' eşyası, 'minecraft:composite' modelindeki girişlerden biri için gerekli 'model' argümanı eksik." +warning.config.item.model.range_dispatch.compass.missing_target: " dosyasında sorun bulundu - '' eşyası, 'minecraft:compass' özelliği için gerekli 'target' argümanı eksik." +warning.config.item.model.range_dispatch.time.missing_source: " dosyasında sorun bulundu - '' eşyası, 'minecraft:time' özelliği için gerekli 'source' argümanı eksik." +warning.config.item.model.select.missing_property: " dosyasında sorun bulundu - '' eşyası, 'minecraft:select' modeli için gerekli 'property' argümanı eksik." +warning.config.item.model.select.invalid_property: " dosyasında sorun bulundu - '' eşyası, 'minecraft:select' modeli için geçersiz bir özellik '' kullanıyor." +warning.config.item.model.select.missing_cases: " dosyasında sorun bulundu - '' eşyası, 'minecraft:select' modeli için gerekli 'cases' argümanı eksik." +warning.config.item.model.select.case.missing_when: " dosyasında sorun bulundu - '' eşyası, 'minecraft:select' modelindeki durumlardan biri için gerekli 'when' argümanı eksik." +warning.config.item.model.select.case.missing_model: " dosyasında sorun bulundu - '' eşyası, 'minecraft:select' modelindeki durumlardan biri için gerekli 'model' argümanı eksik." +warning.config.item.model.select.block_state.missing_property: " dosyasında sorun bulundu - '' eşyası, 'minecraft:block_state' özelliği için gerekli 'block-state-property' argümanı eksik." +warning.config.item.model.select.local_time.missing_pattern: " dosyasında sorun bulundu - '' eşyası, 'minecraft:local_time' özelliği için gerekli 'pattern' argümanı eksik." +warning.config.item.model.special.missing_type: " dosyasında sorun bulundu - '' eşyası, 'minecraft:special' modeli için gerekli 'type' argümanı eksik." +warning.config.item.model.special.invalid_type: " dosyasında sorun bulundu - '' eşyası, 'minecraft:special' modeli için geçersiz bir tür '' kullanıyor." +warning.config.item.model.special.banner.missing_color: " dosyasında sorun bulundu - '' eşyası, 'minecraft:banner' özel modeli için gerekli 'color' argümanı eksik." +warning.config.item.model.special.bed.missing_texture: " dosyasında sorun bulundu - '' eşyası, 'minecraft:bed' özel modeli için gerekli 'texture' argümanı eksik." +warning.config.item.model.special.sign.missing_wood_type: " dosyasında sorun bulundu - '' eşyası, 'minecraft:hanging_sign'/'minecraft:standing_sign' özel modeli için gerekli 'wood-type' argümanı eksik." +warning.config.item.model.special.sign.missing_texture: " dosyasında sorun bulundu - '' eşyası, 'minecraft:hanging_sign'/'minecraft:standing_sign' özel modeli için gerekli 'texture' argümanı eksik." +warning.config.item.model.special.chest.missing_texture: " dosyasında sorun bulundu - '' eşyası, 'minecraft:chest' özel modeli için gerekli 'texture' argümanı eksik." +warning.config.item.model.special.chest.invalid_openness: " dosyasında sorun bulundu - '' eşyası, 'minecraft:chest' özel modeli için geçersiz bir 'openness' değeri '' kullanıyor. Geçerli aralık '0~1.'" +warning.config.item.model.special.shulker_box.missing_texture: " dosyasında sorun bulundu - '' eşyası, 'minecraft:shulker_box' özel modeli için gerekli 'texture' argümanı eksik." +warning.config.item.model.special.shulker_box.invalid_openness: " dosyasında sorun bulundu - '' eşyası, 'minecraft:shulker_box' özel modeli için geçersiz bir 'openness' değeri '' kullanıyor. Geçerli aralık '0~1.'" +warning.config.item.model.special.head.missing_kind: " dosyasında sorun bulundu - '' eşyası, 'minecraft:head' özel modeli için gerekli 'kind' argümanı eksik." +warning.config.item.model.special.head.missing_texture: " dosyasında sorun bulundu - '' eşyası, 'minecraft:head' özel modeli için gerekli 'texture' argümanı eksik." +warning.config.block.duplicate: " dosyasında sorun bulundu - Yinelenen blok ''. Diğer dosyalarda aynı yapılandırmanın olup olmadığını kontrol edin." +warning.config.block.missing_state: " dosyasında sorun bulundu - '' bloğu gerekli 'state' argümanı eksik." +warning.config.block.state.property.missing_type: " dosyasında sorun bulundu - '' bloğu, '' özelliği için gerekli 'type' argümanı eksik." +warning.config.block.state.property.invalid_type: " dosyasında sorun bulundu - '' bloğu, '' özelliği için geçersiz bir 'type' argümanı '' kullanıyor." +warning.config.block.state.property.integer.invalid_range: " dosyasında sorun bulundu - '' bloğu, '' tamsayı özelliği için geçersiz bir 'range' argümanı '' kullanıyor. Doğru sözdizimi: 1~2." +warning.config.block.state.property.invalid_format: " dosyasında sorun bulundu - '' bloğu, geçersiz bir blok durum özelliği formatı '' kullanıyor." +warning.config.block.state.missing_real_id: " dosyasında sorun bulundu - '' bloğu, 'state' için gerekli 'id' argümanı eksik. 'id', her blok durumu türü için benzersiz olan sunucu tarafı blok kimliğidir. 'note_block' ve id 30 ile bir sunucu tarafı blok oluşturursanız, gerçek blok kimliği 'craftengine:note_block_30' olur." +warning.config.block.state.missing_state: " dosyasında sorun bulundu - '' bloğu, 'state' için gerekli 'state' argümanı eksik." +warning.config.block.state.missing_properties: " dosyasında sorun bulundu - '' bloğu, 'states' için gerekli 'properties' bölümü eksik." +warning.config.block.state.missing_appearances: " dosyasında sorun bulundu - '' bloğu, 'states' için gerekli 'appearances' bölümü eksik." +warning.config.block.state.missing_variants: " dosyasında sorun bulundu - '' bloğu, 'states' için gerekli 'variants' bölümü eksik." +warning.config.block.state.variant.missing_appearance: " dosyasında sorun bulundu - '' bloğu, '' varyantı için gerekli 'appearance' argümanı eksik." +warning.config.block.state.variant.invalid_appearance: " dosyasında sorun bulundu - '' bloğunda, '' varyantının var olmayan bir görünüm '' kullandığı bir hata var." +warning.config.block.state.invalid_vanilla: " dosyasında sorun bulundu - '' bloğu geçersiz bir vanilya blok durumu '' kullanıyor." +warning.config.block.state.unavailable_vanilla: " dosyasında sorun bulundu - '' bloğu kullanılamayan bir vanilya blok durumu '' kullanıyor. Lütfen bu durumu mappings.yml dosyasında serbest bırakın." +warning.config.block.state.invalid_vanilla_id: " dosyasında sorun bulundu - '' bloğu, mevcut yuva aralığı '0~' aşan bir vanilya blok durumu '' kullanıyor." +warning.config.block.state.conflict: " dosyasında sorun bulundu - '' bloğu, '' tarafından işgal edilmiş bir vanilya blok durumu '' kullanıyor." +warning.config.block.state.bind_failed: " dosyasında sorun bulundu - '' bloğu, durum '' tarafından işgal edildiği için '' için gerçek blok durumu bağlamada başarısız oldu." +warning.config.block.state.missing_model: " dosyasında sorun bulundu - '' bloğu gerekli 'model' veya 'models' argümanı eksik." +warning.config.block.state.invalid_real_id: " dosyasında sorun bulundu - '' bloğu, mevcut yuva aralığı '0~' aşan bir gerçek blok durumu '' kullanıyor. Yuvalar kullanılmışsa, 'additional-real-blocks.yml' dosyasına daha fazla gerçek durum eklemeyi düşünün." +warning.config.block.state.model.missing_path: " dosyasında sorun bulundu - '' bloğu, 'model' için gerekli 'path' seçeneği eksik." +warning.config.block.state.model.invalid_path: " dosyasında sorun bulundu - '' bloğunun, yasak karakterler içeren bir 'path' argümanı '' var. Lütfen https://minecraft.wiki/w/Resource_location#Legal_characters sayfasını okuyun." +warning.config.block.settings.unknown: " dosyasında sorun bulundu - '' bloğu bilinmeyen bir ayar türü '' kullanıyor." +warning.config.block.behavior.missing_type: " dosyasında sorun bulundu - '' bloğu, blok davranışı için gerekli 'type' argümanı eksik." +warning.config.block.behavior.invalid_type: " dosyasında sorun bulundu - '' bloğu geçersiz bir blok davranış türü '' kullanıyor." +warning.config.block.behavior.concrete.missing_solid: " dosyasında sorun bulundu - '' bloğu, 'concrete_block' davranışı için gerekli 'solid-block' seçeneği eksik." +warning.config.block.behavior.crop.missing_age: " dosyasında sorun bulundu - '' bloğu, 'crop_block' davranışı için gerekli 'age' özelliği eksik." +warning.config.block.behavior.sugar_cane.missing_age: " dosyasında sorun bulundu - '' bloğu, 'sugar_cane_block' davranışı için gerekli 'age' özelliği eksik." +warning.config.block.behavior.leaves.missing_persistent: " dosyasında sorun bulundu - '' bloğu, 'leaves_block' davranışı için gerekli 'persistent' özelliği eksik." +warning.config.block.behavior.leaves.missing_distance: " dosyasında sorun bulundu - '' bloğu, 'leaves_block' davranışı için gerekli 'distance' özelliği eksik." +warning.config.block.behavior.sapling.missing_stage: " dosyasında sorun bulundu - '' bloğu, 'sapling_block' davranışı için gerekli 'stage' özelliği eksik." +warning.config.block.behavior.sapling.missing_feature: " dosyasında sorun bulundu - '' bloğu, 'sapling_block' davranışı için gerekli 'feature' argümanı eksik." +warning.config.block.behavior.strippable.missing_stripped: " dosyasında sorun bulundu - '' bloğu, 'strippable_block' davranışı için gerekli 'stripped' argümanı eksik." +warning.config.model.generation.missing_parent: " dosyasında sorun bulundu - '' yapılandırması, 'generation' bölümünde gerekli 'parent' argümanı eksik." +warning.config.model.generation.conflict: " dosyasında sorun bulundu - '' için model oluşturulurken hata; iki veya daha fazla yapılandırma aynı yolla farklı json modelleri oluşturmaya çalışıyor: ''." +warning.config.model.generation.texture.invalid: " dosyasında sorun bulundu - '' yapılandırması, yasak karakterler içeren '' yoluna sahip bir '' dokusuna sahip. Lütfen https://minecraft.wiki/w/Resource_location#Legal_characters sayfasını okuyun." +warning.config.model.generation.parent.invalid: " dosyasında sorun bulundu - '' yapılandırması, yasak karakterler içeren bir parent argümanı '' kullanıyor. Lütfen https://minecraft.wiki/w/Resource_location#Legal_characters sayfasını okuyun." +warning.config.emoji.missing_keywords: " dosyasında sorun bulundu - '' emojisi gerekli 'keywords' argümanı eksik." +warning.config.emoji.duplicate: " dosyasında sorun bulundu - Yinelenen emoji ''. Diğer dosyalarda aynı yapılandırmanın olup olmadığını kontrol edin." +warning.config.emoji.invalid_image: " dosyasında sorun bulundu - '' emojisi geçersiz bir 'image' argümanı '' kullanıyor." +warning.config.advancement.duplicate: " dosyasında sorun bulundu - Yinelenen ilerleme ''. Diğer dosyalarda aynı yapılandırmanın olup olmadığını kontrol edin." +warning.config.loot_table.missing_pools: " dosyasında sorun bulundu - '', gerekli 'pools' argümanı eksik olan yanlış yapılandırılmış bir ganimet tablosuna sahip." +warning.config.loot_table.invalid_pools_type: " dosyasında sorun bulundu - '', yanlış yapılandırılmış bir ganimet tablosuna sahip, 'pools' bir dizi/harita listesi olmalı, mevcut tür: ''." +warning.config.loot_table.invalid_conditions_type: " dosyasında sorun bulundu - '', yanlış yapılandırılmış bir ganimet tablosuna sahip, 'conditions' bir harita listesi olmalı, mevcut tür: ''." +warning.config.loot_table.invalid_functions_type: " dosyasında sorun bulundu - '', yanlış yapılandırılmış bir ganimet tablosuna sahip, 'functions' bir harita listesi olmalı, mevcut tür: ''." +warning.config.loot_table.invalid_entries_type: " dosyasında sorun bulundu - '', yanlış yapılandırılmış bir ganimet tablosuna sahip, 'entries' bir harita listesi olmalı, mevcut tür: ''." +warning.config.loot_table.function.missing_type: " dosyasında sorun bulundu - '', yanlış yapılandırılmış bir ganimet tablosuna sahip, fonksiyonlardan biri için gerekli 'type' argümanı eksik." +warning.config.loot_table.function.invalid_type: " dosyasında sorun bulundu - '', yanlış yapılandırılmış bir ganimet tablosuna sahip, fonksiyonlardan biri geçersiz bir fonksiyon türü '' kullanıyor." +warning.config.loot_table.function.apply_bonus.missing_enchantment: " dosyasında sorun bulundu - '', yanlış yapılandırılmış bir ganimet tablosuna sahip, 'apply_bonus' fonksiyonu için gerekli 'enchantment' argümanı eksik." +warning.config.loot_table.function.apply_bonus.missing_formula: " dosyasında sorun bulundu - '', yanlış yapılandırılmış bir ganimet tablosuna sahip, 'apply_bonus' fonksiyonu için gerekli 'formula' argümanı eksik." +warning.config.loot_table.function.drop_exp.missing_count: " dosyasında sorun bulundu - '', yanlış yapılandırılmış bir ganimet tablosuna sahip, 'drop_exp' fonksiyonu için gerekli 'count' argümanı eksik." +warning.config.loot_table.function.set_count.missing_count: " dosyasında sorun bulundu - '', yanlış yapılandırılmış bir ganimet tablosuna sahip, 'set_count' fonksiyonu için gerekli 'count' argümanı eksik." +warning.config.loot_table.entry.missing_type: " dosyasında sorun bulundu - '', yanlış yapılandırılmış bir ganimet tablosuna sahip, girişlerden biri için gerekli 'type' argümanı eksik." +warning.config.loot_table.entry.invalid_type: " dosyasında sorun bulundu - '', yanlış yapılandırılmış bir ganimet tablosuna sahip, girişlerden biri geçersiz bir giriş türü '' kullanıyor." +warning.config.loot_table.entry.exp.missing_count: " dosyasında sorun bulundu - '', yanlış yapılandırılmış bir ganimet tablosuna sahip, 'exp' girişi için gerekli 'count' argümanı eksik." +warning.config.loot_table.entry.item.missing_item: " dosyasında sorun bulundu - '', yanlış yapılandırılmış bir ganimet tablosuna sahip, 'item' girişi için gerekli 'item' argümanı eksik." +warning.config.loot_table.condition.missing_type: " dosyasında sorun bulundu - '', yanlış yapılandırılmış bir ganimet tablosuna sahip, koşullardan biri için gerekli 'type' argümanı eksik." +warning.config.loot_table.condition.invalid_type: " dosyasında sorun bulundu - '', yanlış yapılandırılmış bir ganimet tablosuna sahip, koşullardan biri geçersiz bir koşul türü '' kullanıyor." +warning.config.host.missing_type: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - Host için gerekli 'type' argümanı eksik." +warning.config.host.invalid_type: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - Host türü '' geçersiz. Lütfen https://mo-mi.gitbook.io/xiaomomi-plugins/craftengine/plugin-wiki/craftengine/resource-pack/host sayfasını okuyun." +warning.config.host.external.missing_url: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - Harici host için gerekli 'url' argümanı eksik." +warning.config.host.alist.missing_api_url: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - alist host için gerekli 'api-url' argümanı eksik." +warning.config.host.alist.missing_username: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - alist host için gerekli 'username' argümanı veya 'CE_ALIST_USERNAME' ortam değişkeni eksik." +warning.config.host.alist.missing_password: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - alist host için gerekli 'password' argümanı veya 'CE_ALIST_PASSWORD' ortam değişkeni eksik." +warning.config.host.alist.missing_upload_path: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - alist host için gerekli 'upload-path' argümanı eksik." +warning.config.host.dropbox.missing_app_key: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - dropbox host için gerekli 'app-key' argümanı veya 'CE_DROPBOX_APP_KEY' ortam değişkeni eksik." +warning.config.host.dropbox.missing_app_secret: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - dropbox host için gerekli 'app-secret' argümanı veya 'CE_DROPBOX_APP_SECRET' ortam değişkeni eksik." +warning.config.host.dropbox.missing_refresh_token: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - dropbox host için gerekli 'refresh-token' argümanı veya 'CE_DROPBOX_REFRESH_TOKEN' ortam değişkeni eksik." +warning.config.host.dropbox.missing_upload_path: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - dropbox host için gerekli 'upload-path' argümanı eksik." +warning.config.host.lobfile.missing_api_key: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - lobfile host için gerekli 'api-key' argümanı eksik." +warning.config.host.onedrive.missing_client_id: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - onedrive host için gerekli 'client-id' argümanı veya 'CE_ONEDRIVE_CLIENT_ID' ortam değişkeni eksik." +warning.config.host.onedrive.missing_client_secret: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - onedrive host için gerekli 'client-secret' argümanı veya 'CE_ONEDRIVE_CLIENT_SECRET' ortam değişkeni eksik." +warning.config.host.onedrive.missing_refresh_token: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - onedrive host için gerekli 'refresh-token' argümanı veya 'CE_ONEDRIVE_REFRESH_TOKEN' ortam değişkeni eksik." +warning.config.host.onedrive.missing_upload_path: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - onedrive host için gerekli 'upload-path' argümanı eksik." +warning.config.host.s3.missing_endpoint: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - s3 host için gerekli 'endpoint' argümanı eksik." +warning.config.host.s3.missing_bucket: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - s3 host için gerekli 'bucket' argümanı eksik." +warning.config.host.s3.missing_access_key: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - s3 host için gerekli 'access-key-id' argümanı veya 'CE_S3_ACCESS_KEY_ID' ortam değişkeni eksik." +warning.config.host.s3.missing_secret: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - s3 host için gerekli 'access-key-secret' argümanı veya 'CE_S3_ACCESS_KEY_SECRET' ortam değişkeni eksik." +warning.config.host.s3.missing_upload_path: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - s3 host için gerekli 'upload-path' argümanı eksik." +warning.config.host.self.missing_ip: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - self host için gerekli 'ip' argümanı eksik." +warning.config.host.self.invalid_port: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - self host için geçersiz port ''." +warning.config.host.gitlab.missing_url: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - gitlab host için gerekli 'gitlab-url' argümanı eksik." +warning.config.host.gitlab.missing_token: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - gitlab host için gerekli 'access-token' argümanı eksik." +warning.config.host.gitlab.missing_project: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - gitlab host için gerekli 'project-id' argümanı eksik." +warning.config.host.proxy.missing_host: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - proxy için gerekli 'host' argümanı eksik." +warning.config.host.proxy.missing_port: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - proxy için gerekli 'port' argümanı eksik." +warning.config.host.proxy.missing_scheme: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - proxy için gerekli 'scheme' argümanı eksik." +warning.config.host.proxy.invalid: "config.yml dosyasında 'resource-pack.delivery.hosting' bölümünde sorun bulundu - Geçersiz proxy ''." +warning.config.conflict_matcher.missing_type: "config.yml dosyasında 'resource-pack.duplicated-files-handler' bölümünde sorun bulundu - İşleyicilerden biri için gerekli 'type' argümanı eksik." +warning.config.conflict_matcher.invalid_type: "config.yml dosyasında 'resource-pack.duplicated-files-handler' bölümünde sorun bulundu - Terimlerden biri geçersiz bir tür '' kullanıyor." +warning.config.conflict_matcher.exact.missing_path: "config.yml dosyasında 'resource-pack.duplicated-files-handler' bölümünde sorun bulundu - 'exact' eşleştiricisi için gerekli 'path' argümanı eksik." +warning.config.conflict_matcher.contains.missing_path: "config.yml dosyasında 'resource-pack.duplicated-files-handler' bölümünde sorun bulundu - 'contains' eşleştiricisi için gerekli 'path' argümanı eksik." +warning.config.conflict_matcher.filename.missing_name: "config.yml dosyasında 'resource-pack.duplicated-files-handler' bölümünde sorun bulundu - 'filename' eşleştiricisi için gerekli 'path' argümanı eksik." +warning.config.conflict_matcher.pattern.missing_pattern: "config.yml dosyasında 'resource-pack.duplicated-files-handler' bölümünde sorun bulundu - 'pattern' eşleştiricisi için gerekli 'pattern' argümanı eksik." +warning.config.conflict_matcher.parent_prefix.missing_prefix: "config.yml dosyasında 'resource-pack.duplicated-files-handler' bölümünde sorun bulundu - 'parent_path_prefix' eşleştiricisi için gerekli 'prefix' argümanı eksik." +warning.config.conflict_matcher.parent_suffix.missing_suffix: "config.yml dosyasında 'resource-pack.duplicated-files-handler' bölümünde sorun bulundu - 'parent_path_suffix' eşleştiricisi için gerekli 'suffix' argümanı eksik." +warning.config.conflict_matcher.inverted.missing_term: "config.yml dosyasında 'resource-pack.duplicated-files-handler' bölümünde sorun bulundu - 'inverted' eşleştiricisi için gerekli 'term' argümanı eksik." +warning.config.conflict_matcher.all_of.missing_terms: "config.yml dosyasında 'resource-pack.duplicated-files-handler' bölümünde sorun bulundu - 'all_of' eşleştiricisi için gerekli 'terms' argümanı eksik." +warning.config.conflict_matcher.any_of.missing_terms: "config.yml dosyasında 'resource-pack.duplicated-files-handler' bölümünde sorun bulundu - 'any_of' eşleştiricisi için gerekli 'terms' argümanı eksik." +warning.config.conflict_resolution.missing_type: "config.yml dosyasında 'resource-pack.duplicated-files-handler' bölümünde sorun bulundu - Çözümlerden biri için gerekli 'type' argümanı eksik." +warning.config.conflict_resolution.invalid_type: "config.yml dosyasında 'resource-pack.duplicated-files-handler' bölümünde sorun bulundu - Çözümlerden biri geçersiz bir tür '' kullanıyor." \ No newline at end of file diff --git a/bukkit/loader/src/main/resources/translations/zh_cn.yml b/bukkit/loader/src/main/resources/translations/zh_cn.yml index f191e0076..d2e6ed5f9 100644 --- a/bukkit/loader/src/main/resources/translations/zh_cn.yml +++ b/bukkit/loader/src/main/resources/translations/zh_cn.yml @@ -1,7 +1,6 @@ # 别动这个 lang-version: "${lang_version}" -# 命令 exception.invalid_syntax: "无效语法. 正确语法: " exception.invalid_argument: "无效参数. 原因: " exception.invalid_sender: " 不允许执行该命令. 执行者必须是 " @@ -70,6 +69,8 @@ warning.config.type.float: "在文件 发现问题 - 无法加 warning.config.type.double: "在文件 发现问题 - 无法加载 '': 无法将 '' 转换为双精度类型 (选项 '')" warning.config.type.quaternionf: "在文件 发现问题 - 无法加载 '': 无法将 '' 转换为四元数类型 (选项 '')" warning.config.type.vector3f: "在文件 发现问题 - 无法加载 '': 无法将 '' 转换为三维向量类型 (选项 '')" +warning.config.number.missing_type: "在文件 发现问题 - 配置项 '' 缺少数字类型所需的 'type' 参数" +warning.config.number.invalid_type: "在文件 发现问题 - 配置项 '' 使用了无效的数字类型 ''" warning.config.number.missing_argument: "在文件 发现问题 - 配置项 '' 缺少数字参数" warning.config.number.invalid_format: "在文件 发现问题 - 配置项 '' 使用了无效的数字格式 ''" warning.config.number.fixed.missing_value: "在文件 发现问题 - 配置项 '' 缺少 'constant' 数字类型所需的 'value' 参数" @@ -222,6 +223,8 @@ warning.config.block.behavior.leaves.missing_distance: "在文件 在文件 发现问题 - 方块 '' 的 'sapling_block' 行为缺少必需的 'stage' 属性" warning.config.block.behavior.sapling.missing_feature: "在文件 发现问题 - 方块 '' 的 'sapling_block' 行为缺少必需的 'feature' 参数" warning.config.block.behavior.strippable.missing_stripped: "在文件 发现问题 - 方块 '' 的 'strippable_block' 行为缺少必需的 'stripped' 参数" +warning.config.block.event.condition.missing_type: "在文件 - 方块 '' 的事件条件缺少 'type' 参数" +warning.config.block.event.condition.invalid_type: "在文件 - 方块 '' 使用了无效的事件条件类型 ''" warning.config.model.generation.missing_parent: "在文件 发现问题 - 配置项 '' 的 'generation' 段落缺少必需的 'parent' 参数" warning.config.model.generation.conflict: "在文件 发现问题 - 无法为 '' 生成模型 存在多个配置尝试使用相同路径 '' 生成不同的 JSON 模型" warning.config.model.generation.texture.invalid: "在文件 发现问题 - 配置项 '' 的纹理 '' 路径 '' 包含非法字符 请参考 https://zh.minecraft.wiki/w/%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4ID#%E5%90%88%E6%B3%95%E5%AD%97%E7%AC%A6" @@ -247,10 +250,6 @@ warning.config.loot_table.entry.exp.missing_count: "在文件 warning.config.loot_table.entry.item.missing_item: "在文件 发现问题 - '' 的战利品表配置错误 'item' 条目缺少必需的 'item' 参数" warning.config.loot_table.condition.missing_type: "在文件 发现问题 - '' 的战利品表配置错误 某个条件缺少必需的 'type' 参数" warning.config.loot_table.condition.invalid_type: "在文件 发现问题 - '' 的战利品表配置错误 某个条件使用了无效的条件类型 ''" -warning.config.loot_table.condition.table_bonus.missing_enchantment: "在文件 发现问题 - '' 的战利品表配置错误 'table_bonus' 条件缺少必需的 'enchantment' 参数" -warning.config.loot_table.condition.table_bonus.missing_chances: "在文件 发现问题 - '' 的战利品表配置错误 'table_bonus' 条件缺少必需的 'chances' 参数" -warning.config.loot_table.number.missing_type: "在文件 发现问题 - '' 的战利品表配置错误 某个数值缺少必需的 'type' 参数" -warning.config.loot_table.number.invalid_type: "在文件 发现问题 - '' 的战利品表配置错误 某个数值使用了无效的数值类型 ''" warning.config.host.missing_type: "在 config.yml 的 'resource-pack.delivery.hosting' 处发现问题 - 缺少必需的 'type' 参数" warning.config.host.invalid_type: "在 config.yml 的 'resource-pack.delivery.hosting' 处发现问题 - 无效的托管类型 '' 请参考 https://mo-mi.gitbook.io/xiaomomi-plugins/craftengine/plugin-wiki/craftengine/resource-pack/host" warning.config.host.external.missing_url: "在 config.yml 的 'resource-pack.delivery.hosting' 处发现问题 - 外部托管缺少必需的 'url' 参数" diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/CropBlockBehavior.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/CropBlockBehavior.java index f74239a2d..e5681c5fb 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/CropBlockBehavior.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/behavior/CropBlockBehavior.java @@ -157,7 +157,7 @@ public class CropBlockBehavior extends BushBlockBehavior { if (i > maxAge) { i = maxAge; } - FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, immutableBlockState.with(this.ageProperty, i).customBlockState().handle(), UpdateOption.UPDATE_NONE.flags()); + FastNMS.INSTANCE.method$LevelWriter$setBlock(level, pos, immutableBlockState.with(this.ageProperty, i).customBlockState().handle(), UpdateOption.UPDATE_ALL.flags()); if (sendParticles) { world.spawnParticle(ParticleUtils.getParticle("HAPPY_VILLAGER"), x + 0.5, y + 0.5, z + 0.5, 15, 0.25, 0.25, 0.25); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java index 0bb780dd4..9a54e77a1 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/injector/BukkitInjector.java @@ -17,6 +17,7 @@ import net.bytebuddy.implementation.bind.annotation.AllArguments; import net.bytebuddy.implementation.bind.annotation.RuntimeType; import net.bytebuddy.implementation.bind.annotation.SuperCall; import net.bytebuddy.implementation.bind.annotation.This; +import net.bytebuddy.implementation.bytecode.assign.Assigner; import net.bytebuddy.implementation.bytecode.assign.TypeCasting; import net.bytebuddy.implementation.bytecode.member.FieldAccess; import net.bytebuddy.implementation.bytecode.member.MethodReturn; @@ -77,6 +78,7 @@ public class BukkitInjector { private static Class clazz$InjectedPalettedContainer; private static Class clazz$InjectedLevelChunkSection; + private static MethodHandle constructor$InjectedLevelChunkSection; private static VarHandle varHandle$InjectedPalettedContainer$target; @@ -104,6 +106,7 @@ public class BukkitInjector { .name("net.minecraft.world.level.chunk.InjectedPalettedContainer") .implement(InjectedHolder.Palette.class) .defineField("target", Reflections.clazz$PalettedContainer, Visibility.PUBLIC) + .defineField("active", boolean.class, Visibility.PUBLIC) .defineField("cesection", CESection.class, Visibility.PRIVATE) .defineField("cechunk", CEChunk.class, Visibility.PRIVATE) .defineField("cepos", SectionPos.class, Visibility.PRIVATE) @@ -116,6 +119,10 @@ public class BukkitInjector { .intercept(MethodDelegation.to(GetAndSetInterceptor.INSTANCE)) .method(ElementMatchers.named("target")) .intercept(FieldAccessor.ofField("target")) + .method(ElementMatchers.named("setTarget")) + .intercept(FieldAccessor.ofField("target").withAssigner(Assigner.DEFAULT, Assigner.Typing.DYNAMIC)) + .method(ElementMatchers.named("isActive").or(ElementMatchers.named("setActive"))) + .intercept(FieldAccessor.ofField("active")) .method(ElementMatchers.named("ceSection")) .intercept(FieldAccessor.ofField("cesection")) .method(ElementMatchers.named("ceChunk")) @@ -125,13 +132,14 @@ public class BukkitInjector { .make() .load(BukkitInjector.class.getClassLoader()) .getLoaded(); - varHandle$InjectedPalettedContainer$target = Objects.requireNonNull(ReflectionUtils.findVarHandle(clazz$InjectedPalettedContainer, "target", Reflections.clazz$PalettedContainer)); + //varHandle$InjectedPalettedContainer$target = Objects.requireNonNull(ReflectionUtils.findVarHandle(clazz$InjectedPalettedContainer, "target", Reflections.clazz$PalettedContainer)); // Level Chunk Section clazz$InjectedLevelChunkSection = byteBuddy - .subclass(Reflections.clazz$LevelChunkSection) + .subclass(Reflections.clazz$LevelChunkSection, ConstructorStrategy.Default.IMITATE_SUPER_CLASS_OPENING) .name("net.minecraft.world.level.chunk.InjectedLevelChunkSection") .implement(InjectedHolder.Section.class) + .defineField("active", boolean.class, Visibility.PUBLIC) .defineField("cesection", CESection.class, Visibility.PRIVATE) .defineField("cechunk", CEChunk.class, Visibility.PRIVATE) .defineField("cepos", SectionPos.class, Visibility.PRIVATE) @@ -143,10 +151,16 @@ public class BukkitInjector { .intercept(FieldAccessor.ofField("cechunk")) .method(ElementMatchers.named("cePos")) .intercept(FieldAccessor.ofField("cepos")) + .method(ElementMatchers.named("isActive").or(ElementMatchers.named("setActive"))) + .intercept(FieldAccessor.ofField("active")) .make() .load(BukkitInjector.class.getClassLoader()) .getLoaded(); + constructor$InjectedLevelChunkSection = MethodHandles.publicLookup().in(clazz$InjectedLevelChunkSection) + .findConstructor(clazz$InjectedLevelChunkSection, MethodType.methodType(void.class, Reflections.clazz$PalettedContainer, Reflections.clazz$PalettedContainer)) + .asType(MethodType.methodType(Reflections.clazz$LevelChunkSection, Reflections.clazz$PalettedContainer, Reflections.clazz$PalettedContainer)); + // State Predicate DynamicType.Unloaded alwaysTrue = byteBuddy .subclass(Reflections.clazz$StatePredicate) @@ -408,32 +422,50 @@ public class BukkitInjector { try { if (Config.injectionTarget()) { Object container = FastNMS.INSTANCE.field$LevelChunkSection$states(targetSection); - if (!(container instanceof InjectedHolder.Palette)) { + if (!(container instanceof InjectedHolder.Palette holder)) { InjectedHolder.Palette injectedObject; if (Config.fastInjection()) { injectedObject = FastNMS.INSTANCE.createInjectedPalettedContainerHolder(container); } else { injectedObject = (InjectedHolder.Palette) Reflections.UNSAFE.allocateInstance(clazz$InjectedPalettedContainer); - varHandle$InjectedPalettedContainer$target.set(injectedObject, container); + injectedObject.setTarget(container); + //varHandle$InjectedPalettedContainer$target.set(injectedObject, container); } injectedObject.ceChunk(chunk); injectedObject.ceSection(ceSection); injectedObject.cePos(pos); + injectedObject.setActive(true); Reflections.varHandle$PalettedContainer$data.setVolatile(injectedObject, Reflections.varHandle$PalettedContainer$data.get(container)); Reflections.field$LevelChunkSection$states.set(targetSection, injectedObject); + } else { + holder.ceChunk(chunk); + holder.ceSection(ceSection); + holder.cePos(pos); + holder.setActive(true); } } else { - InjectedHolder.Section injectedObject; - if (true) { - injectedObject = FastNMS.INSTANCE.createInjectedLevelChunkSectionHolder(targetSection); + if (!(targetSection instanceof InjectedHolder.Section holder)) { + InjectedHolder.Section injectedObject; + if (Config.fastInjection()) { + injectedObject = FastNMS.INSTANCE.createInjectedLevelChunkSectionHolder(targetSection); + } else { + injectedObject = (InjectedHolder.Section) constructor$InjectedLevelChunkSection.invoke( + FastNMS.INSTANCE.field$LevelChunkSection$states(targetSection), FastNMS.INSTANCE.field$LevelChunkSection$biomes(targetSection)); + } + injectedObject.ceChunk(chunk); + injectedObject.ceSection(ceSection); + injectedObject.cePos(pos); + injectedObject.setActive(true); + callback.accept(injectedObject); + } else { + holder.ceChunk(chunk); + holder.ceSection(ceSection); + holder.cePos(pos); + holder.setActive(true); } - injectedObject.ceChunk(chunk); - injectedObject.ceSection(ceSection); - injectedObject.cePos(pos); - callback.accept(injectedObject); } - } catch (Exception e) { - CraftEngine.instance().logger().severe("Failed to inject chunk section", e); + } catch (Throwable e) { + CraftEngine.instance().logger().severe("Failed to inject chunk section " + pos, e); } } @@ -450,15 +482,17 @@ public class BukkitInjector { if (Config.injectionTarget()) { Object states = FastNMS.INSTANCE.field$LevelChunkSection$states(section); if (states instanceof InjectedHolder.Palette holder) { - try { - Reflections.field$LevelChunkSection$states.set(section, holder.target()); - } catch (ReflectiveOperationException e) { - CraftEngine.instance().logger().severe("Failed to uninject palette", e); - } + holder.setActive(false); +// try { +// Reflections.field$LevelChunkSection$states.set(section, holder.target()); +// } catch (ReflectiveOperationException e) { +// CraftEngine.instance().logger().severe("Failed to uninject palette", e); +// } } } else { if (section instanceof InjectedHolder.Section holder) { - return FastNMS.INSTANCE.constructor$LevelChunkSection(holder); + holder.setActive(false); + //return FastNMS.INSTANCE.constructor$LevelChunkSection(holder); } } return section; @@ -730,7 +764,9 @@ public class BukkitInjector { int z = (int) args[2]; Object newState = args[3]; Object previousState = superMethod.call(); - compareAndUpdateBlockState(x, y, z, newState, previousState, holder); + if (holder.isActive()) { + compareAndUpdateBlockState(x, y, z, newState, previousState, holder); + } return previousState; } } @@ -747,7 +783,9 @@ public class BukkitInjector { int z = (int) args[2]; Object newState = args[3]; Object previousState = FastNMS.INSTANCE.method$PalettedContainer$getAndSet(targetStates, x, y, z, newState); - compareAndUpdateBlockState(x, y, z, newState, previousState, holder); + if (holder.isActive()) { + compareAndUpdateBlockState(x, y, z, newState, previousState, holder); + } return previousState; } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index 9858ea30a..a88d663ec 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -59,6 +59,7 @@ import org.bukkit.inventory.PlayerInventory; import org.bukkit.persistence.PersistentDataType; import org.bukkit.util.RayTraceResult; import org.bukkit.util.Vector; +import org.jetbrains.annotations.Nullable; import java.lang.reflect.InvocationTargetException; import java.nio.charset.StandardCharsets; @@ -1484,7 +1485,7 @@ public class PacketConsumers { if (state == null) return; Key itemId = state.settings().itemId(); if (itemId == null) return; - pickItem(player, itemId); + pickItem(player, itemId, pos, null); } // 1.21.4+ @@ -1523,18 +1524,24 @@ public class PacketConsumers { private static void handlePickItemFromEntityOnMainThread(Player player, LoadedFurniture furniture) throws Exception { Key itemId = furniture.config().settings().itemId(); if (itemId == null) return; - pickItem(player, itemId); + pickItem(player, itemId, null, FastNMS.INSTANCE.method$CraftEntity$getHandle(furniture.baseEntity())); } - private static void pickItem(Player player, Key itemId) throws IllegalAccessException, InvocationTargetException { + private static void pickItem(Player player, Key itemId, @Nullable Object blockPos, @Nullable Object entity) throws IllegalAccessException, InvocationTargetException { ItemStack itemStack = BukkitCraftEngine.instance().itemManager().buildCustomItemStack(itemId, BukkitCraftEngine.instance().adapt(player)); if (itemStack == null) { CraftEngine.instance().logger().warn("Item: " + itemId + " is not a valid item"); return; } assert Reflections.method$ServerGamePacketListenerImpl$tryPickItem != null; - Reflections.method$ServerGamePacketListenerImpl$tryPickItem.invoke( - Reflections.field$ServerPlayer$connection.get(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player)), FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack)); + if (VersionHelper.isOrAbove1_21_5()) { + Reflections.method$ServerGamePacketListenerImpl$tryPickItem.invoke( + Reflections.field$ServerPlayer$connection.get(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player)), + FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack), blockPos, entity, true); + } else { + Reflections.method$ServerGamePacketListenerImpl$tryPickItem.invoke( + Reflections.field$ServerPlayer$connection.get(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player)), FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack)); + } } public static final BiConsumer ADD_ENTITY_BYTEBUFFER = (user, event) -> { diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java index 440a93116..9023eef48 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java @@ -4967,10 +4967,10 @@ public class Reflections { public static final Method method$BonemealableBlock$isValidBonemealTarget = requireNonNull( VersionHelper.isOrAbove1_20_2() ? - ReflectionUtils.getMethod( + ReflectionUtils.getInstanceMethod( clazz$BonemealableBlock, boolean.class, clazz$LevelReader, clazz$BlockPos, clazz$BlockState ) : - ReflectionUtils.getMethod( + ReflectionUtils.getInstanceMethod( clazz$BonemealableBlock, boolean.class, clazz$LevelReader, clazz$BlockPos, clazz$BlockState, boolean.class ) ); @@ -5034,6 +5034,10 @@ public class Reflections { ); public static final Method method$ServerGamePacketListenerImpl$tryPickItem = + VersionHelper.isOrAbove1_21_5() ? + ReflectionUtils.getDeclaredMethod( + clazz$ServerGamePacketListenerImpl, void.class, clazz$ItemStack, clazz$BlockPos, clazz$Entity, boolean.class + ) : ReflectionUtils.getDeclaredMethod( clazz$ServerGamePacketListenerImpl, void.class, clazz$ItemStack ); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java index ffc0b77bf..d527a0ab7 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/world/BukkitWorldManager.java @@ -266,27 +266,24 @@ public class BukkitWorldManager implements WorldManager, Listener { if (ceChunk != null) { if (ceChunk.dirty()) { try { - world.worldDataStorage().writeChunkAt(pos, ceChunk, false); + this.plugin.debug(() -> "[Dirty Chunk]" + pos + " unloaded"); + world.worldDataStorage().writeChunkAt(pos, ceChunk); ceChunk.setDirty(false); } catch (IOException e) { this.plugin.logger().warn("Failed to write chunk tag at " + chunk.getX() + " " + chunk.getZ(), e); } } - if (Config.restoreVanillaBlocks()) { - boolean unsaved = false; - CESection[] ceSections = ceChunk.sections(); - Object worldServer = FastNMS.INSTANCE.field$CraftChunk$worldServer(chunk); - Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(worldServer); - Object levelChunk = FastNMS.INSTANCE.method$ServerChunkCache$getChunkAtIfLoadedMainThread(chunkSource, chunk.getX(), chunk.getZ()); - Object[] sections = FastNMS.INSTANCE.method$ChunkAccess$getSections(levelChunk); - for (int i = 0; i < ceSections.length; i++) { - CESection ceSection = ceSections[i]; - Object section = sections[i]; - Object uninjectedSection = BukkitInjector.uninjectLevelChunkSection(section); - if (uninjectedSection != section) { - sections[i] = uninjectedSection; - section = uninjectedSection; - } + boolean unsaved = false; + CESection[] ceSections = ceChunk.sections(); + Object worldServer = FastNMS.INSTANCE.field$CraftChunk$worldServer(chunk); + Object chunkSource = FastNMS.INSTANCE.method$ServerLevel$getChunkSource(worldServer); + Object levelChunk = FastNMS.INSTANCE.method$ServerChunkCache$getChunkAtIfLoadedMainThread(chunkSource, chunk.getX(), chunk.getZ()); + Object[] sections = FastNMS.INSTANCE.method$ChunkAccess$getSections(levelChunk); + for (int i = 0; i < ceSections.length; i++) { + CESection ceSection = ceSections[i]; + Object section = sections[i]; + BukkitInjector.uninjectLevelChunkSection(section); + if (Config.restoreVanillaBlocks()) { if (!ceSection.statesContainer().isEmpty()) { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { @@ -301,9 +298,9 @@ public class BukkitWorldManager implements WorldManager, Listener { } } } - if (unsaved && !FastNMS.INSTANCE.method$LevelChunk$isUnsaved(levelChunk)) { - FastNMS.INSTANCE.method$LevelChunk$markUnsaved(levelChunk); - } + } + if (unsaved && !FastNMS.INSTANCE.method$LevelChunk$isUnsaved(levelChunk)) { + FastNMS.INSTANCE.method$LevelChunk$markUnsaved(levelChunk); } ceChunk.unload(); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/UpdateOption.java b/core/src/main/java/net/momirealms/craftengine/core/block/UpdateOption.java index 98286d2ea..ae1c652ad 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/UpdateOption.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/UpdateOption.java @@ -14,6 +14,10 @@ public class UpdateOption { return flags; } + public static Builder builder() { + return new Builder(); + } + public static class Builder { private int flags; diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java index e595457bf..fde4746d5 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/config/Config.java @@ -101,7 +101,7 @@ public class Config { protected boolean chunk_system$restore_vanilla_blocks_on_chunk_unload; protected boolean chunk_system$restore_custom_blocks_on_chunk_load; protected boolean chunk_system$sync_custom_blocks_on_chunk_load; - protected int chunk_system$delay_serialization; + protected boolean chunk_system$cache_system; protected boolean chunk_system$injection$use_fast_method; protected boolean chunk_system$injection$target; @@ -274,7 +274,7 @@ public class Config { chunk_system$restore_vanilla_blocks_on_chunk_unload = config.getBoolean("chunk-system.restore-vanilla-blocks-on-chunk-unload", true); chunk_system$restore_custom_blocks_on_chunk_load = config.getBoolean("chunk-system.restore-custom-blocks-on-chunk-load", true); chunk_system$sync_custom_blocks_on_chunk_load = config.getBoolean("chunk-system.sync-custom-blocks-on-chunk-load", false); - chunk_system$delay_serialization = config.getInt("chunk-system.delay-serialization", 20); + chunk_system$cache_system = config.getBoolean("chunk-system.cache-system", true); chunk_system$injection$use_fast_method = config.getBoolean("chunk-system.injection.use-fast-method", false); if (firstTime) { chunk_system$injection$target = config.getEnum("chunk-system.injection.target", InjectionTarget.class, InjectionTarget.PALETTE) == InjectionTarget.PALETTE; @@ -699,8 +699,8 @@ public class Config { return instance.furniture$collision_entity_type; } - public static int delaySerialization() { - return instance.chunk_system$delay_serialization; + public static boolean enableChunkCache() { + return instance.chunk_system$cache_system; } public static boolean fastInjection() { diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/number/NumberProviders.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/number/NumberProviders.java index 2d73ce359..5d5d609a4 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/context/number/NumberProviders.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/context/number/NumberProviders.java @@ -43,11 +43,11 @@ public class NumberProviders { } public static NumberProvider fromMap(Map map) { - String type = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("type"), "warning.config.loot_table.number.missing_type"); + String type = ResourceConfigUtils.requireNonEmptyStringOrThrow(map.get("type"), "warning.config.number.missing_type"); Key key = Key.withDefaultNamespace(type, Key.DEFAULT_NAMESPACE); Factory factory = BuiltInRegistries.NUMBER_PROVIDER_FACTORY.getValue(key); if (factory == null) { - throw new LocalizedResourceConfigException("warning.config.loot_table.number.invalid_type", type); + throw new LocalizedResourceConfigException("warning.config.number.invalid_type", type); } return factory.create(map); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/ReflectionUtils.java b/core/src/main/java/net/momirealms/craftengine/core/util/ReflectionUtils.java index f83302bab..04a9d4baf 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/ReflectionUtils.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/ReflectionUtils.java @@ -246,6 +246,27 @@ public class ReflectionUtils { return null; } + @Nullable + public static Method getInstanceMethod(final Class clazz, Class returnType, final Class... parameterTypes) { + outer: + for (Method method : clazz.getMethods()) { + if (method.getParameterCount() != parameterTypes.length) { + continue; + } + if (Modifier.isStatic(method.getModifiers())) { + continue; + } + Class[] types = method.getParameterTypes(); + for (int i = 0; i < types.length; i++) { + if (types[i] != parameterTypes[i]) { + continue outer; + } + } + if (returnType.isAssignableFrom(method.getReturnType())) return method; + } + return null; + } + @Nullable public static Method getDeclaredMethod(final Class clazz, Class returnType, final String[] possibleMethodNames, final Class... parameterTypes) { outer: diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/CEWorld.java b/core/src/main/java/net/momirealms/craftengine/core/world/CEWorld.java index 51bc86577..e36abc7ce 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/CEWorld.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/CEWorld.java @@ -49,7 +49,7 @@ public abstract class CEWorld { for (Map.Entry entry : this.loadedChunkMap.entrySet()) { CEChunk chunk = entry.getValue(); if (chunk.dirty()) { - worldDataStorage.writeChunkAt(new ChunkPos(entry.getKey()), chunk, true); + worldDataStorage.writeChunkAt(new ChunkPos(entry.getKey()), chunk); chunk.setDirty(false); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/ChunkPos.java b/core/src/main/java/net/momirealms/craftengine/core/world/ChunkPos.java index 6962e334b..115dd689a 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/ChunkPos.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/ChunkPos.java @@ -68,4 +68,17 @@ public class ChunkPos { public static long asLong(int chunkX, int chunkZ) { return (long) chunkX & 4294967295L | ((long) chunkZ & 4294967295L) << 32; } + + @Override + public final boolean equals(Object o) { + if (!(o instanceof ChunkPos chunkPos)) return false; + return x == chunkPos.x && z == chunkPos.z; + } + + @Override + public int hashCode() { + int result = x; + result = 31 * result + z; + return result; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/InjectedHolder.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/InjectedHolder.java index a625a0a47..4287019e6 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/InjectedHolder.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/InjectedHolder.java @@ -4,6 +4,10 @@ import net.momirealms.craftengine.core.world.SectionPos; public interface InjectedHolder { + boolean isActive(); + + void setActive(boolean active); + CESection ceSection(); void ceSection(CESection section); @@ -22,5 +26,7 @@ public interface InjectedHolder { interface Palette extends InjectedHolder { Object target(); + + void setTarget(Object target); } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/CachedStorage.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/CachedStorage.java new file mode 100644 index 000000000..9cc9d5d5e --- /dev/null +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/CachedStorage.java @@ -0,0 +1,53 @@ +package net.momirealms.craftengine.core.world.chunk.storage; + +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.Scheduler; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.world.CEWorld; +import net.momirealms.craftengine.core.world.ChunkPos; +import net.momirealms.craftengine.core.world.chunk.CEChunk; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +public class CachedStorage implements WorldDataStorage { + private final T storage; + private final Cache chunkCache; + + public CachedStorage(T storage) { + this.storage = storage; + this.chunkCache = Caffeine.newBuilder() + .executor(CraftEngine.instance().scheduler().async()) + .scheduler(Scheduler.systemScheduler()) + .expireAfterAccess(30, TimeUnit.SECONDS) + .build(); + } + + @Override + public @NotNull CEChunk readChunkAt(@NotNull CEWorld world, @NotNull ChunkPos pos) throws IOException { + CEChunk chunk = this.chunkCache.getIfPresent(pos); + if (chunk != null) { + return chunk; + } + chunk = this.storage.readChunkAt(world, pos); + this.chunkCache.put(pos, chunk); + return chunk; + } + + @Override + public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk) throws IOException { + this.storage.writeChunkAt(pos, chunk); + } + + @Override + public void close() throws IOException { + this.storage.close(); + } + + @Override + public void flush() throws IOException { + this.storage.flush(); + } +} \ No newline at end of file diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultRegionFileStorage.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultRegionFileStorage.java index 132bc699f..bfeef7a58 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultRegionFileStorage.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultRegionFileStorage.java @@ -147,7 +147,7 @@ public class DefaultRegionFileStorage implements WorldDataStorage { } @Override - public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk, boolean immediately) throws IOException { + public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk) throws IOException { CompoundTag nbt = DefaultChunkSerializer.serialize(chunk); writeChunkTagAt(pos, nbt); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultStorageAdaptor.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultStorageAdaptor.java index 401ed6880..6b669241f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultStorageAdaptor.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DefaultStorageAdaptor.java @@ -9,8 +9,8 @@ public class DefaultStorageAdaptor implements StorageAdaptor { @Override public @NotNull WorldDataStorage adapt(@NotNull World world) { - if (Config.delaySerialization() > 0) { - return new DelayedDefaultRegionFileStorage(world.directory().resolve(CEWorld.REGION_DIRECTORY), Config.delaySerialization()); + if (Config.enableChunkCache()) { + return new CachedStorage<>(new DefaultRegionFileStorage(world.directory().resolve(CEWorld.REGION_DIRECTORY))); } else { return new DefaultRegionFileStorage(world.directory().resolve(CEWorld.REGION_DIRECTORY)); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DelayedDefaultRegionFileStorage.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DelayedDefaultRegionFileStorage.java deleted file mode 100644 index f711fbbb3..000000000 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/DelayedDefaultRegionFileStorage.java +++ /dev/null @@ -1,85 +0,0 @@ -package net.momirealms.craftengine.core.world.chunk.storage; - -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.Caffeine; -import com.github.benmanes.caffeine.cache.RemovalCause; -import net.momirealms.craftengine.core.plugin.CraftEngine; -import net.momirealms.craftengine.core.world.CEWorld; -import net.momirealms.craftengine.core.world.ChunkPos; -import net.momirealms.craftengine.core.world.chunk.CEChunk; -import org.jetbrains.annotations.NotNull; - -import java.io.IOException; -import java.nio.channels.ClosedChannelException; -import java.nio.file.Path; -import java.util.concurrent.TimeUnit; - -public class DelayedDefaultRegionFileStorage extends DefaultRegionFileStorage { - private final Cache chunkCache; - private boolean isClosed; - - public DelayedDefaultRegionFileStorage(Path directory, int time) { - super(directory); - this.chunkCache = Caffeine.newBuilder() - .expireAfterWrite(time, TimeUnit.SECONDS) - .removalListener((ChunkPos key, CEChunk value, RemovalCause cause) -> { - if (key == null || value == null || isClosed) { - return; - } - if (cause == RemovalCause.EXPIRED || cause == RemovalCause.SIZE) { - try { - super.writeChunkAt(key, value, true); - } catch (ClosedChannelException e) { - if (this.isClosed) { - return; - } - CraftEngine.instance().logger().warn("Failed to write chunk at " + key, e); - } catch (IOException e) { - CraftEngine.instance().logger().warn("Failed to write chunk at " + key, e); - } - } - }) - .build(); - } - - @Override - public @NotNull CEChunk readChunkAt(@NotNull CEWorld world, @NotNull ChunkPos pos) throws IOException { - CEChunk chunk = this.chunkCache.asMap().remove(pos); - if (chunk != null) { - return chunk; - } - return super.readChunkAt(world, pos); - } - - @Override - public void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk, boolean immediately) throws IOException { - if (immediately) { - super.writeChunkAt(pos, chunk, true); - return; - } - if (chunk.isEmpty()) { - super.writeChunkTagAt(pos, null); - return; - } - this.chunkCache.put(pos, chunk); - } - - @Override - public synchronized void close() throws IOException { - this.isClosed = true; - this.saveCache(); - this.chunkCache.cleanUp(); - super.close(); - } - - private void saveCache() { - try { - for (var chunk : this.chunkCache.asMap().entrySet()) { - super.writeChunkAt(chunk.getKey(), chunk.getValue(), true); - } - } catch (IOException e) { - CraftEngine.instance().logger().warn("Failed to save chunks", e); - } - this.chunkCache.invalidateAll(); - } -} \ No newline at end of file diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/RegionFile.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/RegionFile.java index b50452bae..0ee384791 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/RegionFile.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/RegionFile.java @@ -309,9 +309,6 @@ public class RegionFile implements AutoCloseable { } public void clear(ChunkPos pos) throws IOException { - if (!this.fileChannel.isOpen()) { - throw new ClosedChannelException(); - } int chunkLocation = RegionFile.getChunkLocation(pos); int sectorInfo = this.sectorInfo.get(chunkLocation); if (sectorInfo != INFO_NOT_PRESENT) { @@ -325,9 +322,6 @@ public class RegionFile implements AutoCloseable { @SuppressWarnings("ResultOfMethodCallIgnored") protected synchronized void write(ChunkPos pos, ByteBuffer buf) throws IOException { - if (!this.fileChannel.isOpen()) { - throw new ClosedChannelException(); - } // get old offset info int offsetIndex = RegionFile.getChunkLocation(pos); int previousSectorInfo = this.sectorInfo.get(offsetIndex); diff --git a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/WorldDataStorage.java b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/WorldDataStorage.java index b3b4dd47d..bd44492a9 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/WorldDataStorage.java +++ b/core/src/main/java/net/momirealms/craftengine/core/world/chunk/storage/WorldDataStorage.java @@ -12,7 +12,7 @@ public interface WorldDataStorage { @NotNull CEChunk readChunkAt(@NotNull CEWorld world, @NotNull ChunkPos pos) throws IOException; - void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk, boolean immediately) throws IOException; + void writeChunkAt(@NotNull ChunkPos pos, @NotNull CEChunk chunk) throws IOException; void flush() throws IOException; diff --git a/gradle.properties b/gradle.properties index 7d1d6d3f4..f57da2123 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.53-beta.6 +project_version=0.0.53 config_version=32 lang_version=12 project_group=net.momirealms @@ -50,7 +50,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.4 anti_grief_version=0.15 -nms_helper_version=0.65.12 +nms_helper_version=0.65.15 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.31.23