From 304295050728b977366c39f7e4c07c957d8aacac Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sun, 22 Sep 2024 13:13:07 +0100 Subject: [PATCH 01/39] Update Cobalt to add math.atan(y, x) support --- doc/reference/feature_compat.md | 2 +- gradle/libs.versions.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/reference/feature_compat.md b/doc/reference/feature_compat.md index 72f9b18d81..1fc50c355e 100644 --- a/doc/reference/feature_compat.md +++ b/doc/reference/feature_compat.md @@ -81,7 +81,7 @@ compatibility for these newer versions. | `string.dump` strip argument | ✔ | | | `string.pack`/`string.unpack`/`string.packsize` | ✔ | | | `table.move` | ✔ | | -| `math.atan2` -> `math.atan` | ❌ | | +| `math.atan2` -> `math.atan` | 🔶 | `math.atan` supports its two argument form. | | Removed `math.frexp`, `math.ldexp`, `math.pow`, `math.cosh`, `math.sinh`, `math.tanh` | ❌ | | | `math.maxinteger`/`math.mininteger` | ❌ | | | `math.tointeger` | ❌ | | diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ac6263d683..a4e1ad4be0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -26,7 +26,7 @@ slf4j = "2.0.1" asm = "9.6" autoService = "1.1.1" checkerFramework = "3.42.0" -cobalt = "0.9.3" +cobalt = "0.9.4" commonsCli = "1.6.0" jetbrainsAnnotations = "24.1.0" jsr305 = "3.0.2" From e9aceca1de0283ff7830d82d8f14875c881007fe Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sun, 22 Sep 2024 13:51:11 +0100 Subject: [PATCH 02/39] Add a helper class for working with attached computers One of the easiest things to mess up with writing a custom peripheral is handling attached peripherals. IPeripheral.{attach,detach} are called from multiple threads, so naive implementations that just store computers in a set/list will at some point throw a CME. Historically I've suggested using a concurrent collection (i.e. ConcurrentHashMap). While this solves the problems of CMEs, it still has some flaws. If a computer is detached while iterating over the collection, the iterator will still yield the now-detached peripheral, causing usages of that computer (e.g. queueEvent) to throw an exception. The only fix here is to use a lock when updating and iterating over the collection. This does come with some risks, but I think they are not too serious: - Lock contention: Contention is relatively rare in general (as peripheral attach/detach is not especially frequent). If we do see contention, both iteration and update actions are cheap, so I would not expect the other thread to be blocked for a significant time. - Deadlocks: One could imagine an implementation if IComputerAccess that holds a lock both when detaching a peripheral and inside queueEvent. If we queue an event on one thread, and try to detach on the other, we could see a deadlock: Thread 1 | Thread 2 ---------------------------------------------------------- AttachedComputerSet.queueEvent | MyModem.detach (take lock #1) | (take lock #2) -> MyModem.queueEvent | AttachedComputerSet.remove (wait on lock #2) | (wait on lock #1) Such code would have been broken already (some peripherals already use locks), so I'm fairly sure we've fixed this in CC. But definitely something to watch out for. Anyway, the long and short of it: - Add a new AttachedComputerSet that can be used to track the computers attached to a peripheral. We also mention this in the attach/detach docs, to hopefully make it a little more obvoius. - Update speakers and monitors to use this new class. --- .../monitor/MonitorBlockEntity.java | 8 +- .../peripheral/speaker/SpeakerPeripheral.java | 23 ++-- .../api/peripheral/AttachedComputerSet.java | 129 ++++++++++++++++++ .../api/peripheral/IPeripheral.java | 10 +- 4 files changed, 147 insertions(+), 23 deletions(-) create mode 100644 projects/core-api/src/main/java/dan200/computercraft/api/peripheral/AttachedComputerSet.java diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlockEntity.java index ef12d415df..928590b492 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlockEntity.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlockEntity.java @@ -6,6 +6,7 @@ import com.google.common.annotations.VisibleForTesting; import dan200.computercraft.annotations.ForgeOverride; +import dan200.computercraft.api.peripheral.AttachedComputerSet; import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.core.terminal.Terminal; @@ -25,9 +26,6 @@ import org.slf4j.LoggerFactory; import javax.annotation.Nullable; -import java.util.Collections; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; public class MonitorBlockEntity extends BlockEntity { @@ -53,7 +51,7 @@ public class MonitorBlockEntity extends BlockEntity { private @Nullable ClientMonitor clientMonitor; private @Nullable MonitorPeripheral peripheral; - private final Set computers = Collections.newSetFromMap(new ConcurrentHashMap<>()); + private final AttachedComputerSet computers = new AttachedComputerSet(); private boolean needsUpdate = false; private boolean needsValidating = false; @@ -487,7 +485,7 @@ private void eachComputer(Consumer fun) { var monitor = getLoadedMonitor(x, y).getMonitor(); if (monitor == null) continue; - for (var computer : monitor.computers) fun.accept(computer); + computers.forEach(fun); } } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java index 96405f1d98..54b8d6e074 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java @@ -4,11 +4,11 @@ package dan200.computercraft.shared.peripheral.speaker; -import com.google.errorprone.annotations.concurrent.GuardedBy; import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.lua.LuaTable; +import dan200.computercraft.api.peripheral.AttachedComputerSet; import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.core.util.Nullability; @@ -33,7 +33,10 @@ import net.minecraft.world.level.block.state.properties.NoteBlockInstrument; import javax.annotation.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; import static dan200.computercraft.api.lua.LuaValues.checkFinite; @@ -60,7 +63,7 @@ public abstract class SpeakerPeripheral implements IPeripheral { public static final int SAMPLE_RATE = 48000; private final UUID source = UUID.randomUUID(); - private final @GuardedBy("computers") Set computers = new HashSet<>(); + private final AttachedComputerSet computers = new AttachedComputerSet(); private long clock = 0; private long lastPositionTime; @@ -140,11 +143,7 @@ public void update() { syncedPosition(position); // And notify computers that we have space for more audio. - synchronized (computers) { - for (var computer : computers) { - computer.queueEvent("speaker_audio_empty", computer.getAttachmentName()); - } - } + computers.forEach(c -> c.queueEvent("speaker_audio_empty", c.getAttachmentName())); } // Push position updates to any speakers which have ever played a note, @@ -353,16 +352,12 @@ private void syncedPosition(SpeakerPosition position) { @Override public void attach(IComputerAccess computer) { - synchronized (computers) { - computers.add(computer); - } + computers.add(computer); } @Override public void detach(IComputerAccess computer) { - synchronized (computers) { - computers.remove(computer); - } + computers.remove(computer); } static double clampVolume(double volume) { diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/AttachedComputerSet.java b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/AttachedComputerSet.java new file mode 100644 index 0000000000..aef0ec0354 --- /dev/null +++ b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/AttachedComputerSet.java @@ -0,0 +1,129 @@ +// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 + +package dan200.computercraft.api.peripheral; + +import javax.annotation.Nullable; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.function.Consumer; + +/** + * A thread-safe collection of computers. + *

+ * This collection is intended to be used by peripherals that need to maintain a set of all attached computers. + *

+ * It is recommended to use over Java's built-in concurrent collections (e.g. {@link CopyOnWriteArraySet} or + * {@link ConcurrentHashMap}), as {@link AttachedComputerSet} ensures that computers cannot be accessed after they are + * detached, guaranteeing that {@link NotAttachedException}s will not be thrown. + *

+ * To ensure this, {@link AttachedComputerSet} is not directly iterable, as we cannot ensure that computers are not + * detached while the iterator is running (and so trying to use the computer would error). Instead, computers should be + * looped over using {@link #forEach(Consumer)}. + * + *

Example

+ * + *
{@code
+ * public class MyPeripheral implements IPeripheral {
+ *     private final AttachedComputerSet computers = new ComputerCollection();
+ *
+ *     @Override
+ *     public void attach(IComputerAccess computer) {
+ *         computers.add(computer);
+ *     }
+ *
+ *     @Override
+ *     public void detach(IComputerAccess computer) {
+ *         computers.remove(computer);
+ *     }
+ * }
+ * }
+ * + * @see IComputerAccess + * @see IPeripheral#attach(IComputerAccess) + * @see IPeripheral#detach(IComputerAccess) + */ +public final class AttachedComputerSet { + private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + private final Set computers = new HashSet<>(0); + + /** + * Add a computer to this collection of computers. This should be called from + * {@link IPeripheral#attach(IComputerAccess)}. + * + * @param computer The computer to add. + */ + public void add(IComputerAccess computer) { + lock.writeLock().lock(); + try { + computers.add(computer); + } finally { + lock.writeLock().unlock(); + } + } + + /** + * Remove a computer from this collection of computers. This should be called from + * {@link IPeripheral#detach(IComputerAccess)}. + * + * @param computer The computer to remove. + */ + public void remove(IComputerAccess computer) { + lock.writeLock().lock(); + try { + computers.remove(computer); + } finally { + lock.writeLock().unlock(); + } + } + + /** + * Apply an action to each computer in this collection. + * + * @param action The action to apply. + */ + public void forEach(Consumer action) { + lock.readLock().lock(); + try { + computers.forEach(action); + } finally { + lock.readLock().unlock(); + } + } + + /** + * {@linkplain IComputerAccess#queueEvent(String, Object...) Queue an event} on all computers. + * + * @param event The name of the event to queue. + * @param arguments The arguments for this event. + * @see IComputerAccess#queueEvent(String, Object...) + */ + public void queueEvent(String event, @Nullable Object... arguments) { + forEach(c -> c.queueEvent(event, arguments)); + } + + /** + * Determine if this collection contains any computers. + *

+ * This method is primarily intended for presentation purposes (such as rendering an icon in the UI if a computer + * is attached to your peripheral). Due to the multi-threaded nature of peripherals, it is not recommended to guard + * any logic behind this check. + *

+ * For instance, {@code if(computers.hasComputers()) computers.queueEvent("foo");} contains a race condition, as + * there's no guarantee that any computers are still attached within the body of the if statement. + * + * @return Whether this collection is non-empty. + */ + public boolean hasComputers() { + lock.readLock().lock(); + try { + return !computers.isEmpty(); + } finally { + lock.readLock().unlock(); + } + } +} diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IPeripheral.java b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IPeripheral.java index ca3123a61a..3d96075a8b 100644 --- a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IPeripheral.java +++ b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IPeripheral.java @@ -48,8 +48,9 @@ default Set getAdditionalTypes() { * {@code peripheral.call()}. This method can be used to keep track of which computers are attached to the * peripheral, or to take action when attachment occurs. *

- * Be aware that will be called from both the server thread and ComputerCraft Lua thread, and so must be thread-safe - * and reentrant. + * Be aware that may be called from both the server thread and ComputerCraft Lua thread, and so must be thread-safe + * and reentrant. If you need to store a list of attached computers, it is recommended you use a + * {@link AttachedComputerSet}. * * @param computer The interface to the computer that is being attached. Remember that multiple computers can be * attached to a peripheral at once. @@ -68,8 +69,9 @@ default void attach(IComputerAccess computer) { * This method can be used to keep track of which computers are attached to the peripheral, or to take action when * detachment occurs. *

- * Be aware that this will be called from both the server and ComputerCraft Lua thread, and must be thread-safe - * and reentrant. + * Be aware that this may be called from both the server and ComputerCraft Lua thread, and must be thread-safe + * and reentrant. If you need to store a list of attached computers, it is recommended you use a + * {@link AttachedComputerSet}. * * @param computer The interface to the computer that is being detached. Remember that multiple computers can be * attached to a peripheral at once. From 86e2f92493968fd89de1d72ea725c1de36db3a7d Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sat, 28 Sep 2024 10:15:07 +0100 Subject: [PATCH 03/39] Add Turkish language mapping --- crowdin.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/crowdin.yml b/crowdin.yml index 1f86638a31..68accea61b 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -21,6 +21,7 @@ files: ru: ru_ru # Russian sv-SE: sv_se # Sweedish tok: tok # Toki Pona + tr: tr_tr # Turkish uk: uk_ua # Ukraine vi: vi_vn # Vietnamese zh-CN: zh_cn # Chinese Simplified From a70baf0d742c077852889935990e64d68dafaed9 Mon Sep 17 00:00:00 2001 From: RuyaSavascisi Date: Sat, 28 Sep 2024 15:03:33 +0100 Subject: [PATCH 04/39] Add Turkish translation --- .../assets/computercraft/lang/tr_tr.json | 237 ++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 projects/common/src/main/resources/assets/computercraft/lang/tr_tr.json diff --git a/projects/common/src/main/resources/assets/computercraft/lang/tr_tr.json b/projects/common/src/main/resources/assets/computercraft/lang/tr_tr.json new file mode 100644 index 0000000000..776440a906 --- /dev/null +++ b/projects/common/src/main/resources/assets/computercraft/lang/tr_tr.json @@ -0,0 +1,237 @@ +{ + "argument.computercraft.argument_expected": "Beklenen Argüman", + "argument.computercraft.computer.distance": "Varlığa olan mesafe", + "argument.computercraft.computer.family": "Bilgisayar ailesi", + "argument.computercraft.computer.id": "Bilgisayar Kimliği", + "argument.computercraft.computer.instance": "Benzersiz örnek kimliği", + "argument.computercraft.computer.label": "Bilgisayar etiketi", + "argument.computercraft.computer.many_matching": "Birden fazla bilgisayar eşleşiyor '%s' (örnekler %s)", + "argument.computercraft.computer.no_matching": "Eşleşen bilgisayar yok '%s'", + "argument.computercraft.tracking_field.no_field": "Bilinmeyen alan '%s'", + "argument.computercraft.unknown_computer_family": "Bilinmeyen bilgisayar ailesi '%s'", + "block.computercraft.cable": "Ağ Kablosu", + "block.computercraft.computer_advanced": "Gelişmiş Bilgisayar", + "block.computercraft.computer_command": "Komut Bilgisayarı", + "block.computercraft.computer_normal": "Bilgisayar", + "block.computercraft.disk_drive": "Disk Sürücüsü", + "block.computercraft.monitor_advanced": "Gelişmiş Monitör", + "block.computercraft.monitor_normal": "Monitör", + "block.computercraft.printer": "Yazıcı", + "block.computercraft.speaker": "Hoparlör", + "block.computercraft.turtle_advanced": "Gelişmiş Kaplumbağa", + "block.computercraft.turtle_advanced.upgraded": "Gelişmiş %s Kaplumbağa", + "block.computercraft.turtle_advanced.upgraded_twice": "Gelişmiş %s %s Kaplumbağa", + "block.computercraft.turtle_normal": "Kaplumbağa", + "block.computercraft.turtle_normal.upgraded": "%s Kaplumbağa", + "block.computercraft.turtle_normal.upgraded_twice": "%s %s Kaplumbağa", + "block.computercraft.wired_modem": "Kablolu Modem", + "block.computercraft.wired_modem_full": "Kablolu Modem", + "block.computercraft.wireless_modem_advanced": "Ender Modem", + "block.computercraft.wireless_modem_normal": "Kablosuz Modem", + "chat.computercraft.wired_modem.peripheral_connected": "Çevre birimi \"%s\" ağa bağlandı", + "chat.computercraft.wired_modem.peripheral_disconnected": "Çevre birimi \"%s\" ağ ile bağlantısı kesildi", + "commands.computercraft.desc": "/computercraft komutu, bilgisayarları kontrol etmek ve bilgisayarlarla etkileşimde bulunmak için çeşitli hata ayıklama ve yönetici araçları sağlar.", + "commands.computercraft.dump.action": "Bu bilgisayar hakkında daha fazla bilgi görüntüle", + "commands.computercraft.dump.desc": "Tüm bilgisayarların durumunu veya bir bilgisayarla ilgili belirli bilgileri görüntüleme. Bilgisayarın örnek kimliğini (örn. 123), bilgisayar kimliğini (örn. #123) ya da etiketini (örn. \"@Bilgisayar\") belirtebilirsiniz.", + "commands.computercraft.dump.open_path": "Bu bilgisayarın dosyalarını görüntüle", + "commands.computercraft.dump.synopsis": "Bilgisayarların durumunu görüntüle.", + "commands.computercraft.generic.additional_rows": "%d ek satır…", + "commands.computercraft.generic.exception": "Beklenmeyen durum (%s)", + "commands.computercraft.generic.no": "H", + "commands.computercraft.generic.no_position": "", + "commands.computercraft.generic.position": "%s, %s, %s", + "commands.computercraft.generic.yes": "E", + "commands.computercraft.help.desc": "Bu yardım mesajını görüntüler", + "commands.computercraft.help.no_children": "%s alt komutları yok", + "commands.computercraft.help.no_command": "Böyle bir komut yok '%s'", + "commands.computercraft.help.synopsis": "Belirli bir komut için yardım sağlar", + "commands.computercraft.queue.desc": "Komut bilgisayarına bir computer_command olayı gönder, ek argümanları geçerek. Bu çoğunlukla harita yapımcıları için tasarlanmıştır ve /trigger'ın daha bilgisayar dostu bir versiyonu olarak işlev görür. Herhangi bir oyuncu komutu çalıştırabilir, bu da büyük olasılıkla bir metin bileşeninin tıklama olayı aracılığıyla yapılır.", + "commands.computercraft.queue.synopsis": "Bir komut bilgisayarına computer_command olayı gönder", + "commands.computercraft.shutdown.desc": "Listelenen bilgisayarları veya hiçbiri belirtilmemişse tümünü kapatma. Bilgisayarın örnek kimliğini (örn. 123), bilgisayar kimliğini (örn. #123) ya da etiketini (örn. \"@Bilgisayar\") belirtebilirsiniz.", + "commands.computercraft.shutdown.done": "%s/%s bilgisayarı kapat", + "commands.computercraft.shutdown.synopsis": "Bilgisayarları uzaktan kapat.", + "commands.computercraft.synopsis": "Bilgisayarları kontrol etmek için çeşitli komutlar.", + "commands.computercraft.tp.action": "Bu bilgisayara ışınlan", + "commands.computercraft.tp.desc": "Bir bilgisayarın bulunduğu yere ışınlan. Bilgisayarın örnek kimliğini (örn. 123), bilgisayar kimliğini (örn. #123) belirtebilirsiniz.", + "commands.computercraft.tp.synopsis": "Belirli bir bilgisayara ışınlan.", + "commands.computercraft.track.desc": "Bilgisayarların ne kadar süre çalıştığını ve kaç olay işlediğini takip et. Bu, /forge track'e benzer bir şekilde bilgi sunar ve gecikmeyi teşhis etmek için yararlı olabilir.", + "commands.computercraft.track.dump.computer": "Bilgisayar", + "commands.computercraft.track.dump.desc": "Bilgisayar takibinin en son sonuçlarını boşalt.", + "commands.computercraft.track.dump.no_timings": "Zamanlama mevcut değil", + "commands.computercraft.track.dump.synopsis": "En son izleme sonuçlarını boşalt", + "commands.computercraft.track.start.desc": "Tüm bilgisayarların yürütme sürelerini ve olay sayılarını izlemeye başla. Bu, önceki çalıştırmaların sonuçlarını atacaktır.", + "commands.computercraft.track.start.stop": "İzlemeyi durdurmak ve sonuçları görüntülemek için %s çalıştır", + "commands.computercraft.track.start.synopsis": "Tüm bilgisayarları izlemeyi başlat", + "commands.computercraft.track.stop.action": "İzlemeyi durdurmak için tıkla", + "commands.computercraft.track.stop.desc": "Tüm bilgisayarların olaylarını ve yürütme sürelerini izlemeyi durdur", + "commands.computercraft.track.stop.not_enabled": "Şu anda bilgisayarlar izlenmiyor", + "commands.computercraft.track.stop.synopsis": "Tüm bilgisayarları izlemeyi durdur", + "commands.computercraft.track.synopsis": "Bilgisayarların yürütme sürelerini takip et.", + "commands.computercraft.turn_on.desc": "Listelenen bilgisayarları aç. Bilgisayarın örnek kimliğini (örn. 123), bilgisayar kimliğini (örn. #123) ya da etiketini (örn. \"@Bilgisayar\") belirtebilirsiniz.", + "commands.computercraft.turn_on.done": "%s/%s bilgisayar açıldı", + "commands.computercraft.turn_on.synopsis": "Bilgisayarları uzaktan aç.", + "commands.computercraft.view.action": "Bu bilgisayarı görüntüle", + "commands.computercraft.view.desc": "Bir bilgisayarın terminalinin açılması, bir bilgisayarın uzaktan kontrolüne izin verir. Bu, kaplumbağanın envanterlerine erişim sağlamaz. Bilgisayarın örnek kimliğini (örn. 123), bilgisayar kimliğini (örn. #123) belirtebilirsiniz.", + "commands.computercraft.view.not_player": "Oyuncu olmayanlar için terminal açılamıyor", + "commands.computercraft.view.synopsis": "Bir bilgisayarın terminalini görüntüle.", + "gui.computercraft.config.command_require_creative": "Komut bilgisayarları yaratıcı modu gerektirir", + "gui.computercraft.config.command_require_creative.tooltip": "Oyuncuların komut bilgisayarlarıyla etkileşime girebilmesi için yaratıcı modda olmalarını\nve op'lu olmalarını gerektirir. Bu, vanilla'nın Komut blokları için varsayılan davranıştır.", + "gui.computercraft.config.computer_space_limit": "Bilgisayar alan sınırı (bayt)", + "gui.computercraft.config.computer_space_limit.tooltip": "Bilgisayarlar ve kaplumbağalar için bayt cinsinden disk alanı sınırı.", + "gui.computercraft.config.default_computer_settings": "Varsayılan Bilgisayar ayarları", + "gui.computercraft.config.default_computer_settings.tooltip": "Yeni bilgisayarlarda ayarlanacak varsayılan sistem ayarlarının virgülle\nayrılmış bir listesi.\nÖrnek: \"shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false\"\ntüm otomatik tamamlamayı devre dışı bırakır.", + "gui.computercraft.config.disabled_generic_methods": "Devre dışı bırakılmış genel yöntemler", + "gui.computercraft.config.disabled_generic_methods.tooltip": "Devre dışı bırakılacak genel yöntemlerin veya yöntem kaynaklarının bir listesi.\nGenel yöntemler açık bir çevresel sağlayıcı olmadığında bir blok/blok varlığına\neklenen yöntemlerdir. Bu, envanter yöntemlerini (yani inventory.getItemDetail,\ninventory.pushItems), ve (Forge'da ise), fluid_storage ve energy_storage\nyöntemlerini içerir.\nBu listedeki yöntemler bir grup yöntem (computercraft:inventory)\nya da tek bir yöntem (computercraft:inventory#pushItems) olabilir.\n", + "gui.computercraft.config.execution": "Yürüt", + "gui.computercraft.config.execution.computer_threads": "Bilgisayar iş parçacıkları", + "gui.computercraft.config.execution.computer_threads.tooltip": "Bilgisayarların çalışabileceği iş parçacığı sayısını ayarla. Daha yüksek bir\nsayı, aynı anda daha fazla bilgisayarın çalışabileceği anlamına gelir, ancak\ngecikmeye neden olabilir. Lütfen bazı modların 1'den yüksek iş parçacığı sayısı\nile çalışmayabileceğini unutmayın. Dikkatli kullanın.\nAralık: > 1", + "gui.computercraft.config.execution.max_main_computer_time": "Sunucu tik bilgisayar zaman sınırı", + "gui.computercraft.config.execution.max_main_computer_time.tooltip": "Milisaniye cinsinden, bilgisayarın bir tik içinde yürütebileceği ideal maksimum süre.\nUnutmayın, ne kadar süreceğini söylemenin bir yolu olmadığı için büyük olasılıkla\nbu sınırı aşacağız - bu, ortalama sürenin üst sınırı olmayı\namaçlamaktadır.\nAralık: > 1", + "gui.computercraft.config.execution.max_main_global_time": "Sunucu tik genel zaman sınırı", + "gui.computercraft.config.execution.max_main_global_time.tooltip": "Milisaniye cinsinden, tek bir tikte görevleri yürütmek için harcanabilecek\nmaksimum süre.\nUnutmayın, ne kadar süreceğini söylemenin bir yolu olmadığı için büyük\nolasılıkla bu sınırı aşacağız - bu, ortalama sürenin üst sınırı olmayı\namaçlamaktadır.\nAralık: > 1", + "gui.computercraft.config.execution.tooltip": "Bilgisayarların yürütme davranışını kontrol eder. Bu, büyük ölçüde sunuculara\nince ayar yapmak için tasarlanmıştır ve genellikle dokunulması gerekmez.", + "gui.computercraft.config.floppy_space_limit": "Disket alan sınırı (bayt)", + "gui.computercraft.config.floppy_space_limit.tooltip": "Disketler için bayt cinsinden disk alanı sınırı.", + "gui.computercraft.config.http": "HTTP", + "gui.computercraft.config.http.bandwidth": "Bant Genişliği", + "gui.computercraft.config.http.bandwidth.global_download": "Genel indirme sınırı", + "gui.computercraft.config.http.bandwidth.global_download.tooltip": "Bir saniye içinde indirilebilecek bayt sayısı. Bu tüm bilgisayarlar arasında paylaşılır. (bayt/s).\nAralık: > 1", + "gui.computercraft.config.http.bandwidth.global_upload": "Genel yükleme sınırı", + "gui.computercraft.config.http.bandwidth.global_upload.tooltip": "Bir saniye içinde yüklenebilecek bayt sayısı. Bu tüm bilgisayarlar arasında paylaşılır. (bayt/s).\nAralık: > 1", + "gui.computercraft.config.http.bandwidth.tooltip": "Bilgisayarlar tarafından kullanılan bant genişliğini sınırlar.", + "gui.computercraft.config.http.enabled": "HTTP API'sini etkinleştir", + "gui.computercraft.config.http.enabled.tooltip": "Bilgisayarlarda \"http\" API'sini etkinleştir. Bunu devre dışı bırakmak, birçok kullanıcının güvendiği \"pastebin\" ve\n\"wget\" programlarını da devre dışı bırakır. Bunu açık bırakmanız ve daha ayrıntılı denetim uygulamak için\n\"rules\" yapılandırma seçeneğini kullanmanız önerilir.", + "gui.computercraft.config.http.max_requests": "Maksimum eşzamanlı istekler", + "gui.computercraft.config.http.max_requests.tooltip": "Bir bilgisayarın tek seferde yapabileceği http isteği sayısı. Ek istekler\nkuyruğa alınacak ve çalışan istekler bittiğinde gönderilecektir. Sınırsız için\n0 olarak ayarla.\nAralık: > 0", + "gui.computercraft.config.http.max_websockets": "Maksimum eşzamanlı websocketleri", + "gui.computercraft.config.http.max_websockets.tooltip": "Bir bilgisayarın tek seferde açık tutabileceği websocket sayısı.\nAralık: > 1", + "gui.computercraft.config.http.proxy": "Proxy", + "gui.computercraft.config.http.proxy.host": "Ana bilgisayar adı", + "gui.computercraft.config.http.proxy.host.tooltip": "Proxy sunucusunun ana bilgisayar adı veya IP adresi.", + "gui.computercraft.config.http.proxy.port": "Port", + "gui.computercraft.config.http.proxy.port.tooltip": "Proxy sunucusunun portu.\nAralık: 1 ~ 65536", + "gui.computercraft.config.http.proxy.tooltip": "HTTP ve websocket isteklerini bir proxy sunucusu üzerinden aktarır. Yalnızca \n\"use_proxy\" olan HTTP kurallarını etkiler, true olarak ayarla (varsayılan\nolarak kapalıdır).\nProxy için kimlik doğrulaması gerekiyorsa, \"computercraft-server.toml\" ile\naynı dizinde, iki nokta üst üste ile ayrılmış kullanıcı adı ve parolayı içeren\nbir \"computercraft-proxy.pw\" dosyası oluştur. örn. \"myuser:mypassword\".\nSOCKS4 proxy'leri için yalnızca kullanıcı adı gereklidir.", + "gui.computercraft.config.http.proxy.type": "Proxy türü", + "gui.computercraft.config.http.proxy.type.tooltip": "Kullanılacak proxy türü.\nİzin Verilen Değerler: HTTP, HTTPS, SOCKS4, SOCKS5", + "gui.computercraft.config.http.rules": "Kurallara izin ver/reddet", + "gui.computercraft.config.http.rules.tooltip": "Belirli alan adları veya IP'ler için \"http\" API davranışını denetleyen\nkurallar listesi. Her kural bir ana bilgisayar adı ve isteğe bağlı bir port ile\neşleşir ve ardından istek için çeşitli özellikler ayarlar. Kurallar sırayla\ndeğerlendirilir, yani önceki kurallar sonrakileri geçersiz kılar.\n\nGeçerli özellikler:\n - \"host\" (gerekli): Bu kuralın eşleştiği alan adı veya IP adresi. Bu bir alan adı olabilir\n (\"pastebin.com\"), wildcard (\"*.pastebin.com\") ya da CIDR gösterimi (\"127.0.0.0/8\").\n - \"port\" (isteğe bağlı): Belirli bir porta yönelik istekleri eşleştir\n80 veya 443 gibi\n\n - \"action\" (isteğe bağlı): Bu isteğe izin verilip verilmeyeceği veya\nreddedilip reddedilmeyeceği.\n - \"max_download\" (isteğe bağlı): Bir bilgisayarın bu istekte indirebileceği\nmaksimum boyut (bayt cinsinden).\n - \"max_upload\" (isteğe bağlı): Bir bilgisayarın bu istekte yükleyebileceği\nmaksimum boyut (bayt cinsinden).\n - \"max_websocket_message\" (isteğe bağlı): Bir bilgisayarın bir websocket\npaketinde gönderebileceği veya alabileceği maksimum boyut (bayt cinsinden).\n - \"use_proxy\" (isteğe bağlı): Yapılandırılmışsa HTTP/SOCKS proxy'sinin kullanımını etkinleştir.", + "gui.computercraft.config.http.tooltip": "HTTP API'sini kontrol eder", + "gui.computercraft.config.http.websocket_enabled": "Websocket'leri etkinleştir", + "gui.computercraft.config.http.websocket_enabled.tooltip": "Http websocket kullanımını etkinleştir. Bunun için \"http_enable\" seçeneğinin de true olması gerekir.", + "gui.computercraft.config.log_computer_errors": "Bilgisayar hatalarını günlüğe kaydet", + "gui.computercraft.config.log_computer_errors.tooltip": "Çevre birimleri ve diğer Lua nesneleri tarafından atılan istisnaları\ngünlüğe kaydet. Bu, mod yapımcılarının sorunları ayıklamasını kolaylaştırır\nancak insanların hatalı yöntemler kullanması durumunda günlük spam'ına neden\nolabilir.", + "gui.computercraft.config.maximum_open_files": "Bilgisayar başına maksimum açık dosya", + "gui.computercraft.config.maximum_open_files.tooltip": "Bir bilgisayarda aynı anda kaç dosyanın açık olabileceğini ayarla. Sınırsız için 0 olarak ayarla.\nAralık: > 0", + "gui.computercraft.config.monitor_distance": "Monitör mesafesi", + "gui.computercraft.config.monitor_distance.tooltip": "Monitörlerin görüntü oluşturacağı maksimum mesafe. Bu, varsayılan olarak\nstandart tile entity sınırıdır, ancak daha büyük monitörler oluşturmak\nisterseniz genişletilebilir.\nAralık: 16 ~ 1024", + "gui.computercraft.config.monitor_renderer": "Monitör oluşturucu", + "gui.computercraft.config.monitor_renderer.tooltip": "Monitörler için kullanılacak oluşturucu. Genellikle bu \"best\" değerinde\ntutulmalıdır - monitörlerde performans sorunları varsa, alternatif oluşturucuları\ndenemek isteyebilirsiniz.\nİzin Verilen Değerler: BEST, TBO, VBO", + "gui.computercraft.config.peripheral": "Çevre birimleri", + "gui.computercraft.config.peripheral.command_block_enabled": "Komut bloğu çevresel birimini etkinleştir", + "gui.computercraft.config.peripheral.command_block_enabled.tooltip": "Komut Bloğu çevre birimi desteğini etkinleştir", + "gui.computercraft.config.peripheral.max_notes_per_tick": "Bir bilgisayarın aynı anda çalabileceği maksimum nota sayısı", + "gui.computercraft.config.peripheral.max_notes_per_tick.tooltip": "Bir hoparlörün aynı anda çalabileceği maksimum nota miktarı.\nAralık: > 1", + "gui.computercraft.config.peripheral.modem_high_altitude_range": "Modem menzili (yüksek irtifa)", + "gui.computercraft.config.peripheral.modem_high_altitude_range.tooltip": "Kablosuz Modemlerin açık havada maksimum irtifadaki menzili, metre cinsinden.\nAralık: 0 ~ 100000", + "gui.computercraft.config.peripheral.modem_high_altitude_range_during_storm": "Modem menzili (yüksek irtifa, kötü hava koşulları)", + "gui.computercraft.config.peripheral.modem_high_altitude_range_during_storm.tooltip": "Kablosuz Modemlerin fırtınalı havalarda maksimum irtifadaki menzili, metre cinsinden.\nAralık: 0 ~ 100000", + "gui.computercraft.config.peripheral.modem_range": "Modem menzili (varsayılan)", + "gui.computercraft.config.peripheral.modem_range.tooltip": "Kablosuz Modemlerin açık havada alçak irtifadaki menzili, metre cinsinden.\nAralık: 0 ~ 100000", + "gui.computercraft.config.peripheral.modem_range_during_storm": "Modem menzili (kötü hava koşulları)", + "gui.computercraft.config.peripheral.modem_range_during_storm.tooltip": "Kablosuz Modemlerin fırtınalı havalarda alçak irtifadaki menzili, metre cinsinden.\nAralık: 0 ~ 100000", + "gui.computercraft.config.peripheral.monitor_bandwidth": "Monitör bant genişliği", + "gui.computercraft.config.peripheral.monitor_bandwidth.tooltip": "Tik başına* ne kadar monitör verisi gönderilebileceğinin sınırı. Not:\n - Bant genişliği sıkıştırmadan önce ölçülür, bu nedenle istemciye gönderilen veriler\n daha küçüktür.\n - Bu, bir paketin gönderildiği oyuncu sayısını göz ardı eder. Bir oyuncu için bir\nmonitörü güncellemek, 20 oyuncuya göndermekle aynı bant genişliği sınırını tüketir.\n - Tam boyutlu bir monitör ~25kb veri gönderir. Dolayısıyla varsayılan değer (1MB)\ntek bir tikte ~40 monitörün güncellenmesine izin verir.\nDevre dışı bırakmak için 0 olarak ayarla.\nAralık: > 0", + "gui.computercraft.config.peripheral.tooltip": "Çevre birimlerine ilişkin çeşitli seçenekler.", + "gui.computercraft.config.term_sizes": "Terminal boyutları", + "gui.computercraft.config.term_sizes.computer": "Bilgisayar", + "gui.computercraft.config.term_sizes.computer.height": "Terminal yüksekliği", + "gui.computercraft.config.term_sizes.computer.height.tooltip": "Aralık: 1 ~ 255", + "gui.computercraft.config.term_sizes.computer.tooltip": "Bilgisayarların terminal boyutu.", + "gui.computercraft.config.term_sizes.computer.width": "Terminal genişliği", + "gui.computercraft.config.term_sizes.computer.width.tooltip": "Aralık: 1 ~ 255", + "gui.computercraft.config.term_sizes.monitor": "Monitör", + "gui.computercraft.config.term_sizes.monitor.height": "Maks monitör yüksekliği", + "gui.computercraft.config.term_sizes.monitor.height.tooltip": "Aralık: 1 ~ 32", + "gui.computercraft.config.term_sizes.monitor.tooltip": "Maksimum monitör boyutu (blok olarak).", + "gui.computercraft.config.term_sizes.monitor.width": "Maks monitör genişliği", + "gui.computercraft.config.term_sizes.monitor.width.tooltip": "Aralık: 1 ~ 32", + "gui.computercraft.config.term_sizes.pocket_computer": "Cep Bilgisayarı", + "gui.computercraft.config.term_sizes.pocket_computer.height": "Terminal yüksekliği", + "gui.computercraft.config.term_sizes.pocket_computer.height.tooltip": "Aralık: 1 ~ 255", + "gui.computercraft.config.term_sizes.pocket_computer.tooltip": "Cep bilgisayarlarının terminal boyutu.", + "gui.computercraft.config.term_sizes.pocket_computer.width": "Terminal genişliği", + "gui.computercraft.config.term_sizes.pocket_computer.width.tooltip": "Aralık: 1 ~ 255", + "gui.computercraft.config.term_sizes.tooltip": "Çeşitli bilgisayar terminallerinin boyutunu yapılandır.\nDaha büyük terminaller daha fazla bant genişliği gerektirir, bu nedenle dikkatli\nkullanın.", + "gui.computercraft.config.turtle": "Kaplumbağalar", + "gui.computercraft.config.turtle.advanced_fuel_limit": "Gelişmiş Kaplumbağa yakıt limiti", + "gui.computercraft.config.turtle.advanced_fuel_limit.tooltip": "Gelişmiş Kaplumbağaların yakıt limiti.\nAralık: > 0", + "gui.computercraft.config.turtle.can_push": "Kaplumbağalar varlıkları itebilir", + "gui.computercraft.config.turtle.can_push.tooltip": "true olarak ayarlanırsa, Kaplumbağalar yer varsa durmak yerine varlıkları yolun\ndışına iter.", + "gui.computercraft.config.turtle.need_fuel": "Yakıtı etkinleştir", + "gui.computercraft.config.turtle.need_fuel.tooltip": "Kaplumbağaların hareket etmek için yakıta ihtiyaç duyup duymadığını ayarla.", + "gui.computercraft.config.turtle.normal_fuel_limit": "Kaplumbağa yakıt limiti", + "gui.computercraft.config.turtle.normal_fuel_limit.tooltip": "Kaplumbağaların yakıt limiti.\nAralık: > 0", + "gui.computercraft.config.turtle.tooltip": "Kaplumbağalarla ilgili çeşitli seçenekler.", + "gui.computercraft.config.upload_max_size": "Dosya yükleme boyut sınırı (bayt)", + "gui.computercraft.config.upload_max_size.tooltip": "Bayt cinsinden dosya yükleme boyut sınırı. 1 KiB ve 16 MiB aralığında olmalıdır.\nYüklemelerin tek bir tikte işlendiğini unutmayın - büyük dosyalar veya düşük ağ\nperformansı ağ iş parçacığını bekletebilir. Ve disk alanına dikkat edin!\nAralık: 1024 ~ 16777216", + "gui.computercraft.config.upload_nag_delay": "Yükleme nag gecikmesi", + "gui.computercraft.config.upload_nag_delay.tooltip": "Beklenmeyen içe aktarmalar hakkında bildirimde bulunacağımız saniye cinsinden gecikme. Devre dışı bırakmak için 0 olarak ayarla.\nAralık: 0 ~ 60", + "gui.computercraft.pocket_computer_overlay": "Cep bilgisayarı açık. Kapatmak için ESC tuşuna bas.", + "gui.computercraft.terminal": "Bilgisayar terminali", + "gui.computercraft.tooltip.computer_id": "Bilgisayar Kimliği: %s", + "gui.computercraft.tooltip.copy": "Panoya kopyala", + "gui.computercraft.tooltip.disk_id": "Disk Kimliği: %s", + "gui.computercraft.tooltip.terminate": "Çalışmakta olan kodu durdur", + "gui.computercraft.tooltip.terminate.key": "Ctrl+T basılı tut", + "gui.computercraft.tooltip.turn_off": "Bu bilgisayarı kapat", + "gui.computercraft.tooltip.turn_off.key": "Ctrl+S basılı tut", + "gui.computercraft.tooltip.turn_on": "Bu bilgisayarı aç", + "gui.computercraft.upload.failed": "Yükleme Başarısız", + "gui.computercraft.upload.failed.computer_off": "Dosyaları yüklemeden önce bilgisayarı açmalısın.", + "gui.computercraft.upload.failed.corrupted": "Dosyalar yüklenirken bozuldu. Lütfen tekrar dene.", + "gui.computercraft.upload.failed.generic": "Dosya yükleme başarısız (%s)", + "gui.computercraft.upload.failed.name_too_long": "Dosya adları yüklenemeyecek kadar uzun.", + "gui.computercraft.upload.failed.too_many_files": "Bu kadar dosya yüklenemiyor.", + "gui.computercraft.upload.failed.too_much": "Dosyalarınız yüklenemeyecek kadar büyük.", + "gui.computercraft.upload.no_response": "Dosyalar Aktarılıyor", + "gui.computercraft.upload.no_response.msg": "Bilgisayarınız aktarılan dosyalarınızı kullanmadı. %s programını çalıştırmanız ve tekrar denemeniz gerekebilir.", + "item.computercraft.disk": "Disket", + "item.computercraft.pocket_computer_advanced": "Gelişmiş Cep Bilgisayarı", + "item.computercraft.pocket_computer_advanced.upgraded": "Gelişmiş %s Cep Bilgisayarı", + "item.computercraft.pocket_computer_normal": "Cep Bilgisayarı", + "item.computercraft.pocket_computer_normal.upgraded": "%s Cep Bilgisayarı", + "item.computercraft.printed_book": "Yazdırılmış Kitap", + "item.computercraft.printed_page": "Yazdırılmış Sayfa", + "item.computercraft.printed_pages": "Yazdırılmış Sayfalar", + "item.computercraft.treasure_disk": "Disket", + "itemGroup.computercraft": "ComputerCraft", + "tag.item.computercraft.computer": "Bilgisayarlar", + "tag.item.computercraft.dyeable": "Boyanabilir eşyalar", + "tag.item.computercraft.monitor": "Monitörler", + "tag.item.computercraft.turtle": "Kaplumbağalar", + "tag.item.computercraft.turtle_can_place": "Kaplumbağa-koyulabilir eşyalar", + "tag.item.computercraft.wired_modem": "Kablolu modemler", + "tracking_field.computercraft.avg": "%s (ort)", + "tracking_field.computercraft.computer_tasks.name": "Görevler", + "tracking_field.computercraft.count": "%s (sayı)", + "tracking_field.computercraft.fs.name": "Dosya sistemi işlemleri", + "tracking_field.computercraft.http_download.name": "HTTP indir", + "tracking_field.computercraft.http_requests.name": "HTTP istekleri", + "tracking_field.computercraft.http_upload.name": "HTTP yükleme", + "tracking_field.computercraft.java_allocation.name": "Java Ayırmaları", + "tracking_field.computercraft.max": "%s (maks)", + "tracking_field.computercraft.peripheral.name": "Çevre birimi çağrıları", + "tracking_field.computercraft.server_tasks.name": "Sunucu görevleri", + "tracking_field.computercraft.turtle_ops.name": "Kaplumbağa işlemleri", + "tracking_field.computercraft.websocket_incoming.name": "Websocket gelen", + "tracking_field.computercraft.websocket_outgoing.name": "Websocket giden", + "upgrade.computercraft.speaker.adjective": "Gürültücü", + "upgrade.computercraft.wireless_modem_advanced.adjective": "Ender", + "upgrade.computercraft.wireless_modem_normal.adjective": "Kablosuz", + "upgrade.minecraft.crafting_table.adjective": "Üretken", + "upgrade.minecraft.diamond_axe.adjective": "Düşen", + "upgrade.minecraft.diamond_hoe.adjective": "Çiftçi", + "upgrade.minecraft.diamond_pickaxe.adjective": "Madenci", + "upgrade.minecraft.diamond_shovel.adjective": "Kazıcı", + "upgrade.minecraft.diamond_sword.adjective": "Dövüşçü" +} From bb04df708632278fef7583896824f65397ff2be2 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Fri, 11 Oct 2024 12:12:02 +0200 Subject: [PATCH 05/39] Remove command translation keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - is no longer used, as positions cannot be nullable. - We don't really need the position one — we can just concatenate in Java. --- .../generated/resources/assets/computercraft/lang/en_us.json | 2 -- .../java/dan200/computercraft/data/LanguageProvider.java | 2 -- .../computercraft/shared/command/text/ChatHelpers.java | 5 ++--- .../peripheral/generic/methods/AbstractInventoryMethods.java | 2 +- .../shared/peripheral/generic/methods/InventoryMethods.java | 2 +- 5 files changed, 4 insertions(+), 9 deletions(-) diff --git a/projects/common/src/generated/resources/assets/computercraft/lang/en_us.json b/projects/common/src/generated/resources/assets/computercraft/lang/en_us.json index a53f4b41d6..dde797f0e4 100644 --- a/projects/common/src/generated/resources/assets/computercraft/lang/en_us.json +++ b/projects/common/src/generated/resources/assets/computercraft/lang/en_us.json @@ -38,8 +38,6 @@ "commands.computercraft.generic.additional_rows": "%d additional rows…", "commands.computercraft.generic.exception": "Unhandled exception (%s)", "commands.computercraft.generic.no": "N", - "commands.computercraft.generic.no_position": "", - "commands.computercraft.generic.position": "%s, %s, %s", "commands.computercraft.generic.yes": "Y", "commands.computercraft.help.desc": "Displays this help message", "commands.computercraft.help.no_children": "%s has no sub-commands", diff --git a/projects/common/src/main/java/dan200/computercraft/data/LanguageProvider.java b/projects/common/src/main/java/dan200/computercraft/data/LanguageProvider.java index 2dc57e4055..1f23f7873f 100644 --- a/projects/common/src/main/java/dan200/computercraft/data/LanguageProvider.java +++ b/projects/common/src/main/java/dan200/computercraft/data/LanguageProvider.java @@ -160,8 +160,6 @@ private void addTranslations() { add("commands.computercraft.queue.synopsis", "Send a computer_command event to a command computer"); add("commands.computercraft.queue.desc", "Send a computer_command event to a command computer, passing through the additional arguments. This is mostly designed for map makers, acting as a more computer-friendly version of /trigger. Any player can run the command, which would most likely be done through a text component's click event."); - add("commands.computercraft.generic.no_position", ""); - add("commands.computercraft.generic.position", "%s, %s, %s"); add("commands.computercraft.generic.yes", "Y"); add("commands.computercraft.generic.no", "N"); add("commands.computercraft.generic.exception", "Unhandled exception (%s)"); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/command/text/ChatHelpers.java b/projects/common/src/main/java/dan200/computercraft/shared/command/text/ChatHelpers.java index 8496548754..1c9a910f3d 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/command/text/ChatHelpers.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/command/text/ChatHelpers.java @@ -40,9 +40,8 @@ public static MutableComponent list(Component... children) { return component; } - public static MutableComponent position(@Nullable BlockPos pos) { - if (pos == null) return Component.translatable("commands.computercraft.generic.no_position"); - return Component.translatable("commands.computercraft.generic.position", pos.getX(), pos.getY(), pos.getZ()); + public static MutableComponent position(BlockPos pos) { + return Component.literal(pos.toShortString()); } public static MutableComponent bool(boolean value) { diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/AbstractInventoryMethods.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/AbstractInventoryMethods.java index 1115a46a81..78fd2d934c 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/AbstractInventoryMethods.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/AbstractInventoryMethods.java @@ -1,6 +1,6 @@ // SPDX-FileCopyrightText: 2020 The CC: Tweaked Developers // -// SPDX-License-Identifier: LicenseRef-CCPL +// SPDX-License-Identifier: MPL-2.0 package dan200.computercraft.shared.peripheral.generic.methods; diff --git a/projects/forge/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java b/projects/forge/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java index 09cec73f1c..d1c1094859 100644 --- a/projects/forge/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java +++ b/projects/forge/src/main/java/dan200/computercraft/shared/peripheral/generic/methods/InventoryMethods.java @@ -1,6 +1,6 @@ // SPDX-FileCopyrightText: 2020 The CC: Tweaked Developers // -// SPDX-License-Identifier: LicenseRef-CCPL +// SPDX-License-Identifier: MPL-2.0 package dan200.computercraft.shared.peripheral.generic.methods; From 0bef3ee0d8d18ce09084a778805c613cecace427 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Fri, 11 Oct 2024 20:27:15 +0200 Subject: [PATCH 06/39] Install/run pre-commit directly The update to Python 3.12 has broken the pre-commit action (as it installs via pip rather than pipx). The maintainer seems unwilling to fix it (to put it diplomatically), so let's just stop using the action and imlement it ourselves. --- .github/workflows/main-ci.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main-ci.yml b/.github/workflows/main-ci.yml index 013ec2ad54..4bc762c801 100644 --- a/.github/workflows/main-ci.yml +++ b/.github/workflows/main-ci.yml @@ -30,8 +30,16 @@ jobs: - name: ⚒️ Build run: ./gradlew assemble || ./gradlew assemble + - name: Cache pre-commit + uses: actions/cache@v4 + with: + path: ~/.cache/pre-commit + key: pre-commit-3|${{ env.pythonLocation }}|${{ hashFiles('.pre-commit-config.yaml') }} + - name: 💡 Lint - uses: pre-commit/action@v3.0.0 + run: | + pipx install pre-commit + pre-commit run --show-diff-on-failure --color=always - name: 🧪 Run tests run: ./gradlew test validateMixinNames checkChangelog From d6a246c12222eda0bcb3c558398584c5bafda852 Mon Sep 17 00:00:00 2001 From: Karotte128 <162465409+Karotte128@users.noreply.github.com> Date: Fri, 11 Oct 2024 18:36:28 +0000 Subject: [PATCH 07/39] Small german translation update (#1992) --- .../assets/computercraft/lang/de_de.json | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/projects/common/src/main/resources/assets/computercraft/lang/de_de.json b/projects/common/src/main/resources/assets/computercraft/lang/de_de.json index e41421b74a..e0efbbae07 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/de_de.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/de_de.json @@ -57,7 +57,7 @@ "commands.computercraft.track.start.stop": "Führe %s aus um die Aufzeichnung zu stoppen und die Ergebnisse anzusehen", "commands.computercraft.track.start.synopsis": "Startet die Aufzeichnung von Computern", "commands.computercraft.track.stop.action": "Klicke um die Aufzeichnung zu stoppen", - "commands.computercraft.track.stop.desc": "Stopt die Aufzeichnung aller Computer Events und Laufzeiten", + "commands.computercraft.track.stop.desc": "Stopt die Aufzeichnung aller Computer-Events und Laufzeiten", "commands.computercraft.track.stop.not_enabled": "Momentan werden keine Computer aufgezeichnet", "commands.computercraft.track.stop.synopsis": "Stoppt die Aufzeichnung aller Computer", "commands.computercraft.track.synopsis": "Zeichnet die Laufzeiten von Computern auf.", @@ -75,7 +75,7 @@ "gui.computercraft.config.default_computer_settings": "Computer-Standardeinstellungen", "gui.computercraft.config.default_computer_settings.tooltip": "eine mit Komma separierte Liste an standardmäßige Systemeinstellungen für neuen Computern.\nBeispiel: \"shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false\"\nwürde jegliche Autovervollständigung deaktivieren.", "gui.computercraft.config.disabled_generic_methods": "Generische Methoden deaktiviert.", - "gui.computercraft.config.disabled_generic_methods.tooltip": "Eine Liste an generischen Methoden oder Methodenquellen zum deaktivieren.\nGenerische Methoden sind Methoden die zu einem block/block entity hinzugefügt werden, insofern kein expliziter Peripheral Provider\ngefunden wurde. Mitbetroffen sind Inventarmethoden (d.h. inventory.getItemDetail,\ninventory.pushItems) und, wenn in Forge gespielt wird, die fluid_storage und energy_storage\nMethoden.\nMethoden in dieser Liste können entweder Gruppen von Methoden (wie computercraft:inventory)\noder einzelne Methoden (wie computercraft:inventory#pushItems) sein.\n", + "gui.computercraft.config.disabled_generic_methods.tooltip": "Eine Liste an generischen Methoden oder Methodenquellen zum deaktivieren.\nGenerische Methoden sind Methoden die zu einem Block oder Blockentity hinzugefügt werden, insofern kein expliziter Peripheral Provider\ngefunden wurde. Mitbetroffen sind Inventarmethoden (d.h. inventory.getItemDetail,\ninventory.pushItems) und, wenn in Forge gespielt wird, die fluid_storage und energy_storage\nMethoden.\nMethoden in dieser Liste können entweder Gruppen von Methoden (wie computercraft:inventory)\noder einzelne Methoden (wie computercraft:inventory#pushItems) sein.\n", "gui.computercraft.config.execution": "Ausführung", "gui.computercraft.config.execution.computer_threads": "Computer Threads", "gui.computercraft.config.execution.computer_threads.tooltip": "Setzt die Anzahl an Hintergrundprozessen fest, auf denen Computer laufen können. Eine hohe Nummer heißt,\ndass mehrere Computer zur selben Zeit laufen können, jedoch aber auch ggf. mehr Verzögerungen verursachen. Bitte beachte, dass manche mods\nnicht mit einer Anzahl an Hintergrundprozessen laufen, die höher als 1 ist. Benutze also mit bedacht.\nBereich: > 1", @@ -133,15 +133,15 @@ "upgrade.minecraft.diamond_sword.adjective": "Nahkampf", "argument.computercraft.computer.id": "Computer ID", "argument.computercraft.computer.instance": "einzigartige Instanz ID", - "argument.computercraft.computer.label": "Computer name", - "argument.computercraft.unknown_computer_family": "Unbekannte computer familie '%s'", + "argument.computercraft.computer.label": "Computername", + "argument.computercraft.unknown_computer_family": "Unbekannte Computerfamilie '%s'", "gui.computercraft.config.floppy_space_limit.tooltip": "Die maximale Dateisystem Größe von Disketten (in bytes).", "gui.computercraft.config.http.bandwidth": "Bandbreite", - "gui.computercraft.config.http.bandwidth.global_upload": "Globales upload limit", - "gui.computercraft.config.http.bandwidth.global_download.tooltip": "Die maximale Geschwindigkeit aller Computer in bytes/s mit der Heruntergeladen werden kann.\nBereich: > 1", - "gui.computercraft.config.http.bandwidth.global_download": "Globales download limit", + "gui.computercraft.config.http.bandwidth.global_upload": "Globale Uploadbandbreite", + "gui.computercraft.config.http.bandwidth.global_download.tooltip": "Die maximale Bandbreite aller Computer in bytes/s mit der heruntergeladen werden kann.\nBereich: > 1", + "gui.computercraft.config.http.bandwidth.global_download": "Globale Downloadbandbreite", "gui.computercraft.config.http.bandwidth.tooltip": "Limitiert die Bandbreite der Computer.", - "argument.computercraft.computer.family": "Computer familie", - "gui.computercraft.config.execution.max_main_global_time.tooltip": "Die maximale Zeit in millisekunden, in der Aufgaben ausgeführt werden.\nAnmerkung: Diese Zeit wird höchstwarscheinlich überschritten und dient nur als ungefähre Grenze.\nLimit: > 1", - "gui.computercraft.config.http.bandwidth.global_upload.tooltip": "Die maximale Hochladungs Geschwindigkeit aller Computer in bytes/s.\nBereich: > 1" + "argument.computercraft.computer.family": "Computerfamilie", + "gui.computercraft.config.execution.max_main_global_time.tooltip": "Die maximale Zeit in Millisekunden, in der Aufgaben ausgeführt werden.\nAnmerkung: Diese Zeit wird höchstwarscheinlich überschritten und dient nur als ungefähre Grenze.\nLimit: > 1", + "gui.computercraft.config.http.bandwidth.global_upload.tooltip": "Die maximale Bandbreite aller Computer in bytes/s mit der hochgeladen werden kann.\nBereich: > 1" } From c271ed7c7f9c9e3e927a0939fafb20690b8d40f3 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Thu, 24 Oct 2024 14:03:06 +0100 Subject: [PATCH 08/39] Fix wrong link in os.date docs Should be os.time, not os.date! Fixes #1999 --- .../dan200/computercraft/core/apis/OSAPI.java | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/OSAPI.java b/projects/core/src/main/java/dan200/computercraft/core/apis/OSAPI.java index 49c75e8cb6..3251004c3f 100644 --- a/projects/core/src/main/java/dan200/computercraft/core/apis/OSAPI.java +++ b/projects/core/src/main/java/dan200/computercraft/core/apis/OSAPI.java @@ -403,21 +403,39 @@ public final long epoch(Optional args) throws LuaException { * function. The format string can also be prefixed with an exclamation mark * ({@code !}) to use UTC time instead of the server's local timezone. *

- * If the format is exactly {@code *t} (optionally prefixed with {@code !}), a - * table will be returned instead. This table has fields for the year, month, - * day, hour, minute, second, day of the week, day of the year, and whether - * Daylight Savings Time is in effect. This table can be converted to a UNIX - * timestamp (days since 1 January 1970) with {@link #date}. + * If the format is exactly {@code "*t"} (or {@code "!*t"} ), a table + * representation of the timestamp will be returned instead. This table has + * fields for the year, month, day, hour, minute, second, day of the week, + * day of the year, and whether Daylight Savings Time is in effect. This + * table can be converted back to a timestamp with {@link #time(IArguments)}. * * @param formatA The format of the string to return. This defaults to {@code %c}, which expands to a string similar to "Sat Dec 24 16:58:00 2011". - * @param timeA The time to convert to a string. This defaults to the current time. - * @return The resulting format string. + * @param timeA The timestamp to convert to a string. This defaults to the current time. + * @return The resulting formated string, or table. * @throws LuaException If an invalid format is passed. * @cc.since 1.83.0 * @cc.usage Print the current date in a user-friendly string. *

{@code
      * os.date("%A %d %B %Y") -- See the reference above!
      * }
+ * + * @cc.usage Convert a timestamp to a table. + *
{@code
+     * os.date("!*t", 1242534247)
+     * --[=[ {
+     *   -- Date
+     *   year  = 2009,
+     *   month = 5,
+     *   day   = 17,
+     *   yday  = 137,
+     *   wday  = 1,
+     *   -- Time
+     *   hour  = 4,
+     *   min   = 24,
+     *   sec   = 7,
+     *   isdst = false,
+     * } ]=]
+     * }
*/ @LuaFunction public final Object date(Optional formatA, Optional timeA) throws LuaException { From dcc74e15c7ab88e5ec7bb4c83ca00d49c074b615 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sun, 27 Oct 2024 09:43:47 +0000 Subject: [PATCH 09/39] Fix pocket upgrades not applying after crafting The most annoying thing about pocket computers is handling computer state (label, upgrades, etc...). Unlike other computers, which are tied to a specific block entity, pocket computers float untethered. We can't hold a reference to a specific item stack (as the computer might be moved between inventories, crafted, etc...), so instead we explicitly sync data between the computer and *current* stack, whenever the holding player/entity is ticked. In ed0b156e05ff64784f2f80346c82ab5142d954dc I rewrote this syncing code to always treat the computer as the source of truth. Upgrades would be copied to the computer, but never the other way round. However, this meant that upgrades obtained by crafting would never be detected, requiring the computer to be destroyed and recreated. A more long-term fix here is probably to rewrite IPocketAccess to only allow updating upgrade data on the main thread, and when we have a valid PocketHolder. This is a breaking API change though, and so will have to wait for 1.21.3. For now, we just add a hook that refreshes the upgrade after crafting. Fixes #1957 --- .../shared/pocket/core/PocketBrain.java | 5 ++++- .../shared/pocket/items/PocketComputerItem.java | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketBrain.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketBrain.java index 33b5e82311..6d8286e5b4 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketBrain.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketBrain.java @@ -24,6 +24,7 @@ import javax.annotation.Nullable; import java.util.Collections; import java.util.Map; +import java.util.Objects; /** * Holds additional state for a pocket computer. This includes pocket computer upgrade, @@ -177,7 +178,9 @@ public Map getUpgrades() { */ @Override public void setUpgrade(@Nullable UpgradeData upgrade) { - this.upgrade = upgrade; + if (Objects.equals(this.upgrade, upgrade)) return; + + this.upgrade = UpgradeData.copyOf(upgrade); dirty = true; invalidatePeripheral(); } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItem.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItem.java index 348c96dece..f08c871d1e 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItem.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItem.java @@ -267,6 +267,21 @@ public static PocketServerComputer getServerComputer(MinecraftServer server, Ite return getServerComputer(ServerContext.get(server).registry(), stack); } + @Override + public void onCraftedBy(ItemStack stack, Level level, Player player) { + var tag = stack.getTag(); + if (tag == null) return; + + // Normally we treat the computer instance as the source of truth, and copy the computer's state back to the + // item. However, if we've just crafted the computer with an upgrade, we should sync the other way, and update + // the computer. + var server = level.getServer(); + if (server != null) { + var computer = getServerComputer(server, stack); + if (computer != null) computer.getBrain().setUpgrade(getUpgradeWithData(stack)); + } + } + // IComputerItem implementation private static void setComputerID(ItemStack stack, int computerID) { From 9e5e6a1b60de3fceb7ca93b250c1cce980921004 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sun, 27 Oct 2024 10:01:29 +0000 Subject: [PATCH 10/39] Update npm packages and illuaminate --- gradle/libs.versions.toml | 2 +- package-lock.json | 1271 +++++++++++++++++++++---------------- package.json | 4 +- 3 files changed, 738 insertions(+), 539 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a4e1ad4be0..87231a21f9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -66,7 +66,7 @@ forgeGradle = "6.0.21" githubRelease = "2.5.2" gradleVersions = "0.50.0" ideaExt = "1.1.7" -illuaminate = "0.1.0-73-g43ee16c" +illuaminate = "0.1.0-74-gf1551d5" librarian = "1.+" lwjgl = "3.3.3" minotaur = "2.+" diff --git a/package-lock.json b/package-lock.json index df19d98a2f..3ef49d2719 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,10 +16,10 @@ }, "devDependencies": { "@rollup/plugin-node-resolve": "^15.2.1", - "@rollup/plugin-typescript": "^11.0.0", + "@rollup/plugin-typescript": "^12.0.0", "@rollup/plugin-url": "^8.0.1", "@swc/core": "^1.3.92", - "@types/node": "^20.8.3", + "@types/node": "^22.0.0", "lightningcss": "^1.22.0", "preact-render-to-string": "^6.2.1", "rehype": "^13.0.0", @@ -31,383 +31,423 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", - "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", + "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", - "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", + "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", - "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", + "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", - "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", + "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", - "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", + "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", - "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", + "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", - "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", + "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", - "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", + "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", - "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", + "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", - "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", + "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", - "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", + "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", - "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", + "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", "cpu": [ "loong64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", - "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", + "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", "cpu": [ "mips64el" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", - "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", + "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", - "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", + "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", - "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", + "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", - "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", + "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", - "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", + "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", + "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", - "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", + "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", - "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", + "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", - "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", + "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", - "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", + "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", - "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", + "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@rollup/plugin-node-resolve": { - "version": "15.2.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", - "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.0.tgz", + "integrity": "sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag==", "dev": true, + "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", - "is-builtin-module": "^3.2.1", "is-module": "^1.0.0", "resolve": "^1.22.1" }, @@ -424,10 +464,11 @@ } }, "node_modules/@rollup/plugin-typescript": { - "version": "11.1.6", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.6.tgz", - "integrity": "sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==", + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-12.1.1.tgz", + "integrity": "sha512-t7O653DpfB5MbFrqPe/VcKFFkvRuFNp9qId3xq4Eth5xlyymzxNpye2z8Hrl0RIMuXTSr5GGcFpkdlMeacUiFQ==", "dev": true, + "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.1.0", "resolve": "^1.22.1" @@ -454,6 +495,7 @@ "resolved": "https://registry.npmjs.org/@rollup/plugin-url/-/plugin-url-8.0.2.tgz", "integrity": "sha512-5yW2LP5NBEgkvIRSSEdJkmxe5cUNZKG3eenKtfJvSkxVm/xTTu7w+ayBtNwhozl1ZnTUCU0xFaRQR+cBl2H7TQ==", "dev": true, + "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.0.1", "make-dir": "^3.1.0", @@ -472,14 +514,15 @@ } }, "node_modules/@rollup/pluginutils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", - "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.3.tgz", + "integrity": "sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" + "picomatch": "^4.0.2" }, "engines": { "node": ">=14.0.0" @@ -494,169 +537,238 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz", - "integrity": "sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==", + "version": "4.24.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.1.tgz", + "integrity": "sha512-j2llrtCTwNu68yp1wybgkTUW8CrR8AZvGZzIO/qwNAetVP3FHidylyz1s0dU2zXG9uqqpoUIhWKmMypGMcdM2Q==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.6.tgz", - "integrity": "sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==", + "version": "4.24.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.1.tgz", + "integrity": "sha512-y65R3hM9sJVAXV3qh/dJ5o2OCVzwy6d994qmi+rGw1i1onYY5AoV9dREDYoizaZvc9esEqOs07CyFgPzz4DBqg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.6.tgz", - "integrity": "sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==", + "version": "4.24.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.1.tgz", + "integrity": "sha512-K9iOc75U9HpDffjop9qVPwNoBEPXS0Q6RrVSvh13gs38ynurJ2+HuS7NJbsx+fwiDA+eJYfBi7sablI8G2/3oA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.6.tgz", - "integrity": "sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==", + "version": "4.24.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.1.tgz", + "integrity": "sha512-Ufz0fX79W9937euBI4qEdh2xLb0Lzo4GiZ7xxDpueEZxWdPbow6gnTRokSzSgtqRFs1vFgcgm7Ci/KnOo15MIg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.24.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.1.tgz", + "integrity": "sha512-IfG1khuwe10V2EBfFIrcd7P6X0stdhHQM71NyaG5TPgy6dXr2nzAa5TMNFA35tr41gihUPqp/w8StayYG7jXYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.6.tgz", - "integrity": "sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==", + "version": "4.24.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.1.tgz", + "integrity": "sha512-W+drJRBL1+N1/zaq+8y/CtQ3VP5wxMXwCy7obFl9r5jJ5EFNEYAqchuPfYTleYOoA46bwXAprCL+OVK3BTrWWw==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.24.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.1.tgz", + "integrity": "sha512-mKngr0zxo4FMSDqiq4F4G/1IPqjpNO7MyjAM6+YxDIADO4ZSI4m05bZYD4po12Jid6+n9YJRWdIcvi4JztMVcw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.6.tgz", - "integrity": "sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==", + "version": "4.24.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.1.tgz", + "integrity": "sha512-Rh12WITgvLydYFR9XAjmCRArU71nMfi5lDVLhpRV8dR2sCGtZESVkfD66mi3owp4q1scwysT35nNMPleRTQOow==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.6.tgz", - "integrity": "sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==", + "version": "4.24.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.1.tgz", + "integrity": "sha512-zOLu7V1iBpJMIrrmZjpmAZ9txFlnGgqQMnjNmRrqmV1vQaou9SIT3qI3JE1kt+DQE8zCdB3n2/mAjIU90AfjEg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.24.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.1.tgz", + "integrity": "sha512-h9ipTGhMzTBAJL/bg1HsElhGPWLGeCKE8JkxgvrJ5O/S1MXH9RxMUTl++tzlpzxdOBCAGqygZIMBj3wIDf/kJw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.6.tgz", - "integrity": "sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==", + "version": "4.24.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.1.tgz", + "integrity": "sha512-PNKCMA1xRBARR7/j6KXMSB1z0/eGenC/t2wdQl5et3jnrHA+igIaLVNUEPfnVjmZIZJign7u/dobvV2VkPxMiw==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.24.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.1.tgz", + "integrity": "sha512-mkl3uWq/ix18gAfzBUIecSwioPyJkbR6QXVaNuOGM7Qbs7f1EfDLP4XtLSJx4GL6mO8GrKhB3cmhUc3zjUrQSg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.6.tgz", - "integrity": "sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==", + "version": "4.24.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.1.tgz", + "integrity": "sha512-j0RPQWteEXAAxRQI+IcX3i7WQb7hFe7CW94H3l0edBVyJMIPOlr/hqc5CGG1FBDW9gNr0ZC2IzwSta1iSNJIoA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.6.tgz", - "integrity": "sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==", + "version": "4.24.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.1.tgz", + "integrity": "sha512-UrwXowd3gyT+/ijoeSzMyHHGUaV3WhiJL77eTZE8/Pq+9K6auacIJ264biAUhHJ3FjAHsXNhzEmxGnj4tpDz2g==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.6.tgz", - "integrity": "sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==", + "version": "4.24.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.1.tgz", + "integrity": "sha512-wexHPBkBa2/tPhbGcxLqOM2AFZ7BQsZ0pk3dVxRL5Ec0SsXnkpcMucZ4j4woyoD5DbRdFP6Roptd9TRsGVTvUA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.6.tgz", - "integrity": "sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==", + "version": "4.24.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.1.tgz", + "integrity": "sha512-IW2axCCdiC+kgj5/50Mt5v8qG0LYaDichBGKXM4Oo2NaWStAs0oQp1dqVzCV1XOXNvNNDRFw0EaT+JMs6BX+WQ==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.6.tgz", - "integrity": "sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==", + "version": "4.24.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.1.tgz", + "integrity": "sha512-b9IK2buRXwm7owl4Hd8fselCQ7/gr2WaErv0e/IPgRQuJfFS+O0cFJA4t13+FKAZeQh97iEyBG06g613IJLirQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -666,20 +778,22 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@squid-dev/cc-web-term/-/cc-web-term-2.0.1.tgz", "integrity": "sha512-zHivNbvZgOQHy3abEX72CleeiJbwBICzJbUkUtDFSyve1q2x40hsvoJpv8an/4JVT37ytzM+u52s3Mx46lh5WA==", + "license": "BSD-3-Clause", "dependencies": { "gif.js": "^0.2.0", "preact": "^10.5.5" } }, "node_modules/@swc/core": { - "version": "1.3.106", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.106.tgz", - "integrity": "sha512-++QPSPkFq2qELYVScxNHJC42hKQChjiTWS2P0QQ5JWT4NHb9lmNSfrc1ylFIyImwRnxsW2MTBALLYLf95EFAsg==", + "version": "1.7.40", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.40.tgz", + "integrity": "sha512-0HIzM5vigVT5IvNum+pPuST9p8xFhN6mhdIKju7qYYeNuZG78lwms/2d8WgjTJJlzp6JlPguXGrMMNzjQw0qNg==", "dev": true, "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { - "@swc/counter": "^0.1.1", - "@swc/types": "^0.1.5" + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.13" }, "engines": { "node": ">=10" @@ -689,19 +803,19 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.3.106", - "@swc/core-darwin-x64": "1.3.106", - "@swc/core-linux-arm-gnueabihf": "1.3.106", - "@swc/core-linux-arm64-gnu": "1.3.106", - "@swc/core-linux-arm64-musl": "1.3.106", - "@swc/core-linux-x64-gnu": "1.3.106", - "@swc/core-linux-x64-musl": "1.3.106", - "@swc/core-win32-arm64-msvc": "1.3.106", - "@swc/core-win32-ia32-msvc": "1.3.106", - "@swc/core-win32-x64-msvc": "1.3.106" + "@swc/core-darwin-arm64": "1.7.40", + "@swc/core-darwin-x64": "1.7.40", + "@swc/core-linux-arm-gnueabihf": "1.7.40", + "@swc/core-linux-arm64-gnu": "1.7.40", + "@swc/core-linux-arm64-musl": "1.7.40", + "@swc/core-linux-x64-gnu": "1.7.40", + "@swc/core-linux-x64-musl": "1.7.40", + "@swc/core-win32-arm64-msvc": "1.7.40", + "@swc/core-win32-ia32-msvc": "1.7.40", + "@swc/core-win32-x64-msvc": "1.7.40" }, "peerDependencies": { - "@swc/helpers": "^0.5.0" + "@swc/helpers": "*" }, "peerDependenciesMeta": { "@swc/helpers": { @@ -710,13 +824,14 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.3.106", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.106.tgz", - "integrity": "sha512-XYcbViNyHnnm7RWOAO1YipMmthM7m2aXF32b0y+JMLYFBEyFpjVX9btLkzeL7wRx/5B3I35yJNhE+xyx0Q1Gkw==", + "version": "1.7.40", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.40.tgz", + "integrity": "sha512-LRRrCiRJLb1kpQtxMNNsr5W82Inr0dy5Imho+4HQzVx/Ismi0qX4hQBgzJAnyOBNLK1+OBVb/912UVhKXppdfQ==", "cpu": [ "arm64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "darwin" @@ -726,13 +841,14 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.3.106", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.106.tgz", - "integrity": "sha512-YKDPhUdfuwhmOUS9+CaIwl/0Tp+f1b73BH2EIESuxSNsogZf18a8HQ8O0fQEwdiwmA5LEqw47cj+kfOWV/0+kw==", + "version": "1.7.40", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.40.tgz", + "integrity": "sha512-Lpl0XK/4fLzS5jsK48opUuGXrqJXwqJckYYPwyGbCfCXm4MsBe+7dX2hq/Kc4YMY25+NeTmzAXhla8TT4WYD/g==", "cpu": [ "x64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "darwin" @@ -742,13 +858,14 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.3.106", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.106.tgz", - "integrity": "sha512-bHxxJXogvFfocLL5inZxxtx/x/WgKozigp80Vbx0viac1fPDJrqKBw2X4MzpMiuTRAGVQ03jJI6pDwbSBf+yDw==", + "version": "1.7.40", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.40.tgz", + "integrity": "sha512-4bEvvjptpoc5BRPr/R419h6fXTEuub+frpxxlxBOEKxgXjAF/S3xdxyPijUAakmW/xXBF0u7OC4KYI+38yQp6g==", "cpu": [ "arm" ], "dev": true, + "license": "Apache-2.0", "optional": true, "os": [ "linux" @@ -758,13 +875,14 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.3.106", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.106.tgz", - "integrity": "sha512-c7jue++CHLgtpeaakEukoCLT9eNrImizbleE9Y7Is8CHqLq/7DG4s+7ma9DFKXIzW2MpTg9byIEQfpqSphVW6A==", + "version": "1.7.40", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.40.tgz", + "integrity": "sha512-v2fBlHJ/6Ovz0L2xFAI9TRiKyl9DTdx139PuAHD9gyzp16Utl/W0MPd4t2cYdkI6hPXE9PsJCSzMOrduh+YoDg==", "cpu": [ "arm64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" @@ -774,13 +892,14 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.3.106", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.106.tgz", - "integrity": "sha512-51EaC3Q8qAhLtWVnAVqoYX/gk3tK31cCBzUpwCcmhianhEBM2/WtKRAS4MqPhE8VVZuN3WjO2c2JaF2mX0yuoA==", + "version": "1.7.40", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.40.tgz", + "integrity": "sha512-uMkduQuU4LFVkW6txv8AVArT8GjJVJ5IHoWloXaUBMT447iE8NALmpePdZWhMyj6KV7j0y23CM5rzV/I2eNGLg==", "cpu": [ "arm64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" @@ -790,13 +909,14 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.3.106", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.106.tgz", - "integrity": "sha512-tOUi8BB6jAeCXgx7ESLNnX7nrbMVKQ/XajK77v7Ad4SXf9HYArnimBJpXUUyVFJTXLSv4e6c7s6XHHqXb5Lwcg==", + "version": "1.7.40", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.40.tgz", + "integrity": "sha512-4LZdY1MBSnXyTpW5fpBU/+JGAhkuHT+VnFTDNegRboN5nSPh7y0Yvn4LmIioESV+sWzjKkEXujJPGjrp+oSp5w==", "cpu": [ "x64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" @@ -806,13 +926,14 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.3.106", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.106.tgz", - "integrity": "sha512-binLw4Lbd83NPy4/m/teH2nbaifxveSD+sKDvpxywRbvYW2I0w/iCBpUBcbnl16TQF4TPOGpq5YwG9lVxPVw5g==", + "version": "1.7.40", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.40.tgz", + "integrity": "sha512-FPjOwT3SgI6PAwH1O8bhOGBPzuvzOlzKeCtxLaCjruHJu9V8KKBrMTWOZT/FJyYC9mX5Ip1+l9j30UqUZdQxtA==", "cpu": [ "x64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" @@ -822,13 +943,14 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.3.106", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.106.tgz", - "integrity": "sha512-n4ttBWr8tM7DPzwcEOIBTyTMHZTzCmbic/HTtxEsPyMAf/Daen+yrTKzjPP6k2usfSrjkxA780RSJJxI1N8r2w==", + "version": "1.7.40", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.40.tgz", + "integrity": "sha512-//ovXdD9GsTmhPmXJlXnIbRQkeuL6PSrYSr7uCMNcclrUdJG0YkO0GMM2afUKYbdJcunylDDWsSS8PFWn0QxmA==", "cpu": [ "arm64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "win32" @@ -838,13 +960,14 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.3.106", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.106.tgz", - "integrity": "sha512-GhDNIwxE5FhkujESI6h/4ysT3wxwmrzTUlZYaR8rRui6a6SdX9feIPUHPEE5o5hpyp+xqlmvRxKkRxOnwsq8iA==", + "version": "1.7.40", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.40.tgz", + "integrity": "sha512-iD/1auVhHGlhWAPrWmfRWL3w4AvXIWGVXZiSA109/xnRIPiHKb/HqqTp/qB94E/ZHMPRgLKkLTNwamlkueUs8g==", "cpu": [ "ia32" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "win32" @@ -854,13 +977,14 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.3.106", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.106.tgz", - "integrity": "sha512-2M6yWChuMS1+/MPo3Dor0SOMkvmiugonWlzsZBAu/oZboH2xKrHSRv7brsBujb2Oe47r+NsbV+vq9tnnP9Vl1Q==", + "version": "1.7.40", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.40.tgz", + "integrity": "sha512-ZlFAV1WFPhhWQ/8esiygmetkb905XIcMMtHRRG0FBGCllO+HVL5nikUaLDgTClz1onmEY9sMXUFQeoPtvliV+w==", "cpu": [ "x64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "win32" @@ -870,55 +994,65 @@ } }, "node_modules/@swc/counter": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.2.tgz", - "integrity": "sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw==", - "dev": true + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true, + "license": "Apache-2.0" }, "node_modules/@swc/types": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.5.tgz", - "integrity": "sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==", - "dev": true + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.13.tgz", + "integrity": "sha512-JL7eeCk6zWCbiYQg2xQSdLXQJl8Qoc9rXmG2cEKvHe3CKwMHwHGpfOb8frzNLmbycOo6I51qxnLnn9ESf4I20Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3" + } }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/ms": "*" } }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" }, "node_modules/@types/estree-jsx": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.3.tgz", - "integrity": "sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "*" } }, "node_modules/@types/hast": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.3.tgz", - "integrity": "sha512-2fYGlaDy/qyLlhidX42wAH0KBi2TCjKMH8CHmBXgRlJ3Y+OXTiqsPQ6IWarZKwF1JoUcAJdPogv1d4b0COTpmQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "*" } }, "node_modules/@types/mdast": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", - "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "*" } @@ -927,62 +1061,57 @@ "version": "0.7.34", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { - "version": "20.11.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.7.tgz", - "integrity": "sha512-GPmeN1C3XAyV5uybAf4cMLWT9fDWcmQhZVtMFu7OR32WjrqGG+Wnk2V1d0bmtUyE/Zy1QJ9BxyiTih9z8Oks8A==", + "version": "22.8.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.1.tgz", + "integrity": "sha512-k6Gi8Yyo8EtrNtkHXutUu2corfDf9su95VYVP10aGYMMROM6SAItZi0w1XszA6RtWTHSVp5OeFof37w0IEqCQg==", "dev": true, + "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.8" } }, "node_modules/@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/unist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==", - "dev": true + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/bail": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ccount": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -993,6 +1122,7 @@ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -1003,6 +1133,7 @@ "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -1013,6 +1144,7 @@ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -1023,6 +1155,7 @@ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -1033,18 +1166,20 @@ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -1060,6 +1195,7 @@ "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", "dev": true, + "license": "MIT", "dependencies": { "character-entities": "^2.0.0" }, @@ -1073,6 +1209,7 @@ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1082,6 +1219,7 @@ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1091,6 +1229,7 @@ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "dev": true, + "license": "Apache-2.0", "bin": { "detect-libc": "bin/detect-libc.js" }, @@ -1103,6 +1242,7 @@ "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", "dev": true, + "license": "MIT", "dependencies": { "dequal": "^2.0.0" }, @@ -1116,6 +1256,7 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -1124,41 +1265,43 @@ } }, "node_modules/esbuild": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", - "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", + "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.12", - "@esbuild/android-arm": "0.19.12", - "@esbuild/android-arm64": "0.19.12", - "@esbuild/android-x64": "0.19.12", - "@esbuild/darwin-arm64": "0.19.12", - "@esbuild/darwin-x64": "0.19.12", - "@esbuild/freebsd-arm64": "0.19.12", - "@esbuild/freebsd-x64": "0.19.12", - "@esbuild/linux-arm": "0.19.12", - "@esbuild/linux-arm64": "0.19.12", - "@esbuild/linux-ia32": "0.19.12", - "@esbuild/linux-loong64": "0.19.12", - "@esbuild/linux-mips64el": "0.19.12", - "@esbuild/linux-ppc64": "0.19.12", - "@esbuild/linux-riscv64": "0.19.12", - "@esbuild/linux-s390x": "0.19.12", - "@esbuild/linux-x64": "0.19.12", - "@esbuild/netbsd-x64": "0.19.12", - "@esbuild/openbsd-x64": "0.19.12", - "@esbuild/sunos-x64": "0.19.12", - "@esbuild/win32-arm64": "0.19.12", - "@esbuild/win32-ia32": "0.19.12", - "@esbuild/win32-x64": "0.19.12" + "@esbuild/aix-ppc64": "0.23.1", + "@esbuild/android-arm": "0.23.1", + "@esbuild/android-arm64": "0.23.1", + "@esbuild/android-x64": "0.23.1", + "@esbuild/darwin-arm64": "0.23.1", + "@esbuild/darwin-x64": "0.23.1", + "@esbuild/freebsd-arm64": "0.23.1", + "@esbuild/freebsd-x64": "0.23.1", + "@esbuild/linux-arm": "0.23.1", + "@esbuild/linux-arm64": "0.23.1", + "@esbuild/linux-ia32": "0.23.1", + "@esbuild/linux-loong64": "0.23.1", + "@esbuild/linux-mips64el": "0.23.1", + "@esbuild/linux-ppc64": "0.23.1", + "@esbuild/linux-riscv64": "0.23.1", + "@esbuild/linux-s390x": "0.23.1", + "@esbuild/linux-x64": "0.23.1", + "@esbuild/netbsd-x64": "0.23.1", + "@esbuild/openbsd-arm64": "0.23.1", + "@esbuild/openbsd-x64": "0.23.1", + "@esbuild/sunos-x64": "0.23.1", + "@esbuild/win32-arm64": "0.23.1", + "@esbuild/win32-ia32": "0.23.1", + "@esbuild/win32-x64": "0.23.1" } }, "node_modules/estree-util-is-identifier-name": { @@ -1166,6 +1309,7 @@ "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", "dev": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -1175,13 +1319,15 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fsevents": { "version": "2.3.3", @@ -1189,6 +1335,7 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -1202,15 +1349,17 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-tsconfig": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", - "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", + "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", "dev": true, + "license": "MIT", "dependencies": { "resolve-pkg-maps": "^1.0.0" }, @@ -1221,13 +1370,15 @@ "node_modules/gif.js": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/gif.js/-/gif.js-0.2.0.tgz", - "integrity": "sha512-bYxCoT8OZKmbxY8RN4qDiYuj4nrQDTzgLRcFVovyona1PTWNePzI4nzOmotnlOFIzTk/ZxAHtv+TfVLiBWj/hw==" + "integrity": "sha512-bYxCoT8OZKmbxY8RN4qDiYuj4nrQDTzgLRcFVovyona1PTWNePzI4nzOmotnlOFIzTk/ZxAHtv+TfVLiBWj/hw==", + "license": "MIT" }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -1236,10 +1387,11 @@ } }, "node_modules/hast-util-from-html": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.1.tgz", - "integrity": "sha512-RXQBLMl9kjKVNkJTIO6bZyb2n+cUH8LFaSSzo82jiLT6Tfc+Pt7VQCS+/h3YwG4jaNE2TA2sdJisGWR+aJrp0g==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "devlop": "^1.1.0", @@ -1258,6 +1410,7 @@ "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", @@ -1278,6 +1431,7 @@ "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0" }, @@ -1291,6 +1445,7 @@ "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0" }, @@ -1299,42 +1454,17 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-raw": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.2.tgz", - "integrity": "sha512-PldBy71wO9Uq1kyaMch9AHIghtQvIwxBUkv823pKmkTM3oV1JxtsTNYdevMxvUHqcnOAuO65JKU2+0NOxc2ksA==", - "dev": true, - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-from-parse5": "^8.0.0", - "hast-util-to-parse5": "^8.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "parse5": "^7.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/hast-util-to-html": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.0.tgz", - "integrity": "sha512-IVGhNgg7vANuUA2XKrT6sOIIPgaYZnmLx3l/CCOAK0PtgfoHrZwX7jCSYyFxHTrGmC6S9q8aQQekjp4JPZF+cw==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.3.tgz", + "integrity": "sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", - "hast-util-raw": "^9.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", @@ -1349,10 +1479,11 @@ } }, "node_modules/hast-util-to-jsx-runtime": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz", - "integrity": "sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.2.tgz", + "integrity": "sha512-1ngXYb+V9UT5h+PxNRa1O1FYguZK/XL+gkeqvp7EdHlB9oHUG0eYRo/vY5inBdcqo3RkPMC58/H94HvkbfGdyg==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", @@ -1375,30 +1506,12 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-to-parse5": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", - "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", - "dev": true, - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/hast-util-to-text": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.0.tgz", - "integrity": "sha512-EWiE1FSArNBPUo1cKWtzqgnuRQwEeQbQtnFJRYV1hb1BWDgrAlBU0ExptvZMM/KSA82cDpm2sFGf3Dmc5Mza3w==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", @@ -1415,6 +1528,7 @@ "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0" }, @@ -1428,6 +1542,7 @@ "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", @@ -1445,6 +1560,7 @@ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz", "integrity": "sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=12.0.0" } @@ -1454,22 +1570,25 @@ "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/inline-style-parser": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.2.tgz", - "integrity": "sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ==", - "dev": true + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", + "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==", + "dev": true, + "license": "MIT" }, "node_modules/is-alphabetical": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -1480,6 +1599,7 @@ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", "dev": true, + "license": "MIT", "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" @@ -1489,28 +1609,17 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "dev": true, + "license": "MIT", "dependencies": { - "builtin-modules": "^3.3.0" + "hasown": "^2.0.2" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, - "dependencies": { - "hasown": "^2.0.0" + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1521,6 +1630,7 @@ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -1531,6 +1641,7 @@ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -1540,13 +1651,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -1555,10 +1668,11 @@ } }, "node_modules/lightningcss": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.23.0.tgz", - "integrity": "sha512-SEArWKMHhqn/0QzOtclIwH5pXIYQOUEkF8DgICd/105O+GCgd7jxjNod/QPnBCSWvpRHQBGVz5fQ9uScby03zA==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.27.0.tgz", + "integrity": "sha512-8f7aNmS1+etYSLHht0fQApPc2kNO8qGRutifN5rVIc6Xo6ABsEbqOr758UwI7ALVbTt4x1fllKt0PYgzD9S3yQ==", "dev": true, + "license": "MPL-2.0", "dependencies": { "detect-libc": "^1.0.3" }, @@ -1570,25 +1684,27 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-darwin-arm64": "1.23.0", - "lightningcss-darwin-x64": "1.23.0", - "lightningcss-freebsd-x64": "1.23.0", - "lightningcss-linux-arm-gnueabihf": "1.23.0", - "lightningcss-linux-arm64-gnu": "1.23.0", - "lightningcss-linux-arm64-musl": "1.23.0", - "lightningcss-linux-x64-gnu": "1.23.0", - "lightningcss-linux-x64-musl": "1.23.0", - "lightningcss-win32-x64-msvc": "1.23.0" + "lightningcss-darwin-arm64": "1.27.0", + "lightningcss-darwin-x64": "1.27.0", + "lightningcss-freebsd-x64": "1.27.0", + "lightningcss-linux-arm-gnueabihf": "1.27.0", + "lightningcss-linux-arm64-gnu": "1.27.0", + "lightningcss-linux-arm64-musl": "1.27.0", + "lightningcss-linux-x64-gnu": "1.27.0", + "lightningcss-linux-x64-musl": "1.27.0", + "lightningcss-win32-arm64-msvc": "1.27.0", + "lightningcss-win32-x64-msvc": "1.27.0" } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.23.0.tgz", - "integrity": "sha512-kl4Pk3Q2lnE6AJ7Qaij47KNEfY2/UXRZBT/zqGA24B8qwkgllr/j7rclKOf1axcslNXvvUdztjo4Xqh39Yq1aA==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.27.0.tgz", + "integrity": "sha512-Gl/lqIXY+d+ySmMbgDf0pgaWSqrWYxVHoc88q+Vhf2YNzZ8DwoRzGt5NZDVqqIW5ScpSnmmjcgXP87Dn2ylSSQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "darwin" @@ -1602,13 +1718,14 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.23.0.tgz", - "integrity": "sha512-KeRFCNoYfDdcolcFXvokVw+PXCapd2yHS1Diko1z1BhRz/nQuD5XyZmxjWdhmhN/zj5sH8YvWsp0/lPLVzqKpg==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.27.0.tgz", + "integrity": "sha512-0+mZa54IlcNAoQS9E0+niovhyjjQWEMrwW0p2sSdLRhLDc8LMQ/b67z7+B5q4VmjYCMSfnFi3djAAQFIDuj/Tg==", "cpu": [ "x64" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "darwin" @@ -1622,13 +1739,14 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.23.0.tgz", - "integrity": "sha512-xhnhf0bWPuZxcqknvMDRFFo2TInrmQRWZGB0f6YoAsZX8Y+epfjHeeOIGCfAmgF0DgZxHwYc8mIR5tQU9/+ROA==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.27.0.tgz", + "integrity": "sha512-n1sEf85fePoU2aDN2PzYjoI8gbBqnmLGEhKq7q0DKLj0UTVmOTwDC7PtLcy/zFxzASTSBlVQYJUhwIStQMIpRA==", "cpu": [ "x64" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "freebsd" @@ -1642,13 +1760,14 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.23.0.tgz", - "integrity": "sha512-fBamf/bULvmWft9uuX+bZske236pUZEoUlaHNBjnueaCTJ/xd8eXgb0cEc7S5o0Nn6kxlauMBnqJpF70Bgq3zg==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.27.0.tgz", + "integrity": "sha512-MUMRmtdRkOkd5z3h986HOuNBD1c2lq2BSQA1Jg88d9I7bmPGx08bwGcnB75dvr17CwxjxD6XPi3Qh8ArmKFqCA==", "cpu": [ "arm" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -1662,13 +1781,14 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.23.0.tgz", - "integrity": "sha512-RS7sY77yVLOmZD6xW2uEHByYHhQi5JYWmgVumYY85BfNoVI3DupXSlzbw+b45A9NnVKq45+oXkiN6ouMMtTwfg==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.27.0.tgz", + "integrity": "sha512-cPsxo1QEWq2sfKkSq2Bq5feQDHdUEwgtA9KaB27J5AX22+l4l0ptgjMZZtYtUnteBofjee+0oW1wQ1guv04a7A==", "cpu": [ "arm64" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -1682,13 +1802,14 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.23.0.tgz", - "integrity": "sha512-cU00LGb6GUXCwof6ACgSMKo3q7XYbsyTj0WsKHLi1nw7pV0NCq8nFTn6ZRBYLoKiV8t+jWl0Hv8KkgymmK5L5g==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.27.0.tgz", + "integrity": "sha512-rCGBm2ax7kQ9pBSeITfCW9XSVF69VX+fm5DIpvDZQl4NnQoMQyRwhZQm9pd59m8leZ1IesRqWk2v/DntMo26lg==", "cpu": [ "arm64" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -1702,13 +1823,14 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.23.0.tgz", - "integrity": "sha512-q4jdx5+5NfB0/qMbXbOmuC6oo7caPnFghJbIAV90cXZqgV8Am3miZhC4p+sQVdacqxfd+3nrle4C8icR3p1AYw==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.27.0.tgz", + "integrity": "sha512-Dk/jovSI7qqhJDiUibvaikNKI2x6kWPN79AQiD/E/KeQWMjdGe9kw51RAgoWFDi0coP4jinaH14Nrt/J8z3U4A==", "cpu": [ "x64" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -1722,13 +1844,14 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.23.0.tgz", - "integrity": "sha512-G9Ri3qpmF4qef2CV/80dADHKXRAQeQXpQTLx7AiQrBYQHqBjB75oxqj06FCIe5g4hNCqLPnM9fsO4CyiT1sFSQ==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.27.0.tgz", + "integrity": "sha512-QKjTxXm8A9s6v9Tg3Fk0gscCQA1t/HMoF7Woy1u68wCk5kS4fR+q3vXa1p3++REW784cRAtkYKrPy6JKibrEZA==", "cpu": [ "x64" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "linux" @@ -1741,14 +1864,36 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.27.0.tgz", + "integrity": "sha512-/wXegPS1hnhkeG4OXQKEMQeJd48RDC3qdh+OA8pCuOPCyvnm/yEayrJdJVqzBsqpy1aJklRCVxscpFur80o6iQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.23.0.tgz", - "integrity": "sha512-1rcBDJLU+obPPJM6qR5fgBUiCdZwZLafZM5f9kwjFLkb/UBNIzmae39uCSmh71nzPCTXZqHbvwu23OWnWEz+eg==", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.27.0.tgz", + "integrity": "sha512-/OJLj94Zm/waZShL8nB5jsNj3CfNATLCTyFxZyouilfTmSoLDX7VlVAmhPHoZWVFp4vdmoiEbPEYC8HID3m6yw==", "cpu": [ "x64" ], "dev": true, + "license": "MPL-2.0", "optional": true, "os": [ "win32" @@ -1766,6 +1911,7 @@ "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -1776,6 +1922,7 @@ "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-3.1.0.tgz", "integrity": "sha512-CEbNVoSikAxwDMDPjXlqlFYiZLkDJHwyGu/MfOsJnF3d7f3tds5J3z8s/l9TMXhzfsJCCJEAsD78842mwmg0PQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "devlop": "^1.0.0", @@ -1791,6 +1938,7 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^6.0.0" }, @@ -1802,10 +1950,11 @@ } }, "node_modules/mdast-util-from-markdown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", - "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", "dev": true, + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", @@ -1826,10 +1975,11 @@ } }, "node_modules/mdast-util-mdx-expression": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", - "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", @@ -1844,10 +1994,11 @@ } }, "node_modules/mdast-util-mdx-jsx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.0.0.tgz", - "integrity": "sha512-XZuPPzQNBPAlaqsTTgRrcJnyFbSOBovSadFgbFu8SnuNgm+6Bdx1K+IWoitsmj6Lq6MNtI+ytOqwN70n//NaBA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.3.tgz", + "integrity": "sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", @@ -1859,7 +2010,6 @@ "mdast-util-to-markdown": "^2.0.0", "parse-entities": "^4.0.0", "stringify-entities": "^4.0.0", - "unist-util-remove-position": "^5.0.0", "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" }, @@ -1873,6 +2023,7 @@ "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", @@ -1887,10 +2038,11 @@ } }, "node_modules/mdast-util-phrasing": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.0.0.tgz", - "integrity": "sha512-xadSsJayQIucJ9n053dfQwVu1kuXg7jCTdYsMK8rqzKZh52nLfSH/k0sAxE0u+pj/zKZX+o5wB+ML5mRayOxFA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", "dev": true, + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" @@ -1901,10 +2053,11 @@ } }, "node_modules/mdast-util-to-hast": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.1.0.tgz", - "integrity": "sha512-/e2l/6+OdGp/FB+ctrJ9Avz71AN/GRH3oi/3KAx/kMnoUsD6q0woXlDT8lLEeViVKE7oZxE7RXzvO3T8kF2/sA==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", @@ -1926,6 +2079,7 @@ "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", @@ -1946,6 +2100,7 @@ "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", "dev": true, + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0" }, @@ -1969,6 +2124,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", @@ -1990,9 +2146,9 @@ } }, "node_modules/micromark-core-commonmark": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", - "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", + "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", "dev": true, "funding": [ { @@ -2004,6 +2160,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", @@ -2038,6 +2195,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", @@ -2059,6 +2217,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "devlop": "^1.0.0", "micromark-util-character": "^2.0.0", @@ -2081,6 +2240,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -2101,6 +2261,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", @@ -2123,6 +2284,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", @@ -2131,9 +2293,9 @@ } }, "node_modules/micromark-util-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.0.1.tgz", - "integrity": "sha512-3wgnrmEAJ4T+mGXAUfMvMAbxU9RDG43XmGce4j6CwPtVxB3vfwXSZ6KhFwDzZ3mZHhmPimMAXg71veiBGzeAZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "dev": true, "funding": [ { @@ -2145,6 +2307,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -2165,6 +2328,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0" } @@ -2184,6 +2348,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", @@ -2205,6 +2370,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-chunked": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -2225,6 +2391,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0" } @@ -2244,6 +2411,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "decode-named-character-reference": "^1.0.0", "micromark-util-character": "^2.0.0", @@ -2265,7 +2433,8 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-html-tag-name": { "version": "2.0.0", @@ -2281,7 +2450,8 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-normalize-identifier": { "version": "2.0.0", @@ -2298,6 +2468,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0" } @@ -2317,6 +2488,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-types": "^2.0.0" } @@ -2336,6 +2508,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", @@ -2343,9 +2516,9 @@ } }, "node_modules/micromark-util-subtokenize": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz", - "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", + "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", "dev": true, "funding": [ { @@ -2357,6 +2530,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", @@ -2378,7 +2552,8 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-types": { "version": "2.0.0", @@ -2394,13 +2569,15 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/mime": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", "dev": true, + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -2409,16 +2586,18 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, "node_modules/parse-entities": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^2.0.0", "character-entities": "^2.0.0", @@ -2435,18 +2614,20 @@ } }, "node_modules/parse-entities/node_modules/@types/unist": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", - "dev": true + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "dev": true, + "license": "MIT" }, "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.0.tgz", + "integrity": "sha512-ZkDsAOcxsUMZ4Lz5fVciOehNcJ+Gb8gTzcA4yl3wnc273BAybYWrQ+Ks/OjCjSEpjvQkDSeZbybK9qj2VHHdGA==", "dev": true, + "license": "MIT", "dependencies": { - "entities": "^4.4.0" + "entities": "^4.5.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" @@ -2456,62 +2637,59 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/preact": { - "version": "10.19.3", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.19.3.tgz", - "integrity": "sha512-nHHTeFVBTHRGxJXKkKu5hT8C/YWBkPso4/Gad6xuj5dbptt9iF9NZr9pHbPhBrnT2klheu7mHTxTZ/LjwJiEiQ==", + "version": "10.24.3", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.24.3.tgz", + "integrity": "sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA==", + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/preact" } }, "node_modules/preact-render-to-string": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-6.3.1.tgz", - "integrity": "sha512-NQ28WrjLtWY6lKDlTxnFpKHZdpjfF+oE6V4tZ0rTrunHrtZp6Dm0oFrcJalt/5PNeqJz4j1DuZDS0Y6rCBoqDA==", + "version": "6.5.11", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-6.5.11.tgz", + "integrity": "sha512-ubnauqoGczeGISiOh6RjX0/cdaF8v/oDXIjO85XALCQjwQP+SB4RDXXtvZ6yTYSjG+PC1QRP2AhPgCEsM2EvUw==", "dev": true, - "dependencies": { - "pretty-format": "^3.8.0" - }, + "license": "MIT", "peerDependencies": { "preact": ">=10" } }, - "node_modules/pretty-format": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", - "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==", - "dev": true - }, "node_modules/property-information": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.1.tgz", - "integrity": "sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/rehype": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/rehype/-/rehype-13.0.1.tgz", - "integrity": "sha512-AcSLS2mItY+0fYu9xKxOu1LhUZeBZZBx8//5HKzF+0XP+eP8+6a5MXn2+DW2kfXR6Dtp1FEXMVrjyKAcvcU8vg==", + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/rehype/-/rehype-13.0.2.tgz", + "integrity": "sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "rehype-parse": "^9.0.0", @@ -2524,10 +2702,11 @@ } }, "node_modules/rehype-highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-highlight/-/rehype-highlight-7.0.0.tgz", - "integrity": "sha512-QtobgRgYoQaK6p1eSr2SD1i61f7bjF2kZHAQHxeCHAuJf7ZUDMvQ7owDq9YTkmar5m5TSUol+2D3bp3KfJf/oA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/rehype-highlight/-/rehype-highlight-7.0.1.tgz", + "integrity": "sha512-dB/vVGFsbm7xPglqnYbg0ABg6rAuIWKycTvuXaOO27SgLoOFNoTlniTBtAxp3n5ZyMioW1a3KwiNqgjkb6Skjg==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "hast-util-to-text": "^4.0.0", @@ -2541,10 +2720,11 @@ } }, "node_modules/rehype-parse": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.0.tgz", - "integrity": "sha512-WG7nfvmWWkCR++KEkZevZb/uw41E8TsH4DsY9UxsTbIXCVGbAs4S+r8FrQ+OtH5EEQAs+5UxKC42VinkmpA1Yw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz", + "integrity": "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "hast-util-from-html": "^2.0.0", @@ -2560,6 +2740,7 @@ "resolved": "https://registry.npmjs.org/rehype-react/-/rehype-react-8.0.0.tgz", "integrity": "sha512-vzo0YxYbB2HE+36+9HWXVdxNoNDubx63r5LBzpxBGVWM8s9mdnMdbmuJBAX6TTyuGdZjZix6qU3GcSuKCIWivw==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "hast-util-to-jsx-runtime": "^2.0.0", @@ -2571,10 +2752,11 @@ } }, "node_modules/rehype-stringify": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.0.tgz", - "integrity": "sha512-1TX1i048LooI9QoecrXy7nGFFbFSufxVRAfc6Y9YMRAi56l+oB0zP51mLSV312uRuvVLPV1opSlJmslozR1XHQ==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz", + "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", "dev": true, + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "hast-util-to-html": "^9.0.0", @@ -2590,6 +2772,7 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, + "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -2607,17 +2790,19 @@ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, "node_modules/rollup": { - "version": "4.9.6", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.6.tgz", - "integrity": "sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==", + "version": "4.24.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.1.tgz", + "integrity": "sha512-2lhtdsnyxlfBAZVh9tfriEc1nV9HxjQGnqEpd7z7cWXuLbI4jHWDhAvw6JGs0AVcnYqv0gL7Mjuj/utxW2wPBw==", "dev": true, + "license": "MIT", "dependencies": { - "@types/estree": "1.0.5" + "@types/estree": "1.0.6" }, "bin": { "rollup": "dist/bin/rollup" @@ -2627,19 +2812,24 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.9.6", - "@rollup/rollup-android-arm64": "4.9.6", - "@rollup/rollup-darwin-arm64": "4.9.6", - "@rollup/rollup-darwin-x64": "4.9.6", - "@rollup/rollup-linux-arm-gnueabihf": "4.9.6", - "@rollup/rollup-linux-arm64-gnu": "4.9.6", - "@rollup/rollup-linux-arm64-musl": "4.9.6", - "@rollup/rollup-linux-riscv64-gnu": "4.9.6", - "@rollup/rollup-linux-x64-gnu": "4.9.6", - "@rollup/rollup-linux-x64-musl": "4.9.6", - "@rollup/rollup-win32-arm64-msvc": "4.9.6", - "@rollup/rollup-win32-ia32-msvc": "4.9.6", - "@rollup/rollup-win32-x64-msvc": "4.9.6", + "@rollup/rollup-android-arm-eabi": "4.24.1", + "@rollup/rollup-android-arm64": "4.24.1", + "@rollup/rollup-darwin-arm64": "4.24.1", + "@rollup/rollup-darwin-x64": "4.24.1", + "@rollup/rollup-freebsd-arm64": "4.24.1", + "@rollup/rollup-freebsd-x64": "4.24.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.1", + "@rollup/rollup-linux-arm-musleabihf": "4.24.1", + "@rollup/rollup-linux-arm64-gnu": "4.24.1", + "@rollup/rollup-linux-arm64-musl": "4.24.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.1", + "@rollup/rollup-linux-riscv64-gnu": "4.24.1", + "@rollup/rollup-linux-s390x-gnu": "4.24.1", + "@rollup/rollup-linux-x64-gnu": "4.24.1", + "@rollup/rollup-linux-x64-musl": "4.24.1", + "@rollup/rollup-win32-arm64-msvc": "4.24.1", + "@rollup/rollup-win32-ia32-msvc": "4.24.1", + "@rollup/rollup-win32-x64-msvc": "4.24.1", "fsevents": "~2.3.2" } }, @@ -2648,6 +2838,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -2655,23 +2846,26 @@ "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" }, "node_modules/space-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/stringify-entities": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", - "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", "dev": true, + "license": "MIT", "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" @@ -2682,12 +2876,13 @@ } }, "node_modules/style-to-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.5.tgz", - "integrity": "sha512-rDRwHtoDD3UMMrmZ6BzOW0naTjMsVZLIjsGleSKS/0Oz+cgCfAPRspaqJuE8rDzpKha/nEvnM0IF4seEAZUTKQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz", + "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==", "dev": true, + "license": "MIT", "dependencies": { - "inline-style-parser": "0.2.2" + "inline-style-parser": "0.2.4" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -2695,6 +2890,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -2707,34 +2903,38 @@ "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/trough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", - "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", + "license": "0BSD" }, "node_modules/tsx": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.0.tgz", - "integrity": "sha512-I+t79RYPlEYlHn9a+KzwrvEwhJg35h/1zHsLC2JXvhC2mdynMv6Zxzvhv5EMV6VF5qJlLlkSnMVvdZV3PSIGcg==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz", + "integrity": "sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==", "dev": true, + "license": "MIT", "dependencies": { - "esbuild": "~0.19.10", - "get-tsconfig": "^4.7.2" + "esbuild": "~0.23.0", + "get-tsconfig": "^4.7.5" }, "bin": { "tsx": "dist/cli.mjs" @@ -2747,10 +2947,11 @@ } }, "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -2760,16 +2961,18 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" }, "node_modules/unified": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", @@ -2789,6 +2992,7 @@ "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" @@ -2803,6 +3007,7 @@ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" }, @@ -2816,6 +3021,7 @@ "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" }, @@ -2824,25 +3030,12 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-remove-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", - "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", - "dev": true, - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" }, @@ -2856,6 +3049,7 @@ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", @@ -2871,6 +3065,7 @@ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" @@ -2881,13 +3076,13 @@ } }, "node_modules/vfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" }, "funding": { @@ -2896,10 +3091,11 @@ } }, "node_modules/vfile-location": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", - "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "vfile": "^6.0.0" @@ -2914,6 +3110,7 @@ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", "dev": true, + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" @@ -2928,6 +3125,7 @@ "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2938,6 +3136,7 @@ "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" diff --git a/package.json b/package.json index f93484952c..9a39417b08 100644 --- a/package.json +++ b/package.json @@ -13,10 +13,10 @@ }, "devDependencies": { "@rollup/plugin-node-resolve": "^15.2.1", - "@rollup/plugin-typescript": "^11.0.0", + "@rollup/plugin-typescript": "^12.0.0", "@rollup/plugin-url": "^8.0.1", "@swc/core": "^1.3.92", - "@types/node": "^20.8.3", + "@types/node": "^22.0.0", "lightningcss": "^1.22.0", "preact-render-to-string": "^6.2.1", "rehype": "^13.0.0", From 0da906fc9348e5d0fa8713b8cafea83f5ff8b4ab Mon Sep 17 00:00:00 2001 From: NotSquidDev Date: Sun, 27 Oct 2024 10:18:26 +0000 Subject: [PATCH 11/39] New Crowdin updates (#1954) --- .../assets/computercraft/lang/ja_jp.json | 2 - .../assets/computercraft/lang/tr_tr.json | 138 +++++++++--------- 2 files changed, 67 insertions(+), 73 deletions(-) diff --git a/projects/common/src/main/resources/assets/computercraft/lang/ja_jp.json b/projects/common/src/main/resources/assets/computercraft/lang/ja_jp.json index eaf63c94d0..1c897fb2f8 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/ja_jp.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/ja_jp.json @@ -38,8 +38,6 @@ "commands.computercraft.generic.additional_rows": "%d行を追加…", "commands.computercraft.generic.exception": "未処理の例外 (%s)", "commands.computercraft.generic.no": "N", - "commands.computercraft.generic.no_position": "", - "commands.computercraft.generic.position": "%s, %s, %s", "commands.computercraft.generic.yes": "Y", "commands.computercraft.help.desc": "このヘルプメッセージを表示します", "commands.computercraft.help.no_children": "%s にサブコマンドはありません", diff --git a/projects/common/src/main/resources/assets/computercraft/lang/tr_tr.json b/projects/common/src/main/resources/assets/computercraft/lang/tr_tr.json index 776440a906..2973b84d2f 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/tr_tr.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/tr_tr.json @@ -3,10 +3,10 @@ "argument.computercraft.computer.distance": "Varlığa olan mesafe", "argument.computercraft.computer.family": "Bilgisayar ailesi", "argument.computercraft.computer.id": "Bilgisayar Kimliği", - "argument.computercraft.computer.instance": "Benzersiz örnek kimliği", + "argument.computercraft.computer.instance": "Eşsiz oluşum kimliği", "argument.computercraft.computer.label": "Bilgisayar etiketi", - "argument.computercraft.computer.many_matching": "Birden fazla bilgisayar eşleşiyor '%s' (örnekler %s)", - "argument.computercraft.computer.no_matching": "Eşleşen bilgisayar yok '%s'", + "argument.computercraft.computer.many_matching": "'%s' ile birden fazla bilgisayar eşleşiyor (%s oluşumları)", + "argument.computercraft.computer.no_matching": "'%s' ile eşleşen bilgisayar yok", "argument.computercraft.tracking_field.no_field": "Bilinmeyen alan '%s'", "argument.computercraft.unknown_computer_family": "Bilinmeyen bilgisayar ailesi '%s'", "block.computercraft.cable": "Ağ Kablosu", @@ -18,73 +18,71 @@ "block.computercraft.monitor_normal": "Monitör", "block.computercraft.printer": "Yazıcı", "block.computercraft.speaker": "Hoparlör", - "block.computercraft.turtle_advanced": "Gelişmiş Kaplumbağa", - "block.computercraft.turtle_advanced.upgraded": "Gelişmiş %s Kaplumbağa", - "block.computercraft.turtle_advanced.upgraded_twice": "Gelişmiş %s %s Kaplumbağa", - "block.computercraft.turtle_normal": "Kaplumbağa", - "block.computercraft.turtle_normal.upgraded": "%s Kaplumbağa", - "block.computercraft.turtle_normal.upgraded_twice": "%s %s Kaplumbağa", + "block.computercraft.turtle_advanced": "Gelişmiş Turtle", + "block.computercraft.turtle_advanced.upgraded": "Gelişmiş %s Turtle", + "block.computercraft.turtle_advanced.upgraded_twice": "Gelişmiş %s %s Turtle", + "block.computercraft.turtle_normal": "Turtle", + "block.computercraft.turtle_normal.upgraded": "%s Turtle", + "block.computercraft.turtle_normal.upgraded_twice": "%s %s Turtle", "block.computercraft.wired_modem": "Kablolu Modem", "block.computercraft.wired_modem_full": "Kablolu Modem", - "block.computercraft.wireless_modem_advanced": "Ender Modem", + "block.computercraft.wireless_modem_advanced": "Ender Modemi", "block.computercraft.wireless_modem_normal": "Kablosuz Modem", "chat.computercraft.wired_modem.peripheral_connected": "Çevre birimi \"%s\" ağa bağlandı", - "chat.computercraft.wired_modem.peripheral_disconnected": "Çevre birimi \"%s\" ağ ile bağlantısı kesildi", - "commands.computercraft.desc": "/computercraft komutu, bilgisayarları kontrol etmek ve bilgisayarlarla etkileşimde bulunmak için çeşitli hata ayıklama ve yönetici araçları sağlar.", + "chat.computercraft.wired_modem.peripheral_disconnected": "Çevre birimi \"%s\" ağdan koptu", + "commands.computercraft.desc": "/computercraft komutu, bilgisayar kontrolü ve etkileşimi için çeşitli hata ayıklama ve yönetici araçları sağlar.", "commands.computercraft.dump.action": "Bu bilgisayar hakkında daha fazla bilgi görüntüle", - "commands.computercraft.dump.desc": "Tüm bilgisayarların durumunu veya bir bilgisayarla ilgili belirli bilgileri görüntüleme. Bilgisayarın örnek kimliğini (örn. 123), bilgisayar kimliğini (örn. #123) ya da etiketini (örn. \"@Bilgisayar\") belirtebilirsiniz.", + "commands.computercraft.dump.desc": "Tüm bilgisayarların durumunu veya bir bilgisayara özgü bilgileri göster. Bilgisayarın oluşum kimliğini (örn. 123), bilgisayar kimliğini (örn. #123) ya da etiketini (örn. \"@Bilgisayarım\") belirtebilirsiniz.", "commands.computercraft.dump.open_path": "Bu bilgisayarın dosyalarını görüntüle", - "commands.computercraft.dump.synopsis": "Bilgisayarların durumunu görüntüle.", - "commands.computercraft.generic.additional_rows": "%d ek satır…", + "commands.computercraft.dump.synopsis": "Bilgisayarların durumunu göster.", + "commands.computercraft.generic.additional_rows": "Fazladan %d satır…", "commands.computercraft.generic.exception": "Beklenmeyen durum (%s)", - "commands.computercraft.generic.no": "H", - "commands.computercraft.generic.no_position": "", - "commands.computercraft.generic.position": "%s, %s, %s", - "commands.computercraft.generic.yes": "E", - "commands.computercraft.help.desc": "Bu yardım mesajını görüntüler", - "commands.computercraft.help.no_children": "%s alt komutları yok", - "commands.computercraft.help.no_command": "Böyle bir komut yok '%s'", - "commands.computercraft.help.synopsis": "Belirli bir komut için yardım sağlar", - "commands.computercraft.queue.desc": "Komut bilgisayarına bir computer_command olayı gönder, ek argümanları geçerek. Bu çoğunlukla harita yapımcıları için tasarlanmıştır ve /trigger'ın daha bilgisayar dostu bir versiyonu olarak işlev görür. Herhangi bir oyuncu komutu çalıştırabilir, bu da büyük olasılıkla bir metin bileşeninin tıklama olayı aracılığıyla yapılır.", + "commands.computercraft.generic.no": "N", + "commands.computercraft.generic.yes": "Y", + "commands.computercraft.help.desc": "Bu yardım mesajını gösterir", + "commands.computercraft.help.no_children": "%s, hiçbir alt komuta sahip değil", + "commands.computercraft.help.no_command": "'%s' gibi bir komut yok", + "commands.computercraft.help.synopsis": "Belirli bir komut hakkında yardım göster", + "commands.computercraft.queue.desc": "Bir komut bilgisayarına ek argümanları da girerek bir computer_command olayı gönder. Bu esasen harita yapımcıları için tasarlanmıştır ve /trigger komutunun daha bilgisayar dostu bir versiyonu olarak işlev görür. Bu komut herhangi bir oyuncu tarafından çalıştırılabilir, bu da büyük ihtimalle bir metin bileşeninin tıklama olayı ile olur.", "commands.computercraft.queue.synopsis": "Bir komut bilgisayarına computer_command olayı gönder", - "commands.computercraft.shutdown.desc": "Listelenen bilgisayarları veya hiçbiri belirtilmemişse tümünü kapatma. Bilgisayarın örnek kimliğini (örn. 123), bilgisayar kimliğini (örn. #123) ya da etiketini (örn. \"@Bilgisayar\") belirtebilirsiniz.", - "commands.computercraft.shutdown.done": "%s/%s bilgisayarı kapat", + "commands.computercraft.shutdown.desc": "Listelenen bilgisayarları veya hiçbiri belirtilmemişse tümünü kapat. Bilgisayarın oluşum kimliğini (örn. 123), bilgisayar kimliğini (örn. #123) ya da etiketini (örn. \"@Bilgisayarım\") belirtebilirsiniz.", + "commands.computercraft.shutdown.done": "%s/%s bilgisayar kapatıldı", "commands.computercraft.shutdown.synopsis": "Bilgisayarları uzaktan kapat.", "commands.computercraft.synopsis": "Bilgisayarları kontrol etmek için çeşitli komutlar.", - "commands.computercraft.tp.action": "Bu bilgisayara ışınlan", - "commands.computercraft.tp.desc": "Bir bilgisayarın bulunduğu yere ışınlan. Bilgisayarın örnek kimliğini (örn. 123), bilgisayar kimliğini (örn. #123) belirtebilirsiniz.", - "commands.computercraft.tp.synopsis": "Belirli bir bilgisayara ışınlan.", - "commands.computercraft.track.desc": "Bilgisayarların ne kadar süre çalıştığını ve kaç olay işlediğini takip et. Bu, /forge track'e benzer bir şekilde bilgi sunar ve gecikmeyi teşhis etmek için yararlı olabilir.", + "commands.computercraft.tp.action": "Bu bilgisayara ışınla", + "commands.computercraft.tp.desc": "Bir bilgisayarın konumuna ışınla. Bilgisayarın oluşum kimliğini (örn. 123) ya da bilgisayar kimliğini (örn. #123) belirtebilirsiniz.", + "commands.computercraft.tp.synopsis": "Belirli bir bilgisayara ışınla.", + "commands.computercraft.track.desc": "Bilgisayarların ne kadar süre çalıştığını ve kaç olay işlediğini izlemeye al. Bu, /forge track komutuna benzer şekilde bilgi sunar ve gecikmeyi tanılamaya yardımcı olabilir.", "commands.computercraft.track.dump.computer": "Bilgisayar", - "commands.computercraft.track.dump.desc": "Bilgisayar takibinin en son sonuçlarını boşalt.", - "commands.computercraft.track.dump.no_timings": "Zamanlama mevcut değil", - "commands.computercraft.track.dump.synopsis": "En son izleme sonuçlarını boşalt", - "commands.computercraft.track.start.desc": "Tüm bilgisayarların yürütme sürelerini ve olay sayılarını izlemeye başla. Bu, önceki çalıştırmaların sonuçlarını atacaktır.", - "commands.computercraft.track.start.stop": "İzlemeyi durdurmak ve sonuçları görüntülemek için %s çalıştır", - "commands.computercraft.track.start.synopsis": "Tüm bilgisayarları izlemeyi başlat", + "commands.computercraft.track.dump.desc": "Bilgisayar izlemenin en son sonuç dökümünü göster.", + "commands.computercraft.track.dump.no_timings": "Hiçbir zamanlama mevcut değil", + "commands.computercraft.track.dump.synopsis": "En son izleme sonuç dökümünü göster", + "commands.computercraft.track.start.desc": "Tüm bilgisayarların yürütme sürelerini ve olay sayılarını izlemeye başla. Bu, önceki çalıştırmaların sonuçlarını silecektir.", + "commands.computercraft.track.start.stop": "%s ile izlemeyi durdur ve sonuçları görüntüle", + "commands.computercraft.track.start.synopsis": "Tüm bilgisayarları izlemeye başla", "commands.computercraft.track.stop.action": "İzlemeyi durdurmak için tıkla", - "commands.computercraft.track.stop.desc": "Tüm bilgisayarların olaylarını ve yürütme sürelerini izlemeyi durdur", - "commands.computercraft.track.stop.not_enabled": "Şu anda bilgisayarlar izlenmiyor", + "commands.computercraft.track.stop.desc": "Tüm bilgisayarların yürütme sürelerini ve olaylarını izlemeyi durdur", + "commands.computercraft.track.stop.not_enabled": "Şu anda hiçbir bilgisayar izlenmiyor", "commands.computercraft.track.stop.synopsis": "Tüm bilgisayarları izlemeyi durdur", - "commands.computercraft.track.synopsis": "Bilgisayarların yürütme sürelerini takip et.", - "commands.computercraft.turn_on.desc": "Listelenen bilgisayarları aç. Bilgisayarın örnek kimliğini (örn. 123), bilgisayar kimliğini (örn. #123) ya da etiketini (örn. \"@Bilgisayar\") belirtebilirsiniz.", + "commands.computercraft.track.synopsis": "Bilgisayarların yürütme sürelerini izlemeye al.", + "commands.computercraft.turn_on.desc": "Listelenen bilgisayarları aç. Bilgisayarın oluşum kimliğini (örn. 123), bilgisayar kimliğini (örn. #123) ya da etiketini (örn. \"@Bilgisayarım\") belirtebilirsiniz.", "commands.computercraft.turn_on.done": "%s/%s bilgisayar açıldı", "commands.computercraft.turn_on.synopsis": "Bilgisayarları uzaktan aç.", "commands.computercraft.view.action": "Bu bilgisayarı görüntüle", - "commands.computercraft.view.desc": "Bir bilgisayarın terminalinin açılması, bir bilgisayarın uzaktan kontrolüne izin verir. Bu, kaplumbağanın envanterlerine erişim sağlamaz. Bilgisayarın örnek kimliğini (örn. 123), bilgisayar kimliğini (örn. #123) belirtebilirsiniz.", - "commands.computercraft.view.not_player": "Oyuncu olmayanlar için terminal açılamıyor", + "commands.computercraft.view.desc": "Bir bilgisayarın terminalini aç ve uzaktan kontrole izin ver. Bununla Turtle envanterlerine erişilemez. Bilgisayarın oluşum kimliğini (örn. 123) ya da bilgisayar kimliğini (örn. #123) belirtebilirsiniz.", + "commands.computercraft.view.not_player": "Oyuncu olmayanlar için terminal açılamaz", "commands.computercraft.view.synopsis": "Bir bilgisayarın terminalini görüntüle.", "gui.computercraft.config.command_require_creative": "Komut bilgisayarları yaratıcı modu gerektirir", - "gui.computercraft.config.command_require_creative.tooltip": "Oyuncuların komut bilgisayarlarıyla etkileşime girebilmesi için yaratıcı modda olmalarını\nve op'lu olmalarını gerektirir. Bu, vanilla'nın Komut blokları için varsayılan davranıştır.", + "gui.computercraft.config.command_require_creative.tooltip": "Oyuncuların komut bilgisayarıyla etkileşime girebilmesi için yaratıcı modda\nve yetkili olmalarını gerektir. Bu, vanilla Komut blokları için varsayılan davranıştır.", "gui.computercraft.config.computer_space_limit": "Bilgisayar alan sınırı (bayt)", - "gui.computercraft.config.computer_space_limit.tooltip": "Bilgisayarlar ve kaplumbağalar için bayt cinsinden disk alanı sınırı.", + "gui.computercraft.config.computer_space_limit.tooltip": "Bilgisayar ve Turtle için bayt cinsinden disk alanı sınırı.", "gui.computercraft.config.default_computer_settings": "Varsayılan Bilgisayar ayarları", - "gui.computercraft.config.default_computer_settings.tooltip": "Yeni bilgisayarlarda ayarlanacak varsayılan sistem ayarlarının virgülle\nayrılmış bir listesi.\nÖrnek: \"shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false\"\ntüm otomatik tamamlamayı devre dışı bırakır.", - "gui.computercraft.config.disabled_generic_methods": "Devre dışı bırakılmış genel yöntemler", - "gui.computercraft.config.disabled_generic_methods.tooltip": "Devre dışı bırakılacak genel yöntemlerin veya yöntem kaynaklarının bir listesi.\nGenel yöntemler açık bir çevresel sağlayıcı olmadığında bir blok/blok varlığına\neklenen yöntemlerdir. Bu, envanter yöntemlerini (yani inventory.getItemDetail,\ninventory.pushItems), ve (Forge'da ise), fluid_storage ve energy_storage\nyöntemlerini içerir.\nBu listedeki yöntemler bir grup yöntem (computercraft:inventory)\nya da tek bir yöntem (computercraft:inventory#pushItems) olabilir.\n", - "gui.computercraft.config.execution": "Yürüt", + "gui.computercraft.config.default_computer_settings.tooltip": "Yeni bilgisayarlarda kullanılacak varsayılan sistem ayarlarının virgülle ayrılmış listesi.\nÖrnek: \"shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false\"\ntüm otomatik tamamlamayı devre dışı bırakacaktır.", + "gui.computercraft.config.disabled_generic_methods": "Devre dışı bırakılmış genelleyici fonksiyonlar", + "gui.computercraft.config.disabled_generic_methods.tooltip": "Devre dışı bırakılacak genelleyici fonksiyonların veya fonksiyon kaynaklarının\nbir listesi. Genelleyici fonksiyonlar (generic methods), bir bloğa/blok varlığına\nbariz bir çevre birimi sağlayıcı yok ise eklenen fonksiyonlardır. Bu,\nenvanter fonksiyonlarını (yani inventory.getItemDetail, inventory.pushItems)\nve (Forge'da ise) fluid_storage ve energy_storage fonksiyonlarını içerir.\nBu listedeki fonksiyonlar ya tüm bir fonksiyon grubu (computercraft:inventory)\nya da tek bir fonksiyon (computercraft:inventory#pushItems) olabilir.\n", + "gui.computercraft.config.execution": "Yürütme", "gui.computercraft.config.execution.computer_threads": "Bilgisayar iş parçacıkları", - "gui.computercraft.config.execution.computer_threads.tooltip": "Bilgisayarların çalışabileceği iş parçacığı sayısını ayarla. Daha yüksek bir\nsayı, aynı anda daha fazla bilgisayarın çalışabileceği anlamına gelir, ancak\ngecikmeye neden olabilir. Lütfen bazı modların 1'den yüksek iş parçacığı sayısı\nile çalışmayabileceğini unutmayın. Dikkatli kullanın.\nAralık: > 1", + "gui.computercraft.config.execution.computer_threads.tooltip": "Bilgisayarların çalışabileceği iş parçacığı sayısını ayarla. Yüksek sayılar, aynı anda\ndaha fazla bilgisayarın çalışabileceği anlamına gelir, ancak gecikmeye neden olabilir. \nLütfen bazı modların 1'den fazla iş parçacığı ile çalışamayacağını unutmayın. \nDikkatli kullanın.\nAralık: > 1", "gui.computercraft.config.execution.max_main_computer_time": "Sunucu tik bilgisayar zaman sınırı", "gui.computercraft.config.execution.max_main_computer_time.tooltip": "Milisaniye cinsinden, bilgisayarın bir tik içinde yürütebileceği ideal maksimum süre.\nUnutmayın, ne kadar süreceğini söylemenin bir yolu olmadığı için büyük olasılıkla\nbu sınırı aşacağız - bu, ortalama sürenin üst sınırı olmayı\namaçlamaktadır.\nAralık: > 1", "gui.computercraft.config.execution.max_main_global_time": "Sunucu tik genel zaman sınırı", @@ -105,7 +103,7 @@ "gui.computercraft.config.http.max_requests.tooltip": "Bir bilgisayarın tek seferde yapabileceği http isteği sayısı. Ek istekler\nkuyruğa alınacak ve çalışan istekler bittiğinde gönderilecektir. Sınırsız için\n0 olarak ayarla.\nAralık: > 0", "gui.computercraft.config.http.max_websockets": "Maksimum eşzamanlı websocketleri", "gui.computercraft.config.http.max_websockets.tooltip": "Bir bilgisayarın tek seferde açık tutabileceği websocket sayısı.\nAralık: > 1", - "gui.computercraft.config.http.proxy": "Proxy", + "gui.computercraft.config.http.proxy": "Vekil sunucu", "gui.computercraft.config.http.proxy.host": "Ana bilgisayar adı", "gui.computercraft.config.http.proxy.host.tooltip": "Proxy sunucusunun ana bilgisayar adı veya IP adresi.", "gui.computercraft.config.http.proxy.port": "Port", @@ -176,25 +174,25 @@ "gui.computercraft.config.upload_max_size.tooltip": "Bayt cinsinden dosya yükleme boyut sınırı. 1 KiB ve 16 MiB aralığında olmalıdır.\nYüklemelerin tek bir tikte işlendiğini unutmayın - büyük dosyalar veya düşük ağ\nperformansı ağ iş parçacığını bekletebilir. Ve disk alanına dikkat edin!\nAralık: 1024 ~ 16777216", "gui.computercraft.config.upload_nag_delay": "Yükleme nag gecikmesi", "gui.computercraft.config.upload_nag_delay.tooltip": "Beklenmeyen içe aktarmalar hakkında bildirimde bulunacağımız saniye cinsinden gecikme. Devre dışı bırakmak için 0 olarak ayarla.\nAralık: 0 ~ 60", - "gui.computercraft.pocket_computer_overlay": "Cep bilgisayarı açık. Kapatmak için ESC tuşuna bas.", + "gui.computercraft.pocket_computer_overlay": "Cep bilgisayarı açık. Kapatmak için ESC tuşuna basın.", "gui.computercraft.terminal": "Bilgisayar terminali", "gui.computercraft.tooltip.computer_id": "Bilgisayar Kimliği: %s", "gui.computercraft.tooltip.copy": "Panoya kopyala", "gui.computercraft.tooltip.disk_id": "Disk Kimliği: %s", "gui.computercraft.tooltip.terminate": "Çalışmakta olan kodu durdur", - "gui.computercraft.tooltip.terminate.key": "Ctrl+T basılı tut", + "gui.computercraft.tooltip.terminate.key": "Ctrl+T tuşlarını basılı tut", "gui.computercraft.tooltip.turn_off": "Bu bilgisayarı kapat", - "gui.computercraft.tooltip.turn_off.key": "Ctrl+S basılı tut", + "gui.computercraft.tooltip.turn_off.key": "Ctrl+S tuşlarını basılı tut", "gui.computercraft.tooltip.turn_on": "Bu bilgisayarı aç", - "gui.computercraft.upload.failed": "Yükleme Başarısız", - "gui.computercraft.upload.failed.computer_off": "Dosyaları yüklemeden önce bilgisayarı açmalısın.", - "gui.computercraft.upload.failed.corrupted": "Dosyalar yüklenirken bozuldu. Lütfen tekrar dene.", + "gui.computercraft.upload.failed": "Karşıya Yükleme Başarısız", + "gui.computercraft.upload.failed.computer_off": "Dosyaları yüklemeden önce bilgisayarı açmalısınız.", + "gui.computercraft.upload.failed.corrupted": "Dosyalar karşıya yüklenirken bozuldu. Lütfen tekrar deneyin.", "gui.computercraft.upload.failed.generic": "Dosya yükleme başarısız (%s)", - "gui.computercraft.upload.failed.name_too_long": "Dosya adları yüklenemeyecek kadar uzun.", - "gui.computercraft.upload.failed.too_many_files": "Bu kadar dosya yüklenemiyor.", - "gui.computercraft.upload.failed.too_much": "Dosyalarınız yüklenemeyecek kadar büyük.", + "gui.computercraft.upload.failed.name_too_long": "Dosya adları karşıya yükleme için fazla uzun.", + "gui.computercraft.upload.failed.too_many_files": "Bu kadar çok dosya karşıya yüklenemez.", + "gui.computercraft.upload.failed.too_much": "Dosyalarınızın boyutu karşıya yükleme için fazla büyük.", "gui.computercraft.upload.no_response": "Dosyalar Aktarılıyor", - "gui.computercraft.upload.no_response.msg": "Bilgisayarınız aktarılan dosyalarınızı kullanmadı. %s programını çalıştırmanız ve tekrar denemeniz gerekebilir.", + "gui.computercraft.upload.no_response.msg": "Bilgisayarınız aktarılan dosyalarınızı kullanmadı. %s programını çalıştırıp tekrar denemeniz gerekebilir.", "item.computercraft.disk": "Disket", "item.computercraft.pocket_computer_advanced": "Gelişmiş Cep Bilgisayarı", "item.computercraft.pocket_computer_advanced.upgraded": "Gelişmiş %s Cep Bilgisayarı", @@ -206,30 +204,28 @@ "item.computercraft.treasure_disk": "Disket", "itemGroup.computercraft": "ComputerCraft", "tag.item.computercraft.computer": "Bilgisayarlar", - "tag.item.computercraft.dyeable": "Boyanabilir eşyalar", "tag.item.computercraft.monitor": "Monitörler", - "tag.item.computercraft.turtle": "Kaplumbağalar", - "tag.item.computercraft.turtle_can_place": "Kaplumbağa-koyulabilir eşyalar", + "tag.item.computercraft.turtle": "Turtlelar", "tag.item.computercraft.wired_modem": "Kablolu modemler", - "tracking_field.computercraft.avg": "%s (ort)", + "tracking_field.computercraft.avg": "%s (ort.)", "tracking_field.computercraft.computer_tasks.name": "Görevler", "tracking_field.computercraft.count": "%s (sayı)", "tracking_field.computercraft.fs.name": "Dosya sistemi işlemleri", - "tracking_field.computercraft.http_download.name": "HTTP indir", + "tracking_field.computercraft.http_download.name": "HTTP indirme", "tracking_field.computercraft.http_requests.name": "HTTP istekleri", "tracking_field.computercraft.http_upload.name": "HTTP yükleme", - "tracking_field.computercraft.java_allocation.name": "Java Ayırmaları", - "tracking_field.computercraft.max": "%s (maks)", + "tracking_field.computercraft.java_allocation.name": "Java'ya Ayrılan", + "tracking_field.computercraft.max": "%s (azami)", "tracking_field.computercraft.peripheral.name": "Çevre birimi çağrıları", "tracking_field.computercraft.server_tasks.name": "Sunucu görevleri", - "tracking_field.computercraft.turtle_ops.name": "Kaplumbağa işlemleri", + "tracking_field.computercraft.turtle_ops.name": "Turtle işlemleri", "tracking_field.computercraft.websocket_incoming.name": "Websocket gelen", "tracking_field.computercraft.websocket_outgoing.name": "Websocket giden", - "upgrade.computercraft.speaker.adjective": "Gürültücü", - "upgrade.computercraft.wireless_modem_advanced.adjective": "Ender", + "upgrade.computercraft.speaker.adjective": "Sesli", + "upgrade.computercraft.wireless_modem_advanced.adjective": "Enderli", "upgrade.computercraft.wireless_modem_normal.adjective": "Kablosuz", "upgrade.minecraft.crafting_table.adjective": "Üretken", - "upgrade.minecraft.diamond_axe.adjective": "Düşen", + "upgrade.minecraft.diamond_axe.adjective": "Ağaç Kesen", "upgrade.minecraft.diamond_hoe.adjective": "Çiftçi", "upgrade.minecraft.diamond_pickaxe.adjective": "Madenci", "upgrade.minecraft.diamond_shovel.adjective": "Kazıcı", From 2155ec3d6344d56f53fde018c46b9b9db89e952d Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sun, 27 Oct 2024 11:01:33 +0000 Subject: [PATCH 12/39] Give up on codecov v4 of the action seems to be much more restrictive in what can upload coveage. I'll miss this (the historic view of coverage was nice!), but not worth trying to get working again. We also stop running client tests. These break so often, we only really ran them for code coverage reasons. --- .github/workflows/main-ci.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/main-ci.yml b/.github/workflows/main-ci.yml index 4bc762c801..3da0267261 100644 --- a/.github/workflows/main-ci.yml +++ b/.github/workflows/main-ci.yml @@ -50,11 +50,6 @@ jobs: - name: 🧪 Run integration tests run: ./gradlew runGametest - - name: 🧪 Run client tests - run: ./gradlew runGametestClient # Not checkClient, as no point running rendering tests. - # These are a little flaky on GH actions: its useful to run them, but don't break the build. - continue-on-error: true - - name: 🧪 Parse test reports run: ./tools/parse-reports.py if: ${{ failure() }} @@ -71,9 +66,6 @@ jobs: name: CC-Tweaked path: ./jars - - name: 📤 Upload coverage - uses: codecov/codecov-action@v4 - build-core: strategy: fail-fast: false From 0aaeeeee2479644efe6758aee60bb4f45c2542ec Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sun, 27 Oct 2024 16:07:17 +0000 Subject: [PATCH 13/39] Don't log HTTP errors We don't do this for websockets, so maybe we can get away without this for HTTP ones too? Closes #1975. --- .../core/apis/http/request/HttpRequestHandler.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequestHandler.java b/projects/core/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequestHandler.java index 7cba7a803f..005440e597 100644 --- a/projects/core/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequestHandler.java +++ b/projects/core/src/main/java/dan200/computercraft/core/apis/http/request/HttpRequestHandler.java @@ -4,7 +4,6 @@ package dan200.computercraft.core.apis.http.request; -import dan200.computercraft.core.Logging; import dan200.computercraft.core.apis.handles.ArrayByteChannel; import dan200.computercraft.core.apis.handles.ReadHandle; import dan200.computercraft.core.apis.http.HTTPRequestException; @@ -162,7 +161,7 @@ public void channelRead0(ChannelHandlerContext ctx, HttpObject message) { @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { - LOG.error(Logging.HTTP_ERROR, "Error handling HTTP response", cause); + ctx.close(); request.failure(NetworkUtils.toFriendlyError(cause)); } From 37c4789fa4b3ad6df7314956ede9bef15385e326 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Thu, 31 Oct 2024 08:31:21 +0000 Subject: [PATCH 14/39] Fix Czech language mapping --- crowdin.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crowdin.yml b/crowdin.yml index 68accea61b..5a1b4d18ce 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,12 +1,13 @@ # SPDX-FileCopyrightText: 2017 The CC: Tweaked Developers # # SPDX-License-Identifier: MPL-2.0 + files: - source: projects/common/src/generated/resources/assets/computercraft/lang/en_us.json translation: /projects/common/src/main/resources/assets/computercraft/lang/%locale_with_underscore%.json languages_mapping: locale_with_underscore: - cs: cs_cs # Czech + cs: cs_cz # Czech da: da_dk # Danish de: de_de # German es-ES: es_es # Spanish From 97a2f2dbddb1b8eb1327e1acae6987498a491751 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Thu, 31 Oct 2024 08:30:27 +0000 Subject: [PATCH 15/39] A desperate plea to get people to include logs --- .github/ISSUE_TEMPLATE/bug_report.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 4e02c95c3d..1e24b2b9bc 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -6,7 +6,9 @@ body: id: mc-version attributes: label: Minecraft Version - description: What version of Minecraft are you using? + description: | + What version of Minecraft are you using? If your version is not listed, + please try to reproduce on one of the supported versions. options: - 1.20.1 - 1.21.x @@ -27,7 +29,8 @@ body: description: | Description of the bug. Please include the following: - Logs: These will be located in the `logs/` directory of your Minecraft - instance. Please upload them as a gist or directly into this editor. + instance. This is always useful, even if it doesn't include errors, so + please upload this! - Detailed reproduction steps: sometimes I can spot a bug pretty easily, but often it's much more obscure. The more information I have to help reproduce it, the quicker it'll get fixed. From 5d473725d53babffb390ff4c994b2abdaf5befc1 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Thu, 31 Oct 2024 08:32:44 +0000 Subject: [PATCH 16/39] Don't word-wrap in the bug report template Oh, I wish GHFM handled soft-breaks as soft-breaks, rather than turning them into hard ones :/. --- .github/ISSUE_TEMPLATE/bug_report.yaml | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 1e24b2b9bc..6ce1aba4f8 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -7,8 +7,7 @@ body: attributes: label: Minecraft Version description: | - What version of Minecraft are you using? If your version is not listed, - please try to reproduce on one of the supported versions. + What version of Minecraft are you using? If your version is not listed, please try to reproduce on one of the supported versions. options: - 1.20.1 - 1.21.x @@ -28,9 +27,5 @@ body: label: Details description: | Description of the bug. Please include the following: - - Logs: These will be located in the `logs/` directory of your Minecraft - instance. This is always useful, even if it doesn't include errors, so - please upload this! - - Detailed reproduction steps: sometimes I can spot a bug pretty easily, - but often it's much more obscure. The more information I have to help - reproduce it, the quicker it'll get fixed. + - Logs: These will be located in the `logs/` directory of your Minecraft instance. This is always useful, even if it doesn't include errors, so please upload this! + - Detailed reproduction steps: sometimes I can spot a bug pretty easily, but often it's much more obscure. The more information I have to help reproduce it, the quicker it'll get fixed. From 064ff31830f3060a6ba5815146591753dc835ac9 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Thu, 31 Oct 2024 09:33:22 +0000 Subject: [PATCH 17/39] Don't reset client pocket state when changing level As part of the multi-loader work, we unified some of our event listening code (0908acbe9bbb63d9c1be513d098e9a14d5bb68e3). This incorrectly caused client pocket computer state to be reset when the player changes dimension, rather than when the player (dis)connects. The server code isn't aware of this behaviour, and so does not resend pocket computer state when the player moves level. We could change this, but just fixing when we clear the pocket computer state is a much nicer fix! Fixes #2004 --- .../client/java/dan200/computercraft/client/ClientHooks.java | 3 +++ .../dan200/computercraft/mixin/client/MinecraftMixin.java | 1 + .../java/dan200/computercraft/client/ForgeClientHooks.java | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/projects/common/src/client/java/dan200/computercraft/client/ClientHooks.java b/projects/common/src/client/java/dan200/computercraft/client/ClientHooks.java index 36b331939b..3ecd0bdc6a 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/ClientHooks.java +++ b/projects/common/src/client/java/dan200/computercraft/client/ClientHooks.java @@ -64,6 +64,9 @@ public static void onRenderTick() { public static void onWorldUnload() { MonitorRenderState.destroyAll(); SpeakerManager.reset(); + } + + public static void onDisconnect() { ClientPocketComputers.reset(); } diff --git a/projects/fabric/src/client/java/dan200/computercraft/mixin/client/MinecraftMixin.java b/projects/fabric/src/client/java/dan200/computercraft/mixin/client/MinecraftMixin.java index 23244e8b9d..e413c3a405 100644 --- a/projects/fabric/src/client/java/dan200/computercraft/mixin/client/MinecraftMixin.java +++ b/projects/fabric/src/client/java/dan200/computercraft/mixin/client/MinecraftMixin.java @@ -28,6 +28,7 @@ class MinecraftMixin { @SuppressWarnings("unused") private void clearLevel(Screen screen, CallbackInfo ci) { ClientHooks.onWorldUnload(); + ClientHooks.onDisconnect(); } @Inject(method = "setLevel", at = @At("HEAD")) diff --git a/projects/forge/src/client/java/dan200/computercraft/client/ForgeClientHooks.java b/projects/forge/src/client/java/dan200/computercraft/client/ForgeClientHooks.java index ea97bf1203..7aa52b03a5 100644 --- a/projects/forge/src/client/java/dan200/computercraft/client/ForgeClientHooks.java +++ b/projects/forge/src/client/java/dan200/computercraft/client/ForgeClientHooks.java @@ -38,6 +38,10 @@ public static void onWorldUnload(LevelEvent.Unload event) { if (event.getLevel().isClientSide()) ClientHooks.onWorldUnload(); } + @SubscribeEvent + public static void onDisconnect(ClientPlayerNetworkEvent.LoggingOut event) { + ClientHooks.onDisconnect(); + } @SubscribeEvent public static void drawHighlight(RenderHighlightEvent.Block event) { From 3293639adf80fce9441a8887c04163207993e55e Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Tue, 5 Nov 2024 10:00:08 +0000 Subject: [PATCH 18/39] Normalise language files --- .../assets/computercraft/lang/cs_cz.json | 16 ++-- .../assets/computercraft/lang/de_de.json | 30 ++++---- .../assets/computercraft/lang/es_es.json | 2 - .../assets/computercraft/lang/fr_fr.json | 2 - .../assets/computercraft/lang/it_it.json | 30 ++++---- .../assets/computercraft/lang/ko_kr.json | 2 - .../assets/computercraft/lang/nb_no.json | 2 - .../assets/computercraft/lang/nl_nl.json | 2 - .../assets/computercraft/lang/pl_pl.json | 2 - .../assets/computercraft/lang/ru_ru.json | 2 - .../assets/computercraft/lang/sv_se.json | 2 - .../assets/computercraft/lang/tok.json | 2 - .../assets/computercraft/lang/uk_ua.json | 2 - .../assets/computercraft/lang/zh_cn.json | 76 +++++++++---------- 14 files changed, 72 insertions(+), 100 deletions(-) diff --git a/projects/common/src/main/resources/assets/computercraft/lang/cs_cz.json b/projects/common/src/main/resources/assets/computercraft/lang/cs_cz.json index 8051fa6e48..80090e400e 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/cs_cz.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/cs_cz.json @@ -32,8 +32,6 @@ "commands.computercraft.generic.additional_rows": "%d řádků navíc…", "commands.computercraft.generic.exception": "Neočekávaná chyba (%s)", "commands.computercraft.generic.no": "N", - "commands.computercraft.generic.no_position": "<žádná pozice>", - "commands.computercraft.generic.position": "%s, %s, %s", "commands.computercraft.generic.yes": "A", "commands.computercraft.help.desc": "Ukáže tuto pomocnou zprávu", "commands.computercraft.help.no_children": "%s nemá žádné podpříkazy", @@ -98,6 +96,7 @@ "gui.computercraft.config.http.max_requests.tooltip": "Počet HTTP požadavků které počítač může udělat v jedné chvíli. Požadavky navíc\nbudou zaslány do fronty, a poslány když běžící požadavky byly dokončeny. Nastav\nna 0 pro neomezeno.\nRozsah: > 0", "gui.computercraft.config.http.max_websockets": "Maximální souběžné websockety", "gui.computercraft.config.http.max_websockets.tooltip": "Počet websocketů které může mít počítač otevřené najednou: Nastav na 0 pro neomezeno.\nRozsah: > 1", + "gui.computercraft.config.http.proxy": "Proxy", "gui.computercraft.config.http.proxy.host": "Název hostitele", "gui.computercraft.config.http.proxy.host.tooltip": "Název hostitele nebo IP adresa proxy serveru.", "gui.computercraft.config.http.proxy.port": "Port", @@ -164,6 +163,7 @@ "gui.computercraft.config.turtle.normal_fuel_limit.tooltip": "Limit paliva pro roboty.\nRozsah: > 0", "gui.computercraft.config.turtle.tooltip": "Různé možnosti o robotech.", "gui.computercraft.config.upload_max_size": "Limit velikosti nahrávaného souboru (v bajtech)", + "gui.computercraft.config.upload_max_size.tooltip": "Limit velikosti nahrávaného souboru v bytech. Musí být v rozmezí od 1 KiB do 16 MiB.\nMěj na paměti, že nahrávání souborů je zpracováváno v jednom ticku - velké soubory nebo\nšpatný výkon sítě mohou zpomalit síťové vlákno. A nezapomeň na místo na disku!\nRozsah: 1024 ~ 16777216", "gui.computercraft.config.upload_nag_delay": "Nahrání zpoždění nag", "gui.computercraft.config.upload_nag_delay.tooltip": "Zpoždění v sekundách po kterém oznámíme o nezpracovaných importech. Nastav na 0 pro vypnutí.\nRozsah: 0 ~ 60", "gui.computercraft.pocket_computer_overlay": "Kapesní počítač otevřen. Zmáčkni ESC pro uzavření.", @@ -195,6 +195,10 @@ "item.computercraft.printed_pages": "Tisknuté stránky", "item.computercraft.treasure_disk": "Disketa", "itemGroup.computercraft": "ComputerCraft", + "tag.item.computercraft.computer": "Počítače", + "tag.item.computercraft.monitor": "Monitory", + "tag.item.computercraft.turtle": "Roboti", + "tag.item.computercraft.wired_modem": "Drátové modemy", "tracking_field.computercraft.avg": "%s (průměr)", "tracking_field.computercraft.computer_tasks.name": "Úlohy", "tracking_field.computercraft.count": "%s (počet)", @@ -216,11 +220,5 @@ "upgrade.minecraft.diamond_hoe.adjective": "Farmářský", "upgrade.minecraft.diamond_pickaxe.adjective": "Těžební", "upgrade.minecraft.diamond_shovel.adjective": "Kopací", - "upgrade.minecraft.diamond_sword.adjective": "Bojový", - "tag.item.computercraft.computer": "Počítače", - "tag.item.computercraft.monitor": "Monitory", - "tag.item.computercraft.turtle": "Roboti", - "tag.item.computercraft.wired_modem": "Drátové modemy", - "gui.computercraft.config.http.proxy": "Proxy", - "gui.computercraft.config.upload_max_size.tooltip": "Limit velikosti nahrávaného souboru v bytech. Musí být v rozmezí od 1 KiB do 16 MiB.\nMěj na paměti, že nahrávání souborů je zpracováváno v jednom ticku - velké soubory nebo\nšpatný výkon sítě mohou zpomalit síťové vlákno. A nezapomeň na místo na disku!\nRozsah: 1024 ~ 16777216" + "upgrade.minecraft.diamond_sword.adjective": "Bojový" } diff --git a/projects/common/src/main/resources/assets/computercraft/lang/de_de.json b/projects/common/src/main/resources/assets/computercraft/lang/de_de.json index e0efbbae07..83093dba96 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/de_de.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/de_de.json @@ -1,8 +1,13 @@ { "argument.computercraft.argument_expected": "Parameter erwartet", + "argument.computercraft.computer.family": "Computerfamilie", + "argument.computercraft.computer.id": "Computer ID", + "argument.computercraft.computer.instance": "einzigartige Instanz ID", + "argument.computercraft.computer.label": "Computername", "argument.computercraft.computer.many_matching": "Mehrere Computer passen auf '%s' (Instanzen %s)", "argument.computercraft.computer.no_matching": "Kein Computer passt auf '%s'", "argument.computercraft.tracking_field.no_field": "Unbekanntes Feld '%s'", + "argument.computercraft.unknown_computer_family": "Unbekannte Computerfamilie '%s'", "block.computercraft.cable": "Netzwerkkabel", "block.computercraft.computer_advanced": "Erweiterter Computer", "block.computercraft.computer_command": "Befehlscomputer", @@ -32,8 +37,6 @@ "commands.computercraft.generic.additional_rows": "%d zusätzliche Zeilen…", "commands.computercraft.generic.exception": "Unbehandelte Ausnahme (%s)", "commands.computercraft.generic.no": "N", - "commands.computercraft.generic.no_position": "", - "commands.computercraft.generic.position": "%s, %s, %s", "commands.computercraft.generic.yes": "J", "commands.computercraft.help.desc": "Zeigt diese Hilfe Nachricht", "commands.computercraft.help.no_children": "%s hat keine Unterbefehle", @@ -82,8 +85,16 @@ "gui.computercraft.config.execution.max_main_computer_time": "Computer Servertick Zeitlimit", "gui.computercraft.config.execution.max_main_computer_time.tooltip": "Die ideale maximale Zeit, in der ein Computer laufen kann im innerhalb von einem tick in Millisekunden.\nBeachte, dass wir wahrscheinlich über diesen Limit gehen werden, da es unmöglich ist zu bestimmen,\nwie lange ein Computer brauchen wird. Dies wird also die höhere Grenze der durchschnittlichen Zeit darstellen.\nBereich: > 1", "gui.computercraft.config.execution.max_main_global_time": "Globales Servertick Zeitlimit", + "gui.computercraft.config.execution.max_main_global_time.tooltip": "Die maximale Zeit in Millisekunden, in der Aufgaben ausgeführt werden.\nAnmerkung: Diese Zeit wird höchstwarscheinlich überschritten und dient nur als ungefähre Grenze.\nLimit: > 1", "gui.computercraft.config.floppy_space_limit": "Speicherplatz von Disketten (Bytes)", + "gui.computercraft.config.floppy_space_limit.tooltip": "Die maximale Dateisystem Größe von Disketten (in bytes).", "gui.computercraft.config.http": "HTTP", + "gui.computercraft.config.http.bandwidth": "Bandbreite", + "gui.computercraft.config.http.bandwidth.global_download": "Globale Downloadbandbreite", + "gui.computercraft.config.http.bandwidth.global_download.tooltip": "Die maximale Bandbreite aller Computer in bytes/s mit der heruntergeladen werden kann.\nBereich: > 1", + "gui.computercraft.config.http.bandwidth.global_upload": "Globale Uploadbandbreite", + "gui.computercraft.config.http.bandwidth.global_upload.tooltip": "Die maximale Bandbreite aller Computer in bytes/s mit der hochgeladen werden kann.\nBereich: > 1", + "gui.computercraft.config.http.bandwidth.tooltip": "Limitiert die Bandbreite der Computer.", "gui.computercraft.config.http.enabled": "HTTP-API aktivieren", "gui.computercraft.config.http.max_requests": "Maximale Anzahl gleichzeitiger Anfragen", "gui.computercraft.config.http.max_websockets": "Maximale Anzahl gleichzeitiger Websockets", @@ -130,18 +141,5 @@ "upgrade.minecraft.diamond_hoe.adjective": "Ackerbau", "upgrade.minecraft.diamond_pickaxe.adjective": "Bergbau", "upgrade.minecraft.diamond_shovel.adjective": "Graben", - "upgrade.minecraft.diamond_sword.adjective": "Nahkampf", - "argument.computercraft.computer.id": "Computer ID", - "argument.computercraft.computer.instance": "einzigartige Instanz ID", - "argument.computercraft.computer.label": "Computername", - "argument.computercraft.unknown_computer_family": "Unbekannte Computerfamilie '%s'", - "gui.computercraft.config.floppy_space_limit.tooltip": "Die maximale Dateisystem Größe von Disketten (in bytes).", - "gui.computercraft.config.http.bandwidth": "Bandbreite", - "gui.computercraft.config.http.bandwidth.global_upload": "Globale Uploadbandbreite", - "gui.computercraft.config.http.bandwidth.global_download.tooltip": "Die maximale Bandbreite aller Computer in bytes/s mit der heruntergeladen werden kann.\nBereich: > 1", - "gui.computercraft.config.http.bandwidth.global_download": "Globale Downloadbandbreite", - "gui.computercraft.config.http.bandwidth.tooltip": "Limitiert die Bandbreite der Computer.", - "argument.computercraft.computer.family": "Computerfamilie", - "gui.computercraft.config.execution.max_main_global_time.tooltip": "Die maximale Zeit in Millisekunden, in der Aufgaben ausgeführt werden.\nAnmerkung: Diese Zeit wird höchstwarscheinlich überschritten und dient nur als ungefähre Grenze.\nLimit: > 1", - "gui.computercraft.config.http.bandwidth.global_upload.tooltip": "Die maximale Bandbreite aller Computer in bytes/s mit der hochgeladen werden kann.\nBereich: > 1" + "upgrade.minecraft.diamond_sword.adjective": "Nahkampf" } diff --git a/projects/common/src/main/resources/assets/computercraft/lang/es_es.json b/projects/common/src/main/resources/assets/computercraft/lang/es_es.json index 2620152efc..510805689a 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/es_es.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/es_es.json @@ -24,8 +24,6 @@ "chat.computercraft.wired_modem.peripheral_disconnected": "El periférico \"%s\" se desconectó de la red", "commands.computercraft.generic.additional_rows": "%d filas adicionales…", "commands.computercraft.generic.no": "N", - "commands.computercraft.generic.no_position": "", - "commands.computercraft.generic.position": "%s, %s, %s", "commands.computercraft.generic.yes": "Y", "commands.computercraft.help.desc": "Muestra este mensaje de ayuda", "commands.computercraft.help.no_command": "Sin comando '%s'", diff --git a/projects/common/src/main/resources/assets/computercraft/lang/fr_fr.json b/projects/common/src/main/resources/assets/computercraft/lang/fr_fr.json index f719fcc61e..ba0a20149d 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/fr_fr.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/fr_fr.json @@ -32,8 +32,6 @@ "commands.computercraft.generic.additional_rows": "%d lignes supplémentaires…", "commands.computercraft.generic.exception": "Exception non gérée (%s)", "commands.computercraft.generic.no": "N", - "commands.computercraft.generic.no_position": "", - "commands.computercraft.generic.position": "%s, %s, %s", "commands.computercraft.generic.yes": "O", "commands.computercraft.help.desc": "Affiche ce message d'aide", "commands.computercraft.help.no_children": "%s n'a pas de sous-commandes", diff --git a/projects/common/src/main/resources/assets/computercraft/lang/it_it.json b/projects/common/src/main/resources/assets/computercraft/lang/it_it.json index c9ac0babcf..d5ace0c940 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/it_it.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/it_it.json @@ -1,8 +1,14 @@ { "argument.computercraft.argument_expected": "È previsto un argomento", + "argument.computercraft.computer.distance": "Distanza dall'entità", + "argument.computercraft.computer.family": "Famiglia computer", + "argument.computercraft.computer.id": "ID computer", + "argument.computercraft.computer.instance": "ID istanza unica", + "argument.computercraft.computer.label": "Etichetta computer", "argument.computercraft.computer.many_matching": "Molteplici computer che combaciano con '%s' (istanze %s)", "argument.computercraft.computer.no_matching": "Nessun computer che combacia con '%s'", "argument.computercraft.tracking_field.no_field": "Campo sconosciuto '%s'", + "argument.computercraft.unknown_computer_family": "Famiglia computer '%s' sconosciuta", "block.computercraft.cable": "Cavo Di Rete", "block.computercraft.computer_advanced": "Computer Avanzato", "block.computercraft.computer_command": "Computer Comando", @@ -32,8 +38,6 @@ "commands.computercraft.generic.additional_rows": "%d colonne aggiuntive…", "commands.computercraft.generic.exception": "Eccezione non gestita (%s)", "commands.computercraft.generic.no": "N", - "commands.computercraft.generic.no_position": "", - "commands.computercraft.generic.position": "%s, %s, %s", "commands.computercraft.generic.yes": "S", "commands.computercraft.help.desc": "Mostra questo messaggio d'aiuto", "commands.computercraft.help.no_children": "%s non ha sottocomandi", @@ -74,6 +78,8 @@ "gui.computercraft.config.computer_space_limit.tooltip": "Limite di spazio di archiviazione per i computer e le tartarughe, in byte.", "gui.computercraft.config.default_computer_settings": "Impostazioni Computer predefinite", "gui.computercraft.config.default_computer_settings.tooltip": "Una lista di impostazioni predefinite per i nuovi computer, separate da virgola.\nEsempio: \"shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false\"\ndisattiverà tutti gli autocompletamenti.", + "gui.computercraft.config.disabled_generic_methods": "Metodi generici disattivati", + "gui.computercraft.config.disabled_generic_methods.tooltip": "Una lista di metodi generici o sorgenti di metodi da disattivare. I metodi generici sono\nmetodi aggiunti a blocchi/entità blocchi quando non c'è un provider della periferica esplicito.\nQuesto include metodi dell'inventario (ad es. inventory.getItemDetail, inventory.pushItems) e,\nse su Forge, i metodi fluid_storage e energy_storage.\nI metodi in questa lista possono essere sia un gruppo intero di metodi (computer:inventory)\no un singolo metodo (computer:inventory#pushItems).\n", "gui.computercraft.config.execution": "Esecuzione", "gui.computercraft.config.execution.computer_threads": "Threads computer", "gui.computercraft.config.execution.computer_threads.tooltip": "Imposta la quantità di thread che possono eseguire i computer. Un numero più alto significa\nche più computer possono essere eseguiti alla volta, ma può indurre a lag. Alcune mod potrebbero\nnon funzionare con numeri di thread maggiore a 1. Usare con cautela.\nRange: > 1", @@ -197,6 +203,10 @@ "item.computercraft.printed_pages": "Pagine Stampate", "item.computercraft.treasure_disk": "Disco Floppy", "itemGroup.computercraft": "ComputerCraft", + "tag.item.computercraft.computer": "Computer", + "tag.item.computercraft.monitor": "Monitor", + "tag.item.computercraft.turtle": "Tartarughe", + "tag.item.computercraft.wired_modem": "Modem cablati", "tracking_field.computercraft.avg": "%s (media)", "tracking_field.computercraft.computer_tasks.name": "Attività", "tracking_field.computercraft.count": "%s (conta)", @@ -204,6 +214,7 @@ "tracking_field.computercraft.http_download.name": "Download HTTP", "tracking_field.computercraft.http_requests.name": "Richieste HTTP", "tracking_field.computercraft.http_upload.name": "Upload HTTP", + "tracking_field.computercraft.java_allocation.name": "Allocazioni Java", "tracking_field.computercraft.max": "%s (massimo)", "tracking_field.computercraft.peripheral.name": "Chiamate alle periferiche", "tracking_field.computercraft.server_tasks.name": "Attività server", @@ -218,18 +229,5 @@ "upgrade.minecraft.diamond_hoe.adjective": "Contadina", "upgrade.minecraft.diamond_pickaxe.adjective": "Minatrice", "upgrade.minecraft.diamond_shovel.adjective": "Scavatrice", - "upgrade.minecraft.diamond_sword.adjective": "Da Combattimento", - "tag.item.computercraft.computer": "Computer", - "tag.item.computercraft.wired_modem": "Modem cablati", - "argument.computercraft.computer.distance": "Distanza dall'entità", - "argument.computercraft.computer.family": "Famiglia computer", - "argument.computercraft.computer.id": "ID computer", - "argument.computercraft.computer.instance": "ID istanza unica", - "argument.computercraft.computer.label": "Etichetta computer", - "argument.computercraft.unknown_computer_family": "Famiglia computer '%s' sconosciuta", - "gui.computercraft.config.disabled_generic_methods": "Metodi generici disattivati", - "gui.computercraft.config.disabled_generic_methods.tooltip": "Una lista di metodi generici o sorgenti di metodi da disattivare. I metodi generici sono\nmetodi aggiunti a blocchi/entità blocchi quando non c'è un provider della periferica esplicito.\nQuesto include metodi dell'inventario (ad es. inventory.getItemDetail, inventory.pushItems) e,\nse su Forge, i metodi fluid_storage e energy_storage.\nI metodi in questa lista possono essere sia un gruppo intero di metodi (computer:inventory)\no un singolo metodo (computer:inventory#pushItems).\n", - "tag.item.computercraft.monitor": "Monitor", - "tag.item.computercraft.turtle": "Tartarughe", - "tracking_field.computercraft.java_allocation.name": "Allocazioni Java" + "upgrade.minecraft.diamond_sword.adjective": "Da Combattimento" } diff --git a/projects/common/src/main/resources/assets/computercraft/lang/ko_kr.json b/projects/common/src/main/resources/assets/computercraft/lang/ko_kr.json index db2c5071fe..dcce4feeac 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/ko_kr.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/ko_kr.json @@ -32,8 +32,6 @@ "commands.computercraft.generic.additional_rows": "%d개의 추가 행…", "commands.computercraft.generic.exception": "처리되지 않은 예외 (%s)", "commands.computercraft.generic.no": "N", - "commands.computercraft.generic.no_position": "", - "commands.computercraft.generic.position": "%s, %s, %s", "commands.computercraft.generic.yes": "Y", "commands.computercraft.help.desc": "이 도움말 메시지를 표시합니다.", "commands.computercraft.help.no_children": "%s에는 하위 명령어가 없습니다.", diff --git a/projects/common/src/main/resources/assets/computercraft/lang/nb_no.json b/projects/common/src/main/resources/assets/computercraft/lang/nb_no.json index 294a6129eb..7d3269bd28 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/nb_no.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/nb_no.json @@ -32,8 +32,6 @@ "commands.computercraft.generic.additional_rows": "%d flere rader…", "commands.computercraft.generic.exception": "Uhåndtert unntak (%s)", "commands.computercraft.generic.no": "N", - "commands.computercraft.generic.no_position": "", - "commands.computercraft.generic.position": "%s, %s, %s", "commands.computercraft.generic.yes": "J", "commands.computercraft.help.desc": "Viser denne hjelpemeldingen", "commands.computercraft.help.no_children": "%s har ingen underkommandoer", diff --git a/projects/common/src/main/resources/assets/computercraft/lang/nl_nl.json b/projects/common/src/main/resources/assets/computercraft/lang/nl_nl.json index c1127468c6..acca2cfc90 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/nl_nl.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/nl_nl.json @@ -32,8 +32,6 @@ "commands.computercraft.generic.additional_rows": "%d additionele rijen…", "commands.computercraft.generic.exception": "Niet-afgehandelde exception (%s)", "commands.computercraft.generic.no": "N", - "commands.computercraft.generic.no_position": "", - "commands.computercraft.generic.position": "%s, %s, %s", "commands.computercraft.generic.yes": "J", "commands.computercraft.help.desc": "Geeft dit hulpbericht weer", "commands.computercraft.help.no_children": "%s heeft geen sub-commando's", diff --git a/projects/common/src/main/resources/assets/computercraft/lang/pl_pl.json b/projects/common/src/main/resources/assets/computercraft/lang/pl_pl.json index f1f645104d..b899719cdd 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/pl_pl.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/pl_pl.json @@ -19,8 +19,6 @@ "commands.computercraft.dump.desc": "Wyświetla status wszystkich komputerów lub informacje o jednym komputerze. Możesz wybrać numer sesji komputera (np. 123), ID komputera (np. #123) lub jego etykietę (np. \"@Mój Komputer\").", "commands.computercraft.dump.open_path": "Przeglądaj pliki tego komputera", "commands.computercraft.dump.synopsis": "Wyświetl stan komputerów.", - "commands.computercraft.generic.no_position": "", - "commands.computercraft.generic.position": "%s, %s, %s", "commands.computercraft.generic.yes": "T", "commands.computercraft.help.no_children": "%s nie ma pod-komend", "commands.computercraft.help.no_command": "Nie odnaleziono komendy '%s'", diff --git a/projects/common/src/main/resources/assets/computercraft/lang/ru_ru.json b/projects/common/src/main/resources/assets/computercraft/lang/ru_ru.json index c777127cf8..aa1e11a868 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/ru_ru.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/ru_ru.json @@ -32,8 +32,6 @@ "commands.computercraft.generic.additional_rows": "%d дополнительных строк …", "commands.computercraft.generic.exception": "Необработанное исключение (%s)", "commands.computercraft.generic.no": "N", - "commands.computercraft.generic.no_position": "<нет позиции>", - "commands.computercraft.generic.position": "%s, %s, %s", "commands.computercraft.generic.yes": "Y", "commands.computercraft.help.desc": "Отображает это сообщение справки", "commands.computercraft.help.no_children": "%s не имеет подкоманд", diff --git a/projects/common/src/main/resources/assets/computercraft/lang/sv_se.json b/projects/common/src/main/resources/assets/computercraft/lang/sv_se.json index 94c9583ff6..04fd86b5b9 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/sv_se.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/sv_se.json @@ -32,8 +32,6 @@ "commands.computercraft.generic.additional_rows": "%d ytterligare rader…", "commands.computercraft.generic.exception": "Ohanterat felfall (%s)", "commands.computercraft.generic.no": "N", - "commands.computercraft.generic.no_position": "", - "commands.computercraft.generic.position": "%s, %s, %s", "commands.computercraft.generic.yes": "J", "commands.computercraft.help.desc": "Visa detta hjälpmeddelande", "commands.computercraft.help.no_children": "%s har inget underkommando", diff --git a/projects/common/src/main/resources/assets/computercraft/lang/tok.json b/projects/common/src/main/resources/assets/computercraft/lang/tok.json index 8d32734ae0..c48d065f2f 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/tok.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/tok.json @@ -31,8 +31,6 @@ "commands.computercraft.dump.synopsis": "mi pana e sona pi ilo sona.", "commands.computercraft.generic.additional_rows": "mute %d…", "commands.computercraft.generic.exception": "pakala awen ala (%s)", - "commands.computercraft.generic.no_position": "", - "commands.computercraft.generic.position": "%s, %s, %s", "commands.computercraft.help.desc": "mi pana e toki ni", "commands.computercraft.help.no_children": "toki wawa '%s' li jo ala e toki wawa insa", "commands.computercraft.help.no_command": "toki wawa '%s' li lon ala", diff --git a/projects/common/src/main/resources/assets/computercraft/lang/uk_ua.json b/projects/common/src/main/resources/assets/computercraft/lang/uk_ua.json index efea67c236..34b0aeccfb 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/uk_ua.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/uk_ua.json @@ -32,8 +32,6 @@ "commands.computercraft.generic.additional_rows": "%d додаткових рядків …", "commands.computercraft.generic.exception": "Необроблений виняток (%s)", "commands.computercraft.generic.no": "N", - "commands.computercraft.generic.no_position": "<немає позиції>", - "commands.computercraft.generic.position": "%s, %s, %s", "commands.computercraft.generic.yes": "Y", "commands.computercraft.help.desc": "Показує це повідомлення довідки", "commands.computercraft.help.no_children": "%s не має підкоманд", diff --git a/projects/common/src/main/resources/assets/computercraft/lang/zh_cn.json b/projects/common/src/main/resources/assets/computercraft/lang/zh_cn.json index 0d3ad1317b..7f14b4fdc9 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/zh_cn.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/zh_cn.json @@ -1,8 +1,14 @@ { "argument.computercraft.argument_expected": "预期自变量", + "argument.computercraft.computer.distance": "实体距离", + "argument.computercraft.computer.family": "电脑类别", + "argument.computercraft.computer.id": "电脑ID", + "argument.computercraft.computer.instance": "唯一实例ID", + "argument.computercraft.computer.label": "电脑标签", "argument.computercraft.computer.many_matching": "多台计算机匹配'%s' (实例%s)", "argument.computercraft.computer.no_matching": "没有计算机匹配'%s'", "argument.computercraft.tracking_field.no_field": "未知字段'%s'", + "argument.computercraft.unknown_computer_family": "未知电脑类别 '%s'", "block.computercraft.cable": "网络电缆", "block.computercraft.computer_advanced": "高级计算机", "block.computercraft.computer_command": "命令电脑", @@ -27,13 +33,13 @@ "commands.computercraft.desc": "/computercraft命令提供各种调试和管理工具,用于控制和与计算机交互.", "commands.computercraft.dump.action": "查看有关此计算机的更多信息", "commands.computercraft.dump.desc": "显示所有计算机的状态或某台计算机的特定信息. 你可以指定计算机的实例id (例如. 123), 计算机id (例如. #123)或标签(例如. \"@My Computer\").", + "commands.computercraft.dump.open_path": "查看该电脑的文件", "commands.computercraft.dump.synopsis": "显示计算机的状态.", "commands.computercraft.generic.additional_rows": "%d额外的行…", "commands.computercraft.generic.exception": "未处理的异常(%s)", "commands.computercraft.generic.no": "N", - "commands.computercraft.generic.no_position": "<无位置>", - "commands.computercraft.generic.position": "%s, %s, %s", "commands.computercraft.generic.yes": "Y", + "commands.computercraft.help.desc": "显示该帮助信息", "commands.computercraft.help.no_children": "%s没有子命令", "commands.computercraft.help.no_command": "没有这样的命令'%s'", "commands.computercraft.help.synopsis": "为特定的命令提供帮助", @@ -66,17 +72,36 @@ "commands.computercraft.view.desc": "打开计算机的终端,允许远程控制计算机. 这不提供对海龟库存的访问. 你可以指定计算机的实例id (例如. 123)或计算机id (例如. #123).", "commands.computercraft.view.not_player": "无法为非玩家打开终端", "commands.computercraft.view.synopsis": "查看计算机的终端.", + "gui.computercraft.config.command_require_creative": "命令电脑需要创造模式", + "gui.computercraft.config.command_require_creative.tooltip": "玩家需要处于创造模式并为管理员才能与命令计算机交互。\n这是原版命令方块的默认行为。", "gui.computercraft.config.computer_space_limit": "计算机空间限制(字节)", + "gui.computercraft.config.computer_space_limit.tooltip": "计算机和海龟的磁盘空间限制,以字节为单位。", "gui.computercraft.config.default_computer_settings": "默认计算机设置", + "gui.computercraft.config.disabled_generic_methods": "禁用的通用方法", "gui.computercraft.config.execution": "执行", "gui.computercraft.config.execution.computer_threads": "计算机线程数", "gui.computercraft.config.execution.max_main_computer_time": "服务器计算机tick时间限制", "gui.computercraft.config.execution.max_main_global_time": "服务器全局tick时间限制", "gui.computercraft.config.floppy_space_limit": "软盘空间限制(字节)", "gui.computercraft.config.http": "HTTP", + "gui.computercraft.config.http.bandwidth": "带宽", + "gui.computercraft.config.http.bandwidth.global_download": "全局下载限速", + "gui.computercraft.config.http.bandwidth.global_download.tooltip": "每秒钟可以下载的字节数. 所有电脑共享该设置 (bytes/s).\n范围: > 1", + "gui.computercraft.config.http.bandwidth.global_upload": "全局上传限速", + "gui.computercraft.config.http.bandwidth.global_upload.tooltip": "每秒钟可以上传的字节数. 所有电脑共享该设置 (bytes/s).\n范围: > 1", + "gui.computercraft.config.http.bandwidth.tooltip": "限制电脑可以使用的带宽.", "gui.computercraft.config.http.enabled": "启用HTTP API", "gui.computercraft.config.http.max_requests": "最大并发请求数", "gui.computercraft.config.http.max_websockets": "最大并发websockets数", + "gui.computercraft.config.http.proxy": "代理", + "gui.computercraft.config.http.proxy.host": "主机名", + "gui.computercraft.config.http.proxy.host.tooltip": "代理服务器的主机名或IP地址.", + "gui.computercraft.config.http.proxy.port": "端口", + "gui.computercraft.config.http.proxy.port.tooltip": "代理服务器的端口.\n范围: 1 ~ 65536", + "gui.computercraft.config.http.proxy.type": "代理类型", + "gui.computercraft.config.http.proxy.type.tooltip": "代理使用的协议.\n允许: HTTP, HTTPS, SOCKS4, SOCKS5", + "gui.computercraft.config.http.rules": "允许/阻止规则", + "gui.computercraft.config.http.tooltip": "控制HTTP API", "gui.computercraft.config.http.websocket_enabled": "启用websockets", "gui.computercraft.config.log_computer_errors": "记录计算机错误", "gui.computercraft.config.maximum_open_files": "每台计算机打开的最大文件数", @@ -105,10 +130,19 @@ "item.computercraft.printed_pages": "打印纸簇", "item.computercraft.treasure_disk": "软盘", "itemGroup.computercraft": "ComputerCraft", + "tag.item.computercraft.turtle": "海龟", + "tag.item.computercraft.wired_modem": "有线调制解调器", + "tracking_field.computercraft.avg": "%s (平均)", + "tracking_field.computercraft.computer_tasks.name": "任务", + "tracking_field.computercraft.count": "%s (计数)", "tracking_field.computercraft.fs.name": "文件系统操作", "tracking_field.computercraft.http_download.name": "HTTP下载", + "tracking_field.computercraft.http_requests.name": "HTTP请求", "tracking_field.computercraft.http_upload.name": "HTTP上传", + "tracking_field.computercraft.java_allocation.name": "Java分配", + "tracking_field.computercraft.max": "%s (最大)", "tracking_field.computercraft.peripheral.name": "外部设备呼叫", + "tracking_field.computercraft.server_tasks.name": "服务器任务", "tracking_field.computercraft.turtle_ops.name": "海龟行动", "tracking_field.computercraft.websocket_incoming.name": "Websocket传入", "tracking_field.computercraft.websocket_outgoing.name": "Websocket传出", @@ -120,41 +154,5 @@ "upgrade.minecraft.diamond_hoe.adjective": "耕种", "upgrade.minecraft.diamond_pickaxe.adjective": "采掘", "upgrade.minecraft.diamond_shovel.adjective": "挖掘", - "upgrade.minecraft.diamond_sword.adjective": "战斗", - "argument.computercraft.computer.instance": "唯一实例ID", - "commands.computercraft.dump.open_path": "查看该电脑的文件", - "gui.computercraft.config.command_require_creative": "命令电脑需要创造模式", - "gui.computercraft.config.command_require_creative.tooltip": "玩家需要处于创造模式并为管理员才能与命令计算机交互。\n这是原版命令方块的默认行为。", - "gui.computercraft.config.http.bandwidth": "带宽", - "gui.computercraft.config.http.bandwidth.global_download.tooltip": "每秒钟可以下载的字节数. 所有电脑共享该设置 (bytes/s).\n范围: > 1", - "gui.computercraft.config.http.proxy.type.tooltip": "代理使用的协议.\n允许: HTTP, HTTPS, SOCKS4, SOCKS5", - "argument.computercraft.computer.id": "电脑ID", - "argument.computercraft.computer.distance": "实体距离", - "argument.computercraft.computer.family": "电脑类别", - "argument.computercraft.computer.label": "电脑标签", - "argument.computercraft.unknown_computer_family": "未知电脑类别 '%s'", - "commands.computercraft.help.desc": "显示该帮助信息", - "gui.computercraft.config.computer_space_limit.tooltip": "计算机和海龟的磁盘空间限制,以字节为单位。", - "gui.computercraft.config.disabled_generic_methods": "禁用的通用方法", - "gui.computercraft.config.http.bandwidth.global_upload": "全局上传限速", - "gui.computercraft.config.http.bandwidth.global_download": "全局下载限速", - "gui.computercraft.config.http.bandwidth.global_upload.tooltip": "每秒钟可以上传的字节数. 所有电脑共享该设置 (bytes/s).\n范围: > 1", - "gui.computercraft.config.http.bandwidth.tooltip": "限制电脑可以使用的带宽.", - "gui.computercraft.config.http.proxy": "代理", - "gui.computercraft.config.http.proxy.host": "主机名", - "gui.computercraft.config.http.proxy.host.tooltip": "代理服务器的主机名或IP地址.", - "gui.computercraft.config.http.proxy.port": "端口", - "gui.computercraft.config.http.proxy.port.tooltip": "代理服务器的端口.\n范围: 1 ~ 65536", - "gui.computercraft.config.http.proxy.type": "代理类型", - "gui.computercraft.config.http.rules": "允许/阻止规则", - "gui.computercraft.config.http.tooltip": "控制HTTP API", - "tracking_field.computercraft.java_allocation.name": "Java分配", - "tracking_field.computercraft.max": "%s (最大)", - "tracking_field.computercraft.server_tasks.name": "服务器任务", - "tag.item.computercraft.turtle": "海龟", - "tag.item.computercraft.wired_modem": "有线调制解调器", - "tracking_field.computercraft.avg": "%s (平均)", - "tracking_field.computercraft.computer_tasks.name": "任务", - "tracking_field.computercraft.count": "%s (计数)", - "tracking_field.computercraft.http_requests.name": "HTTP请求" + "upgrade.minecraft.diamond_sword.adjective": "战斗" } From b742745854b74be081a97972a2b4b79464f1fd87 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sun, 10 Nov 2024 21:07:44 +0000 Subject: [PATCH 19/39] Cancel no-longer-needed timers Several functions accept a "timeout" argument, which is implemented by starting a timer, and then racing the desired output against the timer event. However, if the timer never wins, we weren't cancelling the timer, and so it was still queued. This is especially problematic if dozens or hundreds of rednet (or websocket) messages are received in quick succession, as we could fill the entire event queue, and stall the computer. See #1995 --- .../apis/http/websocket/WebsocketHandle.java | 8 +++-- .../data/computercraft/lua/rom/apis/gps.lua | 2 ++ .../computercraft/lua/rom/apis/rednet.lua | 5 ++++ .../test-rom/spec/apis/rednet_spec.lua | 30 +++++++++++++++++++ .../test-rom/spec/support/fake_computer.lua | 12 +++++++- 5 files changed, 54 insertions(+), 3 deletions(-) diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/http/websocket/WebsocketHandle.java b/projects/core/src/main/java/dan200/computercraft/core/apis/http/websocket/WebsocketHandle.java index eafd04df02..11c4da7fe8 100644 --- a/projects/core/src/main/java/dan200/computercraft/core/apis/http/websocket/WebsocketHandle.java +++ b/projects/core/src/main/java/dan200/computercraft/core/apis/http/websocket/WebsocketHandle.java @@ -62,7 +62,7 @@ public final MethodResult receive(Optional timeout) throws LuaException ? environment.startTimer(Math.round(checkFinite(0, timeout.get()) / 0.05)) : -1; - return new ReceiveCallback(timeoutId).pull; + return new ReceiveCallback(environment, timeoutId).pull; } /** @@ -110,18 +110,22 @@ private void checkOpen() throws LuaException { private final class ReceiveCallback implements ILuaCallback { final MethodResult pull = MethodResult.pullEvent(null, this); + private final IAPIEnvironment environment; private final int timeoutId; - ReceiveCallback(int timeoutId) { + ReceiveCallback(IAPIEnvironment environment, int timeoutId) { this.timeoutId = timeoutId; + this.environment = environment; } @Override public MethodResult resume(Object[] event) { if (event.length >= 3 && Objects.equals(event[0], MESSAGE_EVENT) && Objects.equals(event[1], address)) { + environment.cancelTimer(timeoutId); return MethodResult.of(Arrays.copyOfRange(event, 2, event.length)); } else if (event.length >= 2 && Objects.equals(event[0], CLOSE_EVENT) && Objects.equals(event[1], address) && websocket.isClosed()) { // If the socket is closed abort. + environment.cancelTimer(timeoutId); return MethodResult.of(); } else if (event.length >= 2 && timeoutId != -1 && Objects.equals(event[0], TIMER_EVENT) && event[1] instanceof Number id && id.intValue() == timeoutId) { diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/apis/gps.lua b/projects/core/src/main/resources/data/computercraft/lua/rom/apis/gps.lua index a884af2536..e9c33b833c 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/apis/gps.lua +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/apis/gps.lua @@ -196,6 +196,8 @@ function locate(_nTimeout, _bDebug) modem.close(CHANNEL_GPS) end + os.cancelTimer(timeout) + -- Return the response if pos1 and pos2 then if _bDebug then diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/apis/rednet.lua b/projects/core/src/main/resources/data/computercraft/lua/rom/apis/rednet.lua index 097086a516..969e6082cb 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/apis/rednet.lua +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/apis/rednet.lua @@ -298,6 +298,7 @@ function receive(protocol_filter, timeout) -- Return the first matching rednet_message local sender_id, message, protocol = p1, p2, p3 if protocol_filter == nil or protocol == protocol_filter then + if timer then os.cancelTimer(timer) end return sender_id, message, protocol end elseif event == "timer" then @@ -431,6 +432,7 @@ function lookup(protocol, hostname) if hostname == nil then table.insert(results, sender_id) elseif message.sHostname == hostname then + os.cancelTimer(timer) return sender_id end end @@ -440,6 +442,9 @@ function lookup(protocol, hostname) break end end + + os.cancelTimer(timer) + if results then return table.unpack(results) end diff --git a/projects/core/src/test/resources/test-rom/spec/apis/rednet_spec.lua b/projects/core/src/test/resources/test-rom/spec/apis/rednet_spec.lua index d808f13955..1554680031 100644 --- a/projects/core/src/test/resources/test-rom/spec/apis/rednet_spec.lua +++ b/projects/core/src/test/resources/test-rom/spec/apis/rednet_spec.lua @@ -171,6 +171,36 @@ describe("The rednet library", function() fake_computer.run_all { computer_1, computer_2 } end) + describe("timeouts", function() + it("can time out messages", function() + local computer = computer_with_rednet(1, function(rednet) + local id = rednet.receive(1) + expect(id):eq(nil) + end, { open = true }) + + local computers = { computer } + fake_computer.run_all(computers, false) + fake_computer.advance_all(computers, 1) + fake_computer.run_all(computers) + end) + + it("cancels the pending timer", function() + local computer = computer_with_rednet(1, function(rednet) + -- Send a message to ourselves with a timer + rednet.send(1, "hello") + local id = rednet.receive(1) + expect(id):eq(1) + end, { open = true }) + + fake_computer.run_all({ computer }) + + -- Our pending timer list only contains the rednet.run timer. + expect(computer.pending_timers):same { + [debugx.getupvalue(computer.env.rednet.run, "prune_received_timer")] = 10, + } + end) + end) + it("repeats messages between computers", function() local computer_1, modem_1 = computer_with_rednet(1, function(rednet) rednet.send(3, "Hello") diff --git a/projects/core/src/test/resources/test-rom/spec/support/fake_computer.lua b/projects/core/src/test/resources/test-rom/spec/support/fake_computer.lua index a07cc73420..e6d3a7d3e7 100644 --- a/projects/core/src/test/resources/test-rom/spec/support/fake_computer.lua +++ b/projects/core/src/test/resources/test-rom/spec/support/fake_computer.lua @@ -50,6 +50,7 @@ local function make_computer(id, fn) pending_timers[t], next_timer = clock + delay, next_timer + 1 return t end, + cancelTimer = function(id) pending_timers[id] = nil end, clock = function() return clock end, sleep = function(time) local timer = env.os.startTimer(time or 0) @@ -98,7 +99,16 @@ local function make_computer(id, fn) local position = vector.new(0, 0, 0) - return { env = env, peripherals = peripherals, queue_event = queue_event, step = step, co = co, advance = advance, position = position } + return { + env = env, + peripherals = peripherals, + queue_event = queue_event, + step = step, + co = co, + advance = advance, + position = position, + pending_timers = pending_timers, + } end local function parse_channel(c) From ba6da3bc6ce758d99a70d1a61d8db580be36ba9a Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Tue, 12 Nov 2024 08:11:09 +0000 Subject: [PATCH 20/39] Update item image exporter to work on 1.20.x --- .../dan200/computercraft/export/Exporter.java | 24 +++++------- .../computercraft/export/ImageRenderer.java | 37 ++++++++++--------- 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/projects/common/src/testMod/java/dan200/computercraft/export/Exporter.java b/projects/common/src/testMod/java/dan200/computercraft/export/Exporter.java index ebec604968..d852c8774d 100644 --- a/projects/common/src/testMod/java/dan200/computercraft/export/Exporter.java +++ b/projects/common/src/testMod/java/dan200/computercraft/export/Exporter.java @@ -9,7 +9,6 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; @@ -19,8 +18,8 @@ import dan200.computercraft.gametest.core.TestHooks; import dan200.computercraft.shared.platform.RegistryWrappers; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; import net.minecraft.network.chat.Component; -import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.crafting.ShapedRecipe; @@ -32,9 +31,8 @@ import java.io.Writer; import java.nio.file.Files; import java.nio.file.Path; -import java.util.HashSet; import java.util.Objects; -import java.util.Set; +import java.util.stream.Collectors; /** * Provides a {@literal /ccexport } command which exports icons and recipes for all ComputerCraft items. @@ -72,12 +70,10 @@ private static void run(String path) { private static void export(Path root, ImageRenderer renderer) throws IOException { var dump = new JsonDump(); - Set items = new HashSet<>(); - // First find all CC items - for (var item : RegistryWrappers.ITEMS) { - if (RegistryWrappers.ITEMS.getKey(item).getNamespace().equals(ComputerCraftAPI.MOD_ID)) items.add(item); - } + var items = RegistryWrappers.ITEMS.stream() + .filter(x -> RegistryWrappers.ITEMS.getKey(x).getNamespace().equals(ComputerCraftAPI.MOD_ID)) + .collect(Collectors.toSet()); // Now find all CC recipes. var level = Objects.requireNonNull(Minecraft.getInstance().level); @@ -121,10 +117,6 @@ private static void export(Path root, ImageRenderer renderer) throws IOException var itemDir = root.resolve("items"); if (Files.exists(itemDir)) MoreFiles.deleteRecursively(itemDir, RecursiveDeleteOption.ALLOW_INSECURE); - renderer.setupState(); - var transform = new PoseStack(); - transform.setIdentity(); - for (var item : items) { var stack = new ItemStack(item); var location = RegistryWrappers.ITEMS.getKey(item); @@ -132,11 +124,13 @@ private static void export(Path root, ImageRenderer renderer) throws IOException dump.itemNames.put(location.toString(), stack.getHoverName().getString()); renderer.captureRender(itemDir.resolve(location.getNamespace()).resolve(location.getPath() + ".png"), () -> { - // TODO: Minecraft.getInstance().getItemRenderer().ren(transform, stack, 0, 0) + + var graphics = new GuiGraphics(Minecraft.getInstance(), Minecraft.getInstance().renderBuffers().bufferSource()); + graphics.renderItem(stack, 0, 0); + graphics.flush(); } ); } - renderer.clearState(); try (Writer writer = Files.newBufferedWriter(root.resolve("index.json")); var jsonWriter = new PrettyJsonWriter(writer)) { GSON.toJson(dump, JsonDump.class, jsonWriter); diff --git a/projects/common/src/testMod/java/dan200/computercraft/export/ImageRenderer.java b/projects/common/src/testMod/java/dan200/computercraft/export/ImageRenderer.java index 032fc7bb78..ea3d8bc7e5 100644 --- a/projects/common/src/testMod/java/dan200/computercraft/export/ImageRenderer.java +++ b/projects/common/src/testMod/java/dan200/computercraft/export/ImageRenderer.java @@ -5,15 +5,14 @@ package dan200.computercraft.export; import com.mojang.blaze3d.pipeline.TextureTarget; +import com.mojang.blaze3d.platform.Lighting; import com.mojang.blaze3d.platform.NativeImage; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.VertexSorting; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.FogRenderer; import org.joml.Matrix4f; -import org.lwjgl.opengl.GL12; -import javax.annotation.Nullable; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -28,39 +27,43 @@ public class ImageRenderer implements AutoCloseable { private final TextureTarget framebuffer = new TextureTarget(WIDTH, HEIGHT, true, Minecraft.ON_OSX); private final NativeImage image = new NativeImage(WIDTH, HEIGHT, Minecraft.ON_OSX); - private @Nullable Matrix4f projectionMatrix; - public ImageRenderer() { framebuffer.setClearColor(0, 0, 0, 0); framebuffer.clear(Minecraft.ON_OSX); } - public void setupState() { - projectionMatrix = RenderSystem.getProjectionMatrix(); - RenderSystem.setProjectionMatrix(new Matrix4f().identity().ortho(0, 16, 0, 16, 1000, 3000), VertexSorting.DISTANCE_TO_ORIGIN); + public void captureRender(Path output, Runnable render) throws IOException { + Files.createDirectories(output.getParent()); + + framebuffer.setClearColor(0, 0, 0, 0); + framebuffer.clear(Minecraft.ON_OSX); + framebuffer.bindWrite(true); + + // Setup rendering state + var projectionMatrix = RenderSystem.getProjectionMatrix(); + RenderSystem.setProjectionMatrix(new Matrix4f().identity().ortho(0, 16, 16, 0, 1000, 3000), VertexSorting.ORTHOGRAPHIC_Z); var transform = RenderSystem.getModelViewStack(); transform.pushPose(); transform.setIdentity(); transform.translate(0.0f, 0.0f, -2000.0f); + RenderSystem.applyModelViewMatrix(); + Lighting.setupFor3DItems(); FogRenderer.setupNoFog(); - } - public void clearState() { - if (projectionMatrix == null) throw new IllegalStateException("Not currently rendering"); + // Render + render.run(); + + // Restore rendering state RenderSystem.setProjectionMatrix(projectionMatrix, VertexSorting.DISTANCE_TO_ORIGIN); RenderSystem.getModelViewStack().popPose(); - } - - public void captureRender(Path output, Runnable render) throws IOException { - Files.createDirectories(output.getParent()); + RenderSystem.applyModelViewMatrix(); - framebuffer.bindWrite(true); - RenderSystem.clear(GL12.GL_COLOR_BUFFER_BIT | GL12.GL_DEPTH_BUFFER_BIT, Minecraft.ON_OSX); - render.run(); framebuffer.unbindWrite(); + Minecraft.getInstance().getMainRenderTarget().bindWrite(true); + // And save the image framebuffer.bindRead(); image.downloadTexture(0, false); image.flipY(); From 4f66ac79d3774a4093d3d14979c10c2f1d59c24d Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Tue, 12 Nov 2024 09:05:27 +0000 Subject: [PATCH 21/39] Add redstone relay block (#2002) - Move redstone methods out of the IAPIEnvironment, and into a new RedstoneAccess. We similarly move the implementation from Environment into a new RedstoneState class. The interface is possibly a little redundant (interfaces with a single implementation are always a little suspect), but it's nice to keep the consumer/producer interfaces separate. - Abstract most redstone API methods into a separate shared class, that can be used by both the rs API and the new redstone relay. - Add the new redstone relay block. The docs are probably a little lacking here, but I really struggled to write anything which wasn't just "look, it's the same as the redstone API". --- doc/events/redstone.md | 6 +- gradle/libs.versions.toml | 2 +- .../blockstates/redstone_relay.json | 8 + .../assets/computercraft/lang/en_us.json | 1 + .../models/block/redstone_relay.json | 9 + .../models/item/redstone_relay.json | 1 + .../recipes/redstone/redstone_relay.json | 16 ++ .../loot_tables/blocks/redstone_relay.json | 12 + .../data/BlockModelProvider.java | 14 + .../computercraft/data/LanguageProvider.java | 1 + .../computercraft/data/LootTableProvider.java | 1 + .../computercraft/data/RecipeProvider.java | 11 + .../computercraft/data/TagProvider.java | 5 +- .../computercraft/shared/ModRegistry.java | 17 +- .../blocks/AbstractComputerBlockEntity.java | 8 +- .../shared/computer/core/ServerComputer.java | 16 +- .../redstone/RedstoneRelayBlock.java | 84 ++++++ .../redstone/RedstoneRelayBlockEntity.java | 92 +++++++ .../redstone/RedstoneRelayPeripheral.java | 71 +++++ .../textures/block/redstone_relay_bottom.png | Bin 0 -> 289 bytes .../textures/block/redstone_relay_front.png | Bin 0 -> 334 bytes .../textures/block/redstone_relay_side.png | Bin 0 -> 316 bytes .../textures/block/redstone_relay_top.png | Bin 0 -> 289 bytes .../computercraft/gametest/Relay_Test.kt | 99 +++++++ .../computercraft/gametest/core/TestHooks.kt | 1 + .../relay_test.no_through_signal.snbt | 141 ++++++++++ .../relay_test.no_through_signal_reverse.snbt | 141 ++++++++++ .../relay_test.self_output_update.snbt | 137 ++++++++++ .../relay_test.set_and_destroy.snbt | 138 ++++++++++ .../core/apis/IAPIEnvironment.java | 12 - .../computercraft/core/apis/RedstoneAPI.java | 137 +--------- .../core/apis/RedstoneMethods.java | 147 +++++++++++ .../computercraft/core/computer/Computer.java | 17 +- .../core/computer/ComputerExecutor.java | 7 +- .../core/computer/Environment.java | 139 +--------- .../core/redstone/RedstoneAccess.java | 63 +++++ .../core/redstone/RedstoneState.java | 248 ++++++++++++++++++ .../test/core/apis/BasicApiEnvironment.java | 28 -- .../computercraft/recipes/redstone_relay.json | 12 + .../minecraft/tags/blocks/mineable/axe.json | 1 + .../tags/blocks/mineable/pickaxe.json | 3 +- .../computercraft/shared/ComputerCraft.java | 1 + .../computercraft/recipes/redstone_relay.json | 12 + .../minecraft/tags/blocks/mineable/axe.json | 1 + .../tags/blocks/mineable/pickaxe.json | 3 +- .../shared/ForgeCommonHooks.java | 14 +- .../web/src/htmlTransform/export/index.json | 83 +++++- .../items/computercraft/redstone_relay.png | Bin 0 -> 1625 bytes .../export/items/minecraft/stick.png | Bin 0 -> 154 bytes .../cc/tweaked/web/stub/ReentrantLock.java | 3 + 50 files changed, 1610 insertions(+), 353 deletions(-) create mode 100644 projects/common/src/generated/resources/assets/computercraft/blockstates/redstone_relay.json create mode 100644 projects/common/src/generated/resources/assets/computercraft/models/block/redstone_relay.json create mode 100644 projects/common/src/generated/resources/assets/computercraft/models/item/redstone_relay.json create mode 100644 projects/common/src/generated/resources/data/computercraft/advancements/recipes/redstone/redstone_relay.json create mode 100644 projects/common/src/generated/resources/data/computercraft/loot_tables/blocks/redstone_relay.json create mode 100644 projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayBlock.java create mode 100644 projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayBlockEntity.java create mode 100644 projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayPeripheral.java create mode 100644 projects/common/src/main/resources/assets/computercraft/textures/block/redstone_relay_bottom.png create mode 100644 projects/common/src/main/resources/assets/computercraft/textures/block/redstone_relay_front.png create mode 100644 projects/common/src/main/resources/assets/computercraft/textures/block/redstone_relay_side.png create mode 100644 projects/common/src/main/resources/assets/computercraft/textures/block/redstone_relay_top.png create mode 100644 projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Relay_Test.kt create mode 100644 projects/common/src/testMod/resources/data/cctest/structures/relay_test.no_through_signal.snbt create mode 100644 projects/common/src/testMod/resources/data/cctest/structures/relay_test.no_through_signal_reverse.snbt create mode 100644 projects/common/src/testMod/resources/data/cctest/structures/relay_test.self_output_update.snbt create mode 100644 projects/common/src/testMod/resources/data/cctest/structures/relay_test.set_and_destroy.snbt create mode 100644 projects/core/src/main/java/dan200/computercraft/core/apis/RedstoneMethods.java create mode 100644 projects/core/src/main/java/dan200/computercraft/core/redstone/RedstoneAccess.java create mode 100644 projects/core/src/main/java/dan200/computercraft/core/redstone/RedstoneState.java create mode 100644 projects/fabric/src/generated/resources/data/computercraft/recipes/redstone_relay.json create mode 100644 projects/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json create mode 100644 projects/forge/src/generated/resources/data/computercraft/recipes/redstone_relay.json create mode 100644 projects/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json create mode 100644 projects/web/src/htmlTransform/export/items/computercraft/redstone_relay.png create mode 100644 projects/web/src/htmlTransform/export/items/minecraft/stick.png diff --git a/doc/events/redstone.md b/doc/events/redstone.md index d097fc2b50..736363bf03 100644 --- a/doc/events/redstone.md +++ b/doc/events/redstone.md @@ -8,7 +8,7 @@ SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers SPDX-License-Identifier: MPL-2.0 --> -The [`event!redstone`] event is fired whenever any redstone inputs on the computer change. +The [`event!redstone`] event is fired whenever any redstone inputs on the computer or [relay][`redstone_relay`] change. ## Return values 1. [`string`]: The event name. @@ -21,3 +21,7 @@ while true do print("A redstone input has changed!") end ``` + +## See also + - [The `redstone` API on computers][`module!redstone`] + - [The `redstone_relay` peripheral][`redstone_relay`] diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 87231a21f9..cb337ee27c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -56,7 +56,7 @@ junit = "5.10.1" jmh = "1.37" # Build tools -cctJavadoc = "1.8.2" +cctJavadoc = "1.8.3" checkstyle = "10.14.1" curseForgeGradle = "1.0.14" errorProne-core = "2.27.0" diff --git a/projects/common/src/generated/resources/assets/computercraft/blockstates/redstone_relay.json b/projects/common/src/generated/resources/assets/computercraft/blockstates/redstone_relay.json new file mode 100644 index 0000000000..5a813aa867 --- /dev/null +++ b/projects/common/src/generated/resources/assets/computercraft/blockstates/redstone_relay.json @@ -0,0 +1,8 @@ +{ + "variants": { + "facing=east": {"model": "computercraft:block/redstone_relay", "y": 90}, + "facing=north": {"model": "computercraft:block/redstone_relay", "y": 0}, + "facing=south": {"model": "computercraft:block/redstone_relay", "y": 180}, + "facing=west": {"model": "computercraft:block/redstone_relay", "y": 270} + } +} diff --git a/projects/common/src/generated/resources/assets/computercraft/lang/en_us.json b/projects/common/src/generated/resources/assets/computercraft/lang/en_us.json index dde797f0e4..0802004c44 100644 --- a/projects/common/src/generated/resources/assets/computercraft/lang/en_us.json +++ b/projects/common/src/generated/resources/assets/computercraft/lang/en_us.json @@ -17,6 +17,7 @@ "block.computercraft.monitor_advanced": "Advanced Monitor", "block.computercraft.monitor_normal": "Monitor", "block.computercraft.printer": "Printer", + "block.computercraft.redstone_relay": "Redstone Relay", "block.computercraft.speaker": "Speaker", "block.computercraft.turtle_advanced": "Advanced Turtle", "block.computercraft.turtle_advanced.upgraded": "Advanced %s Turtle", diff --git a/projects/common/src/generated/resources/assets/computercraft/models/block/redstone_relay.json b/projects/common/src/generated/resources/assets/computercraft/models/block/redstone_relay.json new file mode 100644 index 0000000000..e35b88836a --- /dev/null +++ b/projects/common/src/generated/resources/assets/computercraft/models/block/redstone_relay.json @@ -0,0 +1,9 @@ +{ + "parent": "minecraft:block/orientable_with_bottom", + "textures": { + "bottom": "computercraft:block/redstone_relay_bottom", + "front": "computercraft:block/redstone_relay_front", + "side": "computercraft:block/redstone_relay_side", + "top": "computercraft:block/redstone_relay_top" + } +} diff --git a/projects/common/src/generated/resources/assets/computercraft/models/item/redstone_relay.json b/projects/common/src/generated/resources/assets/computercraft/models/item/redstone_relay.json new file mode 100644 index 0000000000..3ffb62221e --- /dev/null +++ b/projects/common/src/generated/resources/assets/computercraft/models/item/redstone_relay.json @@ -0,0 +1 @@ +{"parent": "computercraft:block/redstone_relay"} diff --git a/projects/common/src/generated/resources/data/computercraft/advancements/recipes/redstone/redstone_relay.json b/projects/common/src/generated/resources/data/computercraft/advancements/recipes/redstone/redstone_relay.json new file mode 100644 index 0000000000..d3a1b65e15 --- /dev/null +++ b/projects/common/src/generated/resources/data/computercraft/advancements/recipes/redstone/redstone_relay.json @@ -0,0 +1,16 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_cable": { + "conditions": {"items": [{"items": ["computercraft:wired_modem"]}]}, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": {"recipe": "computercraft:redstone_relay"}, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [["has_cable", "has_the_recipe"]], + "rewards": {"recipes": ["computercraft:redstone_relay"]}, + "sends_telemetry_event": false +} diff --git a/projects/common/src/generated/resources/data/computercraft/loot_tables/blocks/redstone_relay.json b/projects/common/src/generated/resources/data/computercraft/loot_tables/blocks/redstone_relay.json new file mode 100644 index 0000000000..1f2b43ff5a --- /dev/null +++ b/projects/common/src/generated/resources/data/computercraft/loot_tables/blocks/redstone_relay.json @@ -0,0 +1,12 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [{"condition": "minecraft:survives_explosion"}], + "entries": [{"type": "minecraft:item", "name": "computercraft:redstone_relay"}], + "rolls": 1.0 + } + ], + "random_sequence": "computercraft:blocks/redstone_relay" +} diff --git a/projects/common/src/main/java/dan200/computercraft/data/BlockModelProvider.java b/projects/common/src/main/java/dan200/computercraft/data/BlockModelProvider.java index 274557ad23..a33a277666 100644 --- a/projects/common/src/main/java/dan200/computercraft/data/BlockModelProvider.java +++ b/projects/common/src/main/java/dan200/computercraft/data/BlockModelProvider.java @@ -97,6 +97,8 @@ public static void addBlockModels(BlockModelGenerators generators) { registerCable(generators); + registerRedstoneControl(generators); + registerTurtleUpgrade(generators, "block/turtle_crafting_table", "block/turtle_crafty_face"); registerTurtleUpgrade(generators, "block/turtle_speaker", "block/turtle_speaker_face"); registerTurtleModem(generators, "block/turtle_modem_normal", "block/wireless_modem_normal_face"); @@ -355,6 +357,18 @@ private static void registerCable(BlockModelGenerators generators) { generators.blockStateOutput.accept(generator); } + private static void registerRedstoneControl(BlockModelGenerators generators) { + var redstoneControl = ModRegistry.Blocks.REDSTONE_RELAY.get(); + var model = ModelTemplates.CUBE_ORIENTABLE_TOP_BOTTOM.create( + redstoneControl, TextureMapping.orientableCube(redstoneControl), generators.modelOutput + ); + generators.blockStateOutput.accept( + MultiVariantGenerator.multiVariant(redstoneControl, Variant.variant().with(VariantProperties.MODEL, model)) + .with(createHorizontalFacingDispatch()) + ); + } + + private static final BooleanProperty[] CABLE_DIRECTIONS = { CableBlock.DOWN, CableBlock.UP, CableBlock.NORTH, CableBlock.SOUTH, CableBlock.WEST, CableBlock.EAST }; private static final boolean[] BOOLEANS = new boolean[]{ false, true }; diff --git a/projects/common/src/main/java/dan200/computercraft/data/LanguageProvider.java b/projects/common/src/main/java/dan200/computercraft/data/LanguageProvider.java index 1f23f7873f..09713d21a3 100644 --- a/projects/common/src/main/java/dan200/computercraft/data/LanguageProvider.java +++ b/projects/common/src/main/java/dan200/computercraft/data/LanguageProvider.java @@ -80,6 +80,7 @@ private void addTranslations() { add(ModRegistry.Items.WIRED_MODEM.get(), "Wired Modem"); add(ModRegistry.Items.CABLE.get(), "Networking Cable"); add(ModRegistry.Items.WIRED_MODEM_FULL.get(), "Wired Modem"); + add(ModRegistry.Items.REDSTONE_RELAY.get(), "Redstone Relay"); add(ModRegistry.Items.TURTLE_NORMAL.get(), "Turtle"); add(ModRegistry.Blocks.TURTLE_NORMAL.get().getDescriptionId() + ".upgraded", "%s Turtle"); diff --git a/projects/common/src/main/java/dan200/computercraft/data/LootTableProvider.java b/projects/common/src/main/java/dan200/computercraft/data/LootTableProvider.java index 5f0f5b5ac7..bfd7f63198 100644 --- a/projects/common/src/main/java/dan200/computercraft/data/LootTableProvider.java +++ b/projects/common/src/main/java/dan200/computercraft/data/LootTableProvider.java @@ -51,6 +51,7 @@ private static void registerBlocks(BiConsumer add) { .requires(ingredients.string()) .unlockedBy("has_printer", inventoryChange(ModRegistry.Blocks.PRINTER.get())) .save(RecipeWrapper.wrap(ModRegistry.RecipeSerializers.IMPOSTOR_SHAPELESS.get(), add)); + + ShapedRecipeBuilder + .shaped(RecipeCategory.REDSTONE, ModRegistry.Blocks.REDSTONE_RELAY.get()) + .pattern("SRS") + .pattern("RCR") + .pattern("SRS") + .define('S', Items.STONE) + .define('R', ingredients.redstone()) + .define('C', ModRegistry.Blocks.CABLE.get()) + .unlockedBy("has_cable", inventoryChange(ModRegistry.Blocks.CABLE.get())) + .save(add); } private static DyeColor ofColour(Colour colour) { diff --git a/projects/common/src/main/java/dan200/computercraft/data/TagProvider.java b/projects/common/src/main/java/dan200/computercraft/data/TagProvider.java index 795ecca151..04cf493da4 100644 --- a/projects/common/src/main/java/dan200/computercraft/data/TagProvider.java +++ b/projects/common/src/main/java/dan200/computercraft/data/TagProvider.java @@ -78,9 +78,12 @@ public static void blockTags(TagConsumer tags) { ModRegistry.Blocks.WIRELESS_MODEM_NORMAL.get(), ModRegistry.Blocks.WIRELESS_MODEM_ADVANCED.get(), ModRegistry.Blocks.WIRED_MODEM_FULL.get(), - ModRegistry.Blocks.CABLE.get() + ModRegistry.Blocks.CABLE.get(), + ModRegistry.Blocks.REDSTONE_RELAY.get() ); + tags.tag(BlockTags.MINEABLE_WITH_AXE).add(ModRegistry.Blocks.LECTERN.get()); + tags.tag(BlockTags.WITHER_IMMUNE).add(ModRegistry.Blocks.COMPUTER_COMMAND.get()); tags.tag(ExternalModTags.Blocks.CREATE_BRITTLE).add( diff --git a/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java b/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java index 5cb731e146..b12a8f0cac 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java @@ -62,6 +62,8 @@ import dan200.computercraft.shared.peripheral.printer.PrinterBlock; import dan200.computercraft.shared.peripheral.printer.PrinterBlockEntity; import dan200.computercraft.shared.peripheral.printer.PrinterMenu; +import dan200.computercraft.shared.peripheral.redstone.RedstoneRelayBlock; +import dan200.computercraft.shared.peripheral.redstone.RedstoneRelayBlockEntity; import dan200.computercraft.shared.peripheral.speaker.SpeakerBlock; import dan200.computercraft.shared.peripheral.speaker.SpeakerBlockEntity; import dan200.computercraft.shared.platform.PlatformHelper; @@ -132,7 +134,7 @@ private static BlockBehaviour.Properties properties() { return BlockBehaviour.Properties.of().strength(2); } - private static BlockBehaviour.Properties computerProperties() { + private static BlockBehaviour.Properties redstoneConductor() { // Computers shouldn't conduct redstone through them, so set isRedstoneConductor to false. This still allows // redstone to connect to computers though as it's a signal source. return properties().isRedstoneConductor((block, level, blockPos) -> false); @@ -147,11 +149,11 @@ private static BlockBehaviour.Properties modemProperties() { } public static final RegistryEntry> COMPUTER_NORMAL = REGISTRY.register("computer_normal", - () -> new ComputerBlock<>(computerProperties().mapColor(MapColor.STONE), BlockEntities.COMPUTER_NORMAL)); + () -> new ComputerBlock<>(redstoneConductor().mapColor(MapColor.STONE), BlockEntities.COMPUTER_NORMAL)); public static final RegistryEntry> COMPUTER_ADVANCED = REGISTRY.register("computer_advanced", - () -> new ComputerBlock<>(computerProperties().mapColor(MapColor.GOLD), BlockEntities.COMPUTER_ADVANCED)); + () -> new ComputerBlock<>(redstoneConductor().mapColor(MapColor.GOLD), BlockEntities.COMPUTER_ADVANCED)); public static final RegistryEntry> COMPUTER_COMMAND = REGISTRY.register("computer_command", - () -> new CommandComputerBlock<>(computerProperties().strength(-1, 6000000.0F), BlockEntities.COMPUTER_COMMAND)); + () -> new CommandComputerBlock<>(redstoneConductor().strength(-1, 6000000.0F), BlockEntities.COMPUTER_COMMAND)); public static final RegistryEntry TURTLE_NORMAL = REGISTRY.register("turtle_normal", () -> new TurtleBlock(turtleProperties().mapColor(MapColor.STONE), BlockEntities.TURTLE_NORMAL)); @@ -179,6 +181,9 @@ private static BlockBehaviour.Properties modemProperties() { public static final RegistryEntry LECTERN = REGISTRY.register("lectern", () -> new CustomLecternBlock( BlockBehaviour.Properties.of().mapColor(MapColor.WOOD).instrument(NoteBlockInstrument.BASS).strength(2.5F).sound(SoundType.WOOD).ignitedByLava() )); + + public static final RegistryEntry REDSTONE_RELAY = REGISTRY.register("redstone_relay", + () -> new RedstoneRelayBlock(redstoneConductor().mapColor(MapColor.STONE))); } public static class BlockEntities { @@ -222,6 +227,8 @@ private static RegistryEntry> ofBlock ofBlock(Blocks.WIRELESS_MODEM_ADVANCED, (p, s) -> new WirelessModemBlockEntity(BlockEntities.WIRELESS_MODEM_ADVANCED.get(), p, s, true)); public static final RegistryEntry> LECTERN = ofBlock(Blocks.LECTERN, CustomLecternBlockEntity::new); + + public static final RegistryEntry> REDSTONE_RELAY = ofBlock(Blocks.REDSTONE_RELAY, RedstoneRelayBlockEntity::new); } public static final class Items { @@ -267,6 +274,7 @@ private static RegistryEntry ofBlock(Regist public static final RegistryEntry WIRELESS_MODEM_NORMAL = ofBlock(Blocks.WIRELESS_MODEM_NORMAL, BlockItem::new); public static final RegistryEntry WIRELESS_MODEM_ADVANCED = ofBlock(Blocks.WIRELESS_MODEM_ADVANCED, BlockItem::new); public static final RegistryEntry WIRED_MODEM_FULL = ofBlock(Blocks.WIRED_MODEM_FULL, BlockItem::new); + public static final RegistryEntry REDSTONE_RELAY = ofBlock(Blocks.REDSTONE_RELAY, BlockItem::new); public static final RegistryEntry CABLE = REGISTRY.register("cable", () -> new CableBlockItem.Cable(Blocks.CABLE.get(), properties())); @@ -415,6 +423,7 @@ static class CreativeTabs { out.accept(Items.CABLE.get()); out.accept(Items.WIRED_MODEM.get()); out.accept(Items.WIRED_MODEM_FULL.get()); + out.accept(Items.REDSTONE_RELAY.get()); out.accept(Items.MONITOR_NORMAL.get()); out.accept(Items.MONITOR_ADVANCED.get()); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlockEntity.java index e0f5e688bd..aaceb04eef 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlockEntity.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/blocks/AbstractComputerBlockEntity.java @@ -127,7 +127,7 @@ protected void serverTick() { // Update the block state if needed. updateBlockState(computer.getState()); - var changes = computer.pollAndResetChanges(); + var changes = computer.pollRedstoneChanges(); if (changes != 0) { for (var direction : DirectionUtil.FACINGS) { if ((changes & (1 << remapToLocalSide(direction).ordinal())) != 0) updateRedstoneTo(direction); @@ -195,8 +195,10 @@ private void updateRedstoneInput(ServerComputer computer, Direction dir, BlockPo var offsetSide = dir.getOpposite(); var localDir = remapToLocalSide(dir); - computer.setRedstoneInput(localDir, RedstoneUtil.getRedstoneInput(getLevel(), targetPos, dir)); - computer.setBundledRedstoneInput(localDir, BundledRedstone.getOutput(getLevel(), targetPos, offsetSide)); + computer.setRedstoneInput(localDir, + RedstoneUtil.getRedstoneInput(getLevel(), targetPos, dir), + BundledRedstone.getOutput(getLevel(), targetPos, offsetSide) + ); } /** diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java index 808f38cbb7..3a7d08cec1 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java @@ -134,8 +134,8 @@ boolean hasTimedOut() { * * @return What sides on the computer have changed. */ - public int pollAndResetChanges() { - return computer.pollAndResetChanges(); + public int pollRedstoneChanges() { + return computer.pollRedstoneChanges(); } public UUID register() { @@ -222,19 +222,15 @@ public void queueEvent(String event, @Nullable Object[] arguments) { } public int getRedstoneOutput(ComputerSide side) { - return computer.getEnvironment().getExternalRedstoneOutput(side); + return computer.isOn() ? computer.getRedstone().getExternalOutput(side) : 0; } - public void setRedstoneInput(ComputerSide side, int level) { - computer.getEnvironment().setRedstoneInput(side, level); + public void setRedstoneInput(ComputerSide side, int level, int bundledState) { + computer.getRedstone().setInput(side, level, bundledState); } public int getBundledRedstoneOutput(ComputerSide side) { - return computer.getEnvironment().getExternalBundledRedstoneOutput(side); - } - - public void setBundledRedstoneInput(ComputerSide side, int combination) { - computer.getEnvironment().setBundledRedstoneInput(side, combination); + return computer.isOn() ? computer.getRedstone().getExternalBundledOutput(side) : 0; } public void setPeripheral(ComputerSide side, @Nullable IPeripheral peripheral) { diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayBlock.java new file mode 100644 index 0000000000..61146ee096 --- /dev/null +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayBlock.java @@ -0,0 +1,84 @@ +// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 +package dan200.computercraft.shared.peripheral.redstone; + +import dan200.computercraft.shared.common.IBundledRedstoneBlock; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.HorizontalDirectionalBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; + +import javax.annotation.Nonnull; + +/** + * The block for redstone relays. This mostly just forwards method calls to the {@linkplain RedstoneRelayBlockEntity + * block entity}. + */ +public final class RedstoneRelayBlock extends HorizontalDirectionalBlock implements EntityBlock, IBundledRedstoneBlock { + public RedstoneRelayBlock(Properties properties) { + super(properties); + registerDefaultState(defaultBlockState().setValue(FACING, Direction.NORTH)); + } + + @Override + protected void createBlockStateDefinition(StateDefinition.Builder properties) { + properties.add(FACING); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext placement) { + return defaultBlockState().setValue(FACING, placement.getHorizontalDirection()); + } + + @Override + @Deprecated + public void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + super.tick(state, level, pos, random); + + if (level.getBlockEntity(pos) instanceof RedstoneRelayBlockEntity relay) relay.update(); + } + + @Override + @Deprecated + public boolean isSignalSource(@Nonnull BlockState state) { + return true; + } + + @Override + @Deprecated + public int getDirectSignal(@Nonnull BlockState state, BlockGetter level, @Nonnull BlockPos pos, @Nonnull Direction incomingSide) { + return level.getBlockEntity(pos) instanceof RedstoneRelayBlockEntity relay ? relay.getRedstoneOutput(incomingSide.getOpposite()) : 0; + } + + @Override + @Deprecated + public int getSignal(BlockState state, BlockGetter level, BlockPos pos, Direction direction) { + return getDirectSignal(state, level, pos, direction); + } + + @Override + public int getBundledRedstoneOutput(Level level, BlockPos pos, Direction side) { + return level.getBlockEntity(pos) instanceof RedstoneRelayBlockEntity relay ? relay.getBundledRedstoneOutput(side) : 0; + } + + @Override + @Deprecated + public void neighborChanged(@Nonnull BlockState state, @Nonnull Level world, @Nonnull BlockPos pos, @Nonnull Block neighbourBlock, @Nonnull BlockPos neighbourPos, boolean isMoving) { + if (world.getBlockEntity(pos) instanceof RedstoneRelayBlockEntity relay) relay.neighborChanged(neighbourPos); + } + + @Override + public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { + return new RedstoneRelayBlockEntity(pos, state); + } +} diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayBlockEntity.java new file mode 100644 index 0000000000..833b0d4ad2 --- /dev/null +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayBlockEntity.java @@ -0,0 +1,92 @@ +// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 +package dan200.computercraft.shared.peripheral.redstone; + +import dan200.computercraft.api.peripheral.IPeripheral; +import dan200.computercraft.core.computer.ComputerSide; +import dan200.computercraft.core.redstone.RedstoneState; +import dan200.computercraft.impl.BundledRedstone; +import dan200.computercraft.shared.ModRegistry; +import dan200.computercraft.shared.util.DirectionUtil; +import dan200.computercraft.shared.util.RedstoneUtil; +import dan200.computercraft.shared.util.TickScheduler; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.block.HorizontalDirectionalBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; + +public final class RedstoneRelayBlockEntity extends BlockEntity { + private final TickScheduler.Token tickToken = new TickScheduler.Token(this); + + private final RedstoneState redstoneState = new RedstoneState(() -> TickScheduler.schedule(tickToken)); + private final RedstoneRelayPeripheral peripheral = new RedstoneRelayPeripheral(redstoneState); + + public RedstoneRelayBlockEntity(BlockPos pos, BlockState blockState) { + super(ModRegistry.BlockEntities.REDSTONE_RELAY.get(), pos, blockState); + } + + @Override + public void clearRemoved() { + super.clearRemoved(); + TickScheduler.schedule(tickToken); + } + + void update() { + var changes = redstoneState.updateOutput(); + if (changes != 0) { + for (var direction : DirectionUtil.FACINGS) { + if ((changes & (1 << mapSide(direction).ordinal())) != 0) updateRedstoneTo(direction); + } + } + + if (redstoneState.pollInputChanged()) peripheral.queueRedstoneEvent(); + } + + void neighborChanged(BlockPos neighbour) { + for (var dir : DirectionUtil.FACINGS) { + var offset = getBlockPos().relative(dir); + if (offset.equals(neighbour)) { + updateRedstoneInput(dir, offset, false); + return; + } + } + + // If the position is not any adjacent one, update all inputs. This is pretty terrible, but some redstone mods + // handle this incorrectly. + for (var dir : DirectionUtil.FACINGS) updateRedstoneInput(dir, getBlockPos().relative(dir), false); + } + + private void updateRedstoneTo(Direction direction) { + RedstoneUtil.propagateRedstoneOutput(getLevel(), getBlockPos(), direction); + updateRedstoneInput(direction, getBlockPos().relative(direction), true); + } + + private void updateRedstoneInput(Direction dir, BlockPos targetPos, boolean ticking) { + var changed = redstoneState.setInput(mapSide(dir), + RedstoneUtil.getRedstoneInput(getLevel(), targetPos, dir), + BundledRedstone.getOutput(getLevel(), targetPos, dir.getOpposite()) + ); + + // If the input has changed, and we're not currently in update(), then schedule a new tick so we can queue a + // redstone event. + if (changed && !ticking) TickScheduler.schedule(tickToken); + } + + private ComputerSide mapSide(Direction globalSide) { + return DirectionUtil.toLocal(getBlockState().getValue(HorizontalDirectionalBlock.FACING), globalSide); + } + + int getRedstoneOutput(Direction side) { + return redstoneState.getExternalOutput(mapSide(side)); + } + + int getBundledRedstoneOutput(Direction side) { + return redstoneState.getExternalBundledOutput(mapSide(side)); + } + + public IPeripheral peripheral() { + return peripheral; + } +} diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayPeripheral.java new file mode 100644 index 0000000000..e0a73a1074 --- /dev/null +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayPeripheral.java @@ -0,0 +1,71 @@ +// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 +package dan200.computercraft.shared.peripheral.redstone; + +import dan200.computercraft.api.peripheral.AttachedComputerSet; +import dan200.computercraft.api.peripheral.IComputerAccess; +import dan200.computercraft.api.peripheral.IPeripheral; +import dan200.computercraft.core.apis.RedstoneAPI; +import dan200.computercraft.core.apis.RedstoneMethods; +import dan200.computercraft.core.redstone.RedstoneAccess; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * The redstone relay is a peripheral that allows reading and outputting redstone signals. + *

+ * The peripheral provides largely identical methods to a computer's built-in {@link RedstoneAPI} API, allowing setting + * signals on all six sides of the block ("top", "bottom", "left", "right", "front" and "back"). + * + *

+ * ## Recipe + *

+ * + *
+ * + * @cc.usage Toggle the redstone signal above the computer every 0.5 seconds. + * + *
{@code
+ * local relay = peripheral.find("redstone_relay")
+ * while true do
+ *   relay.setOutput("top", not relay.getOutput("top"))
+ *   sleep(0.5)
+ * end
+ * }
+ * @cc.module redstone_relay + * @cc.since 1.114.0 + */ +public final class RedstoneRelayPeripheral extends RedstoneMethods implements IPeripheral { + private final AttachedComputerSet computers = new AttachedComputerSet(); + + RedstoneRelayPeripheral(RedstoneAccess access) { + super(access); + } + + @Nonnull + @Override + public String getType() { + return "redstone_relay"; + } + + @Override + public boolean equals(@Nullable IPeripheral other) { + return this == other; + } + + @Override + public void attach(IComputerAccess computer) { + computers.add(computer); + } + + @Override + public void detach(IComputerAccess computer) { + computers.remove(computer); + } + + void queueRedstoneEvent() { + computers.queueEvent("redstone"); + } +} diff --git a/projects/common/src/main/resources/assets/computercraft/textures/block/redstone_relay_bottom.png b/projects/common/src/main/resources/assets/computercraft/textures/block/redstone_relay_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..cad4772d690c79eba1b589ba9dede8b610e0a616 GIT binary patch literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!Uw}`DtFp4Pii(Q5y1J&Orna`W zuCA`WzP^Ehfsv7sv9YnKsi~QnnT3Ugm6esXwY80ghPS>>addQ5RaI?mZGC-xLqkJz zbMr=KhAWIr{~4I;LdE)lCii)|IEF}Ej_p6_c-TPXXr0I0mV{T=gx072ceNDJ%V6}p zdj50m{ix`5e{=HX-AgB{D4x8s_!_4$N7kLyu5;ZOBUY>L@tCAj>c~2Wt9Yey-O1dZ z*=j3qiAdZ(&-frc_ax8bpAw#vvez=)IlhBCWqq1L;v|>rue7oj?b}i>%Aix);=`&o kYt_HoYdQ4v9W=Hfxf=J zuCA_%ii)+hwYs{xnVFf9kx_kpeRFejZEbB;Rh6curna_rLqkJxbhM3zhO)Bqe+K3& zj7(NmR<<@asi~aCeUuWaSja#>FwYRrlvu2H#mzS@vujqT7V?eoC zo-U3d5|XS34TG2id0Y;fPr8tDf2+)Sn-4?F4n+oo1CsKecnmfzRd9}piVih-pgcDsq{V&G`lGuWg0Gq%u>U1; z=;P^y2bU_m-l%o&-Qwe3^`bvACI{OIR9|$s{D$|#s_gY$Y}cOpY?(TTTVZC==T-ln eaXRp9$p8P|)ouB~zyCoY$KdJe=d#Wzp$Pz9_p zH8nFcGcYhPFE1}GEiEJ@Bs)7hCnqO1Ha0RcGJk)6gM)*8eSLa*dMPO>D=RC2fPiyb zTRbQzBO@dK00Yzk0y;W6u>$~0OG~e>uS+j1v9YnWwY5J#Kdh{*N=iyiO-)4qa$o=e z0Fg;VK~xwS1;Ig113?f3!OWgn){>Fn%K!hy(elw|)m=o0sG@K8Qn?F&fokGcf`K?- zULI#)wV?n?J`n%{@K@hv1{f19R>?|G7yzOsnys*IXjp$06H#HT+3_~Pcka#J>o z^SEk}{BB51s96CyHv>addQ5RaI?mZGC-xLqkJz zbMr=KhAWIr{~4I;LdE)lCii)|IEF}Ej_p6_c-TPXXr0I0mV{T=gx072ceNDJ%V6}p zdj50m{ix`5e{=HX-AgB{D4x8s_!_4$N7kLyu5;ZOBUY>L@tCAj>c~2Wt9Yey-O1XX z-D)duiAdZ(&-frc_ax8bpAw#vvez=)Iktl{Wqq1L;v|>rue7oj?b}i>%Aix);=`&o jYt_HoYdQ x.setValue(LeverBlock.POWERED, true) } + } + thenIdle(3) + thenExecute { context.assertBlockHas(lamp, RedstoneLampBlock.LIT, false, "Lamp should still not be lit") } + } + + /** + * Similar to the above, but with a repeater before the relay + * + * @see [Computer_Test.No_through_signal_reverse] + */ + @GameTest + fun No_through_signal_reverse(context: GameTestHelper) = context.sequence { + val lamp = BlockPos(2, 2, 4) + val lever = BlockPos(2, 2, 0) + thenExecute { + context.assertBlockHas(lamp, RedstoneLampBlock.LIT, false, "Lamp should not be lit") + context.modifyBlock(lever) { x -> x.setValue(LeverBlock.POWERED, true) } + } + thenIdle(3) + thenExecute { context.assertBlockHas(lamp, RedstoneLampBlock.LIT, false, "Lamp should still not be lit") } + } + + /** + * Check relays propagate redstone to surrounding blocks. + * + * @see [Computer_Test.Set_and_destroy] + */ + @GameTest + fun Set_and_destroy(context: GameTestHelper) = context.sequence { + val lamp = BlockPos(2, 2, 3) + + thenExecute { + val peripheral = context.getBlockEntity(BlockPos(2, 2, 2), ModRegistry.BlockEntities.REDSTONE_RELAY.get()) + .peripheral() + as RedstoneRelayPeripheral + peripheral.setOutput(ComputerSide.BACK, true) + } + thenIdle(1) + thenExecute { context.assertBlockHas(lamp, RedstoneLampBlock.LIT, true, "Lamp should be lit") } + thenExecute { context.setBlock(BlockPos(2, 2, 2), Blocks.AIR) } + thenIdle(4) + thenExecute { context.assertBlockHas(lamp, RedstoneLampBlock.LIT, false, "Lamp should not be lit") } + } + + /** + * Check relays pick up propagated redstone to surrounding blocks. + * + * @see [Computer_Test.Self_output_update] + */ + @GameTest + fun Self_output_update(context: GameTestHelper) = context.sequence { + fun relay() = context.getBlockEntity(BlockPos(2, 2, 2), ModRegistry.BlockEntities.REDSTONE_RELAY.get()) + .peripheral() as RedstoneRelayPeripheral + + thenExecute { relay().setOutput(ComputerSide.BACK, true) } + thenIdle(2) + thenExecute { assertEquals(true, relay().getInput(ComputerSide.BACK), "Input should be on") } + + thenIdle(2) + + thenExecute { relay().setOutput(ComputerSide.BACK, false) } + thenIdle(2) + thenExecute { assertEquals(false, relay().getInput(ComputerSide.BACK), "Input should be off") } + } +} diff --git a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/core/TestHooks.kt b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/core/TestHooks.kt index 149f947ce3..a97363f8e8 100644 --- a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/core/TestHooks.kt +++ b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/core/TestHooks.kt @@ -92,6 +92,7 @@ object TestHooks { Printer_Test::class.java, Printout_Test::class.java, Recipe_Test::class.java, + Relay_Test::class.java, Speaker_Test::class.java, Turtle_Test::class.java, ) diff --git a/projects/common/src/testMod/resources/data/cctest/structures/relay_test.no_through_signal.snbt b/projects/common/src/testMod/resources/data/cctest/structures/relay_test.no_through_signal.snbt new file mode 100644 index 0000000000..008775e567 --- /dev/null +++ b/projects/common/src/testMod/resources/data/cctest/structures/relay_test.no_through_signal.snbt @@ -0,0 +1,141 @@ +{ + DataVersion: 2730, + size: [5, 5, 5], + data: [ + {pos: [0, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [0, 1, 0], state: "minecraft:air"}, + {pos: [0, 1, 1], state: "minecraft:air"}, + {pos: [0, 1, 2], state: "minecraft:air"}, + {pos: [0, 1, 3], state: "minecraft:air"}, + {pos: [0, 1, 4], state: "minecraft:air"}, + {pos: [1, 1, 0], state: "minecraft:air"}, + {pos: [1, 1, 1], state: "minecraft:air"}, + {pos: [1, 1, 2], state: "minecraft:air"}, + {pos: [1, 1, 3], state: "minecraft:air"}, + {pos: [1, 1, 4], state: "minecraft:air"}, + {pos: [2, 1, 0], state: "minecraft:lever{face:floor,facing:south,powered:false}"}, + {pos: [2, 1, 1], state: "minecraft:repeater{delay:1,facing:north,locked:false,powered:false}"}, + {pos: [2, 1, 2], state: "computercraft:redstone_relay{facing:north}"}, + {pos: [2, 1, 3], state: "minecraft:redstone_wire{east:none,north:side,power:0,south:none,west:none}"}, + {pos: [2, 1, 4], state: "minecraft:redstone_lamp{lit:false}"}, + {pos: [3, 1, 0], state: "minecraft:air"}, + {pos: [3, 1, 1], state: "minecraft:air"}, + {pos: [3, 1, 2], state: "minecraft:air"}, + {pos: [3, 1, 3], state: "minecraft:air"}, + {pos: [3, 1, 4], state: "minecraft:air"}, + {pos: [4, 1, 0], state: "minecraft:air"}, + {pos: [4, 1, 1], state: "minecraft:air"}, + {pos: [4, 1, 2], state: "minecraft:air"}, + {pos: [4, 1, 3], state: "minecraft:air"}, + {pos: [4, 1, 4], state: "minecraft:air"}, + {pos: [0, 2, 0], state: "minecraft:air"}, + {pos: [0, 2, 1], state: "minecraft:air"}, + {pos: [0, 2, 2], state: "minecraft:air"}, + {pos: [0, 2, 3], state: "minecraft:air"}, + {pos: [0, 2, 4], state: "minecraft:air"}, + {pos: [1, 2, 0], state: "minecraft:air"}, + {pos: [1, 2, 1], state: "minecraft:air"}, + {pos: [1, 2, 2], state: "minecraft:air"}, + {pos: [1, 2, 3], state: "minecraft:air"}, + {pos: [1, 2, 4], state: "minecraft:air"}, + {pos: [2, 2, 0], state: "minecraft:air"}, + {pos: [2, 2, 1], state: "minecraft:air"}, + {pos: [2, 2, 2], state: "minecraft:air"}, + {pos: [2, 2, 3], state: "minecraft:air"}, + {pos: [2, 2, 4], state: "minecraft:air"}, + {pos: [3, 2, 0], state: "minecraft:air"}, + {pos: [3, 2, 1], state: "minecraft:air"}, + {pos: [3, 2, 2], state: "minecraft:air"}, + {pos: [3, 2, 3], state: "minecraft:air"}, + {pos: [3, 2, 4], state: "minecraft:air"}, + {pos: [4, 2, 0], state: "minecraft:air"}, + {pos: [4, 2, 1], state: "minecraft:air"}, + {pos: [4, 2, 2], state: "minecraft:air"}, + {pos: [4, 2, 3], state: "minecraft:air"}, + {pos: [4, 2, 4], state: "minecraft:air"}, + {pos: [0, 3, 0], state: "minecraft:air"}, + {pos: [0, 3, 1], state: "minecraft:air"}, + {pos: [0, 3, 2], state: "minecraft:air"}, + {pos: [0, 3, 3], state: "minecraft:air"}, + {pos: [0, 3, 4], state: "minecraft:air"}, + {pos: [1, 3, 0], state: "minecraft:air"}, + {pos: [1, 3, 1], state: "minecraft:air"}, + {pos: [1, 3, 2], state: "minecraft:air"}, + {pos: [1, 3, 3], state: "minecraft:air"}, + {pos: [1, 3, 4], state: "minecraft:air"}, + {pos: [2, 3, 0], state: "minecraft:air"}, + {pos: [2, 3, 1], state: "minecraft:air"}, + {pos: [2, 3, 2], state: "minecraft:air"}, + {pos: [2, 3, 3], state: "minecraft:air"}, + {pos: [2, 3, 4], state: "minecraft:air"}, + {pos: [3, 3, 0], state: "minecraft:air"}, + {pos: [3, 3, 1], state: "minecraft:air"}, + {pos: [3, 3, 2], state: "minecraft:air"}, + {pos: [3, 3, 3], state: "minecraft:air"}, + {pos: [3, 3, 4], state: "minecraft:air"}, + {pos: [4, 3, 0], state: "minecraft:air"}, + {pos: [4, 3, 1], state: "minecraft:air"}, + {pos: [4, 3, 2], state: "minecraft:air"}, + {pos: [4, 3, 3], state: "minecraft:air"}, + {pos: [4, 3, 4], state: "minecraft:air"}, + {pos: [0, 4, 0], state: "minecraft:air"}, + {pos: [0, 4, 1], state: "minecraft:air"}, + {pos: [0, 4, 2], state: "minecraft:air"}, + {pos: [0, 4, 3], state: "minecraft:air"}, + {pos: [0, 4, 4], state: "minecraft:air"}, + {pos: [1, 4, 0], state: "minecraft:air"}, + {pos: [1, 4, 1], state: "minecraft:air"}, + {pos: [1, 4, 2], state: "minecraft:air"}, + {pos: [1, 4, 3], state: "minecraft:air"}, + {pos: [1, 4, 4], state: "minecraft:air"}, + {pos: [2, 4, 0], state: "minecraft:air"}, + {pos: [2, 4, 1], state: "minecraft:air"}, + {pos: [2, 4, 2], state: "minecraft:air"}, + {pos: [2, 4, 3], state: "minecraft:air"}, + {pos: [2, 4, 4], state: "minecraft:air"}, + {pos: [3, 4, 0], state: "minecraft:air"}, + {pos: [3, 4, 1], state: "minecraft:air"}, + {pos: [3, 4, 2], state: "minecraft:air"}, + {pos: [3, 4, 3], state: "minecraft:air"}, + {pos: [3, 4, 4], state: "minecraft:air"}, + {pos: [4, 4, 0], state: "minecraft:air"}, + {pos: [4, 4, 1], state: "minecraft:air"}, + {pos: [4, 4, 2], state: "minecraft:air"}, + {pos: [4, 4, 3], state: "minecraft:air"}, + {pos: [4, 4, 4], state: "minecraft:air"} + ], + entities: [], + palette: [ + "minecraft:polished_andesite", + "minecraft:redstone_lamp{lit:false}", + "computercraft:redstone_relay{facing:north}", + "minecraft:air", + "minecraft:lever{face:floor,facing:south,powered:false}", + "minecraft:repeater{delay:1,facing:north,locked:false,powered:false}", + "minecraft:redstone_wire{east:none,north:side,power:0,south:none,west:none}" + ] +} diff --git a/projects/common/src/testMod/resources/data/cctest/structures/relay_test.no_through_signal_reverse.snbt b/projects/common/src/testMod/resources/data/cctest/structures/relay_test.no_through_signal_reverse.snbt new file mode 100644 index 0000000000..d49021b89f --- /dev/null +++ b/projects/common/src/testMod/resources/data/cctest/structures/relay_test.no_through_signal_reverse.snbt @@ -0,0 +1,141 @@ +{ + DataVersion: 3120, + size: [5, 5, 5], + data: [ + {pos: [0, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [0, 1, 0], state: "minecraft:air"}, + {pos: [0, 1, 1], state: "minecraft:air"}, + {pos: [0, 1, 2], state: "minecraft:air"}, + {pos: [0, 1, 3], state: "minecraft:air"}, + {pos: [0, 1, 4], state: "minecraft:air"}, + {pos: [1, 1, 0], state: "minecraft:air"}, + {pos: [1, 1, 1], state: "minecraft:air"}, + {pos: [1, 1, 2], state: "minecraft:air"}, + {pos: [1, 1, 3], state: "minecraft:air"}, + {pos: [1, 1, 4], state: "minecraft:air"}, + {pos: [2, 1, 0], state: "minecraft:lever{face:floor,facing:south,powered:false}"}, + {pos: [2, 1, 1], state: "minecraft:repeater{delay:1,facing:north,locked:false,powered:false}"}, + {pos: [2, 1, 2], state: "computercraft:redstone_relay{facing:north}"}, + {pos: [2, 1, 3], state: "minecraft:redstone_wire{east:none,north:side,power:0,south:side,west:none}"}, + {pos: [2, 1, 4], state: "minecraft:redstone_lamp{lit:false}"}, + {pos: [3, 1, 0], state: "minecraft:air"}, + {pos: [3, 1, 1], state: "minecraft:air"}, + {pos: [3, 1, 2], state: "minecraft:air"}, + {pos: [3, 1, 3], state: "minecraft:air"}, + {pos: [3, 1, 4], state: "minecraft:air"}, + {pos: [4, 1, 0], state: "minecraft:air"}, + {pos: [4, 1, 1], state: "minecraft:air"}, + {pos: [4, 1, 2], state: "minecraft:air"}, + {pos: [4, 1, 3], state: "minecraft:air"}, + {pos: [4, 1, 4], state: "minecraft:air"}, + {pos: [0, 2, 0], state: "minecraft:air"}, + {pos: [0, 2, 1], state: "minecraft:air"}, + {pos: [0, 2, 2], state: "minecraft:air"}, + {pos: [0, 2, 3], state: "minecraft:air"}, + {pos: [0, 2, 4], state: "minecraft:air"}, + {pos: [1, 2, 0], state: "minecraft:air"}, + {pos: [1, 2, 1], state: "minecraft:air"}, + {pos: [1, 2, 2], state: "minecraft:air"}, + {pos: [1, 2, 3], state: "minecraft:air"}, + {pos: [1, 2, 4], state: "minecraft:air"}, + {pos: [2, 2, 0], state: "minecraft:air"}, + {pos: [2, 2, 1], state: "minecraft:air"}, + {pos: [2, 2, 2], state: "minecraft:air"}, + {pos: [2, 2, 3], state: "minecraft:air"}, + {pos: [2, 2, 4], state: "minecraft:air"}, + {pos: [3, 2, 0], state: "minecraft:air"}, + {pos: [3, 2, 1], state: "minecraft:air"}, + {pos: [3, 2, 2], state: "minecraft:air"}, + {pos: [3, 2, 3], state: "minecraft:air"}, + {pos: [3, 2, 4], state: "minecraft:air"}, + {pos: [4, 2, 0], state: "minecraft:air"}, + {pos: [4, 2, 1], state: "minecraft:air"}, + {pos: [4, 2, 2], state: "minecraft:air"}, + {pos: [4, 2, 3], state: "minecraft:air"}, + {pos: [4, 2, 4], state: "minecraft:air"}, + {pos: [0, 3, 0], state: "minecraft:air"}, + {pos: [0, 3, 1], state: "minecraft:air"}, + {pos: [0, 3, 2], state: "minecraft:air"}, + {pos: [0, 3, 3], state: "minecraft:air"}, + {pos: [0, 3, 4], state: "minecraft:air"}, + {pos: [1, 3, 0], state: "minecraft:air"}, + {pos: [1, 3, 1], state: "minecraft:air"}, + {pos: [1, 3, 2], state: "minecraft:air"}, + {pos: [1, 3, 3], state: "minecraft:air"}, + {pos: [1, 3, 4], state: "minecraft:air"}, + {pos: [2, 3, 0], state: "minecraft:air"}, + {pos: [2, 3, 1], state: "minecraft:air"}, + {pos: [2, 3, 2], state: "minecraft:air"}, + {pos: [2, 3, 3], state: "minecraft:air"}, + {pos: [2, 3, 4], state: "minecraft:air"}, + {pos: [3, 3, 0], state: "minecraft:air"}, + {pos: [3, 3, 1], state: "minecraft:air"}, + {pos: [3, 3, 2], state: "minecraft:air"}, + {pos: [3, 3, 3], state: "minecraft:air"}, + {pos: [3, 3, 4], state: "minecraft:air"}, + {pos: [4, 3, 0], state: "minecraft:air"}, + {pos: [4, 3, 1], state: "minecraft:air"}, + {pos: [4, 3, 2], state: "minecraft:air"}, + {pos: [4, 3, 3], state: "minecraft:air"}, + {pos: [4, 3, 4], state: "minecraft:air"}, + {pos: [0, 4, 0], state: "minecraft:air"}, + {pos: [0, 4, 1], state: "minecraft:air"}, + {pos: [0, 4, 2], state: "minecraft:air"}, + {pos: [0, 4, 3], state: "minecraft:air"}, + {pos: [0, 4, 4], state: "minecraft:air"}, + {pos: [1, 4, 0], state: "minecraft:air"}, + {pos: [1, 4, 1], state: "minecraft:air"}, + {pos: [1, 4, 2], state: "minecraft:air"}, + {pos: [1, 4, 3], state: "minecraft:air"}, + {pos: [1, 4, 4], state: "minecraft:air"}, + {pos: [2, 4, 0], state: "minecraft:air"}, + {pos: [2, 4, 1], state: "minecraft:air"}, + {pos: [2, 4, 2], state: "minecraft:air"}, + {pos: [2, 4, 3], state: "minecraft:air"}, + {pos: [2, 4, 4], state: "minecraft:air"}, + {pos: [3, 4, 0], state: "minecraft:air"}, + {pos: [3, 4, 1], state: "minecraft:air"}, + {pos: [3, 4, 2], state: "minecraft:air"}, + {pos: [3, 4, 3], state: "minecraft:air"}, + {pos: [3, 4, 4], state: "minecraft:air"}, + {pos: [4, 4, 0], state: "minecraft:air"}, + {pos: [4, 4, 1], state: "minecraft:air"}, + {pos: [4, 4, 2], state: "minecraft:air"}, + {pos: [4, 4, 3], state: "minecraft:air"}, + {pos: [4, 4, 4], state: "minecraft:air"} + ], + entities: [], + palette: [ + "minecraft:polished_andesite", + "minecraft:redstone_lamp{lit:false}", + "minecraft:air", + "minecraft:lever{face:floor,facing:south,powered:false}", + "minecraft:repeater{delay:1,facing:north,locked:false,powered:false}", + "minecraft:redstone_wire{east:none,north:side,power:0,south:side,west:none}", + "computercraft:redstone_relay{facing:north}" + ] +} diff --git a/projects/common/src/testMod/resources/data/cctest/structures/relay_test.self_output_update.snbt b/projects/common/src/testMod/resources/data/cctest/structures/relay_test.self_output_update.snbt new file mode 100644 index 0000000000..c0aacd1f4b --- /dev/null +++ b/projects/common/src/testMod/resources/data/cctest/structures/relay_test.self_output_update.snbt @@ -0,0 +1,137 @@ +{ + DataVersion: 3120, + size: [5, 5, 5], + data: [ + {pos: [0, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [0, 1, 0], state: "minecraft:air"}, + {pos: [0, 1, 1], state: "minecraft:air"}, + {pos: [0, 1, 2], state: "minecraft:air"}, + {pos: [0, 1, 3], state: "minecraft:air"}, + {pos: [0, 1, 4], state: "minecraft:air"}, + {pos: [1, 1, 0], state: "minecraft:air"}, + {pos: [1, 1, 1], state: "minecraft:air"}, + {pos: [1, 1, 2], state: "minecraft:air"}, + {pos: [1, 1, 3], state: "minecraft:air"}, + {pos: [1, 1, 4], state: "minecraft:air"}, + {pos: [2, 1, 0], state: "minecraft:air"}, + {pos: [2, 1, 1], state: "minecraft:air"}, + {pos: [2, 1, 2], state: "computercraft:redstone_relay{facing:north}"}, + {pos: [2, 1, 3], state: "minecraft:polished_andesite"}, + {pos: [2, 1, 4], state: "minecraft:air"}, + {pos: [3, 1, 0], state: "minecraft:air"}, + {pos: [3, 1, 1], state: "minecraft:air"}, + {pos: [3, 1, 2], state: "minecraft:air"}, + {pos: [3, 1, 3], state: "minecraft:air"}, + {pos: [3, 1, 4], state: "minecraft:air"}, + {pos: [4, 1, 0], state: "minecraft:air"}, + {pos: [4, 1, 1], state: "minecraft:air"}, + {pos: [4, 1, 2], state: "minecraft:air"}, + {pos: [4, 1, 3], state: "minecraft:air"}, + {pos: [4, 1, 4], state: "minecraft:air"}, + {pos: [0, 2, 0], state: "minecraft:air"}, + {pos: [0, 2, 1], state: "minecraft:air"}, + {pos: [0, 2, 2], state: "minecraft:air"}, + {pos: [0, 2, 3], state: "minecraft:air"}, + {pos: [0, 2, 4], state: "minecraft:air"}, + {pos: [1, 2, 0], state: "minecraft:air"}, + {pos: [1, 2, 1], state: "minecraft:air"}, + {pos: [1, 2, 2], state: "minecraft:air"}, + {pos: [1, 2, 3], state: "minecraft:air"}, + {pos: [1, 2, 4], state: "minecraft:air"}, + {pos: [2, 2, 0], state: "minecraft:air"}, + {pos: [2, 2, 1], state: "minecraft:air"}, + {pos: [2, 2, 2], state: "minecraft:air"}, + {pos: [2, 2, 3], state: "minecraft:air"}, + {pos: [2, 2, 4], state: "minecraft:air"}, + {pos: [3, 2, 0], state: "minecraft:air"}, + {pos: [3, 2, 1], state: "minecraft:air"}, + {pos: [3, 2, 2], state: "minecraft:air"}, + {pos: [3, 2, 3], state: "minecraft:air"}, + {pos: [3, 2, 4], state: "minecraft:air"}, + {pos: [4, 2, 0], state: "minecraft:air"}, + {pos: [4, 2, 1], state: "minecraft:air"}, + {pos: [4, 2, 2], state: "minecraft:air"}, + {pos: [4, 2, 3], state: "minecraft:air"}, + {pos: [4, 2, 4], state: "minecraft:air"}, + {pos: [0, 3, 0], state: "minecraft:air"}, + {pos: [0, 3, 1], state: "minecraft:air"}, + {pos: [0, 3, 2], state: "minecraft:air"}, + {pos: [0, 3, 3], state: "minecraft:air"}, + {pos: [0, 3, 4], state: "minecraft:air"}, + {pos: [1, 3, 0], state: "minecraft:air"}, + {pos: [1, 3, 1], state: "minecraft:air"}, + {pos: [1, 3, 2], state: "minecraft:air"}, + {pos: [1, 3, 3], state: "minecraft:air"}, + {pos: [1, 3, 4], state: "minecraft:air"}, + {pos: [2, 3, 0], state: "minecraft:air"}, + {pos: [2, 3, 1], state: "minecraft:air"}, + {pos: [2, 3, 2], state: "minecraft:air"}, + {pos: [2, 3, 3], state: "minecraft:air"}, + {pos: [2, 3, 4], state: "minecraft:air"}, + {pos: [3, 3, 0], state: "minecraft:air"}, + {pos: [3, 3, 1], state: "minecraft:air"}, + {pos: [3, 3, 2], state: "minecraft:air"}, + {pos: [3, 3, 3], state: "minecraft:air"}, + {pos: [3, 3, 4], state: "minecraft:air"}, + {pos: [4, 3, 0], state: "minecraft:air"}, + {pos: [4, 3, 1], state: "minecraft:air"}, + {pos: [4, 3, 2], state: "minecraft:air"}, + {pos: [4, 3, 3], state: "minecraft:air"}, + {pos: [4, 3, 4], state: "minecraft:air"}, + {pos: [0, 4, 0], state: "minecraft:air"}, + {pos: [0, 4, 1], state: "minecraft:air"}, + {pos: [0, 4, 2], state: "minecraft:air"}, + {pos: [0, 4, 3], state: "minecraft:air"}, + {pos: [0, 4, 4], state: "minecraft:air"}, + {pos: [1, 4, 0], state: "minecraft:air"}, + {pos: [1, 4, 1], state: "minecraft:air"}, + {pos: [1, 4, 2], state: "minecraft:air"}, + {pos: [1, 4, 3], state: "minecraft:air"}, + {pos: [1, 4, 4], state: "minecraft:air"}, + {pos: [2, 4, 0], state: "minecraft:air"}, + {pos: [2, 4, 1], state: "minecraft:air"}, + {pos: [2, 4, 2], state: "minecraft:air"}, + {pos: [2, 4, 3], state: "minecraft:air"}, + {pos: [2, 4, 4], state: "minecraft:air"}, + {pos: [3, 4, 0], state: "minecraft:air"}, + {pos: [3, 4, 1], state: "minecraft:air"}, + {pos: [3, 4, 2], state: "minecraft:air"}, + {pos: [3, 4, 3], state: "minecraft:air"}, + {pos: [3, 4, 4], state: "minecraft:air"}, + {pos: [4, 4, 0], state: "minecraft:air"}, + {pos: [4, 4, 1], state: "minecraft:air"}, + {pos: [4, 4, 2], state: "minecraft:air"}, + {pos: [4, 4, 3], state: "minecraft:air"}, + {pos: [4, 4, 4], state: "minecraft:air"} + ], + entities: [], + palette: [ + "minecraft:polished_andesite", + "minecraft:air", + "computercraft:redstone_relay{facing:north}" + ] +} diff --git a/projects/common/src/testMod/resources/data/cctest/structures/relay_test.set_and_destroy.snbt b/projects/common/src/testMod/resources/data/cctest/structures/relay_test.set_and_destroy.snbt new file mode 100644 index 0000000000..2078950b02 --- /dev/null +++ b/projects/common/src/testMod/resources/data/cctest/structures/relay_test.set_and_destroy.snbt @@ -0,0 +1,138 @@ +{ + DataVersion: 3120, + size: [5, 5, 5], + data: [ + {pos: [0, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [0, 1, 0], state: "minecraft:air"}, + {pos: [0, 1, 1], state: "minecraft:air"}, + {pos: [0, 1, 2], state: "minecraft:air"}, + {pos: [0, 1, 3], state: "minecraft:air"}, + {pos: [0, 1, 4], state: "minecraft:air"}, + {pos: [1, 1, 0], state: "minecraft:air"}, + {pos: [1, 1, 1], state: "minecraft:air"}, + {pos: [1, 1, 2], state: "minecraft:air"}, + {pos: [1, 1, 3], state: "minecraft:air"}, + {pos: [1, 1, 4], state: "minecraft:air"}, + {pos: [2, 1, 0], state: "minecraft:air"}, + {pos: [2, 1, 1], state: "minecraft:air"}, + {pos: [2, 1, 2], state: "computercraft:redstone_relay{facing:north}"}, + {pos: [2, 1, 3], state: "minecraft:redstone_lamp{lit:false}"}, + {pos: [2, 1, 4], state: "minecraft:air"}, + {pos: [3, 1, 0], state: "minecraft:air"}, + {pos: [3, 1, 1], state: "minecraft:air"}, + {pos: [3, 1, 2], state: "minecraft:air"}, + {pos: [3, 1, 3], state: "minecraft:air"}, + {pos: [3, 1, 4], state: "minecraft:air"}, + {pos: [4, 1, 0], state: "minecraft:air"}, + {pos: [4, 1, 1], state: "minecraft:air"}, + {pos: [4, 1, 2], state: "minecraft:air"}, + {pos: [4, 1, 3], state: "minecraft:air"}, + {pos: [4, 1, 4], state: "minecraft:air"}, + {pos: [0, 2, 0], state: "minecraft:air"}, + {pos: [0, 2, 1], state: "minecraft:air"}, + {pos: [0, 2, 2], state: "minecraft:air"}, + {pos: [0, 2, 3], state: "minecraft:air"}, + {pos: [0, 2, 4], state: "minecraft:air"}, + {pos: [1, 2, 0], state: "minecraft:air"}, + {pos: [1, 2, 1], state: "minecraft:air"}, + {pos: [1, 2, 2], state: "minecraft:air"}, + {pos: [1, 2, 3], state: "minecraft:air"}, + {pos: [1, 2, 4], state: "minecraft:air"}, + {pos: [2, 2, 0], state: "minecraft:air"}, + {pos: [2, 2, 1], state: "minecraft:air"}, + {pos: [2, 2, 2], state: "minecraft:air"}, + {pos: [2, 2, 3], state: "minecraft:air"}, + {pos: [2, 2, 4], state: "minecraft:air"}, + {pos: [3, 2, 0], state: "minecraft:air"}, + {pos: [3, 2, 1], state: "minecraft:air"}, + {pos: [3, 2, 2], state: "minecraft:air"}, + {pos: [3, 2, 3], state: "minecraft:air"}, + {pos: [3, 2, 4], state: "minecraft:air"}, + {pos: [4, 2, 0], state: "minecraft:air"}, + {pos: [4, 2, 1], state: "minecraft:air"}, + {pos: [4, 2, 2], state: "minecraft:air"}, + {pos: [4, 2, 3], state: "minecraft:air"}, + {pos: [4, 2, 4], state: "minecraft:air"}, + {pos: [0, 3, 0], state: "minecraft:air"}, + {pos: [0, 3, 1], state: "minecraft:air"}, + {pos: [0, 3, 2], state: "minecraft:air"}, + {pos: [0, 3, 3], state: "minecraft:air"}, + {pos: [0, 3, 4], state: "minecraft:air"}, + {pos: [1, 3, 0], state: "minecraft:air"}, + {pos: [1, 3, 1], state: "minecraft:air"}, + {pos: [1, 3, 2], state: "minecraft:air"}, + {pos: [1, 3, 3], state: "minecraft:air"}, + {pos: [1, 3, 4], state: "minecraft:air"}, + {pos: [2, 3, 0], state: "minecraft:air"}, + {pos: [2, 3, 1], state: "minecraft:air"}, + {pos: [2, 3, 2], state: "minecraft:air"}, + {pos: [2, 3, 3], state: "minecraft:air"}, + {pos: [2, 3, 4], state: "minecraft:air"}, + {pos: [3, 3, 0], state: "minecraft:air"}, + {pos: [3, 3, 1], state: "minecraft:air"}, + {pos: [3, 3, 2], state: "minecraft:air"}, + {pos: [3, 3, 3], state: "minecraft:air"}, + {pos: [3, 3, 4], state: "minecraft:air"}, + {pos: [4, 3, 0], state: "minecraft:air"}, + {pos: [4, 3, 1], state: "minecraft:air"}, + {pos: [4, 3, 2], state: "minecraft:air"}, + {pos: [4, 3, 3], state: "minecraft:air"}, + {pos: [4, 3, 4], state: "minecraft:air"}, + {pos: [0, 4, 0], state: "minecraft:air"}, + {pos: [0, 4, 1], state: "minecraft:air"}, + {pos: [0, 4, 2], state: "minecraft:air"}, + {pos: [0, 4, 3], state: "minecraft:air"}, + {pos: [0, 4, 4], state: "minecraft:air"}, + {pos: [1, 4, 0], state: "minecraft:air"}, + {pos: [1, 4, 1], state: "minecraft:air"}, + {pos: [1, 4, 2], state: "minecraft:air"}, + {pos: [1, 4, 3], state: "minecraft:air"}, + {pos: [1, 4, 4], state: "minecraft:air"}, + {pos: [2, 4, 0], state: "minecraft:air"}, + {pos: [2, 4, 1], state: "minecraft:air"}, + {pos: [2, 4, 2], state: "minecraft:air"}, + {pos: [2, 4, 3], state: "minecraft:air"}, + {pos: [2, 4, 4], state: "minecraft:air"}, + {pos: [3, 4, 0], state: "minecraft:air"}, + {pos: [3, 4, 1], state: "minecraft:air"}, + {pos: [3, 4, 2], state: "minecraft:air"}, + {pos: [3, 4, 3], state: "minecraft:air"}, + {pos: [3, 4, 4], state: "minecraft:air"}, + {pos: [4, 4, 0], state: "minecraft:air"}, + {pos: [4, 4, 1], state: "minecraft:air"}, + {pos: [4, 4, 2], state: "minecraft:air"}, + {pos: [4, 4, 3], state: "minecraft:air"}, + {pos: [4, 4, 4], state: "minecraft:air"} + ], + entities: [], + palette: [ + "minecraft:polished_andesite", + "minecraft:redstone_lamp{lit:false}", + "minecraft:air", + "computercraft:redstone_relay{facing:north}" + ] +} diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/IAPIEnvironment.java b/projects/core/src/main/java/dan200/computercraft/core/apis/IAPIEnvironment.java index a8b3e9112d..046fc3ac95 100644 --- a/projects/core/src/main/java/dan200/computercraft/core/apis/IAPIEnvironment.java +++ b/projects/core/src/main/java/dan200/computercraft/core/apis/IAPIEnvironment.java @@ -43,18 +43,6 @@ interface IPeripheralChangeListener { void queueEvent(String event, @Nullable Object... args); - void setOutput(ComputerSide side, int output); - - int getOutput(ComputerSide side); - - int getInput(ComputerSide side); - - void setBundledOutput(ComputerSide side, int output); - - int getBundledOutput(ComputerSide side); - - int getBundledInput(ComputerSide side); - void setPeripheralChangeListener(@Nullable IPeripheralChangeListener listener); @Nullable diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/RedstoneAPI.java b/projects/core/src/main/java/dan200/computercraft/core/apis/RedstoneAPI.java index 66f52ad314..212afca300 100644 --- a/projects/core/src/main/java/dan200/computercraft/core/apis/RedstoneAPI.java +++ b/projects/core/src/main/java/dan200/computercraft/core/apis/RedstoneAPI.java @@ -5,9 +5,9 @@ package dan200.computercraft.core.apis; import dan200.computercraft.api.lua.ILuaAPI; -import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.core.computer.ComputerSide; +import dan200.computercraft.core.redstone.RedstoneAccess; import java.util.List; @@ -53,11 +53,9 @@ * the Minecraft wiki." * @cc.module redstone */ -public class RedstoneAPI implements ILuaAPI { - private final IAPIEnvironment environment; - - public RedstoneAPI(IAPIEnvironment environment) { - this.environment = environment; +public class RedstoneAPI extends RedstoneMethods implements ILuaAPI { + public RedstoneAPI(RedstoneAccess environment) { + super(environment); } @Override @@ -76,131 +74,4 @@ public String[] getNames() { public final List getSides() { return ComputerSide.NAMES; } - - /** - * Turn the redstone signal of a specific side on or off. - * - * @param side The side to set. - * @param on Whether the redstone signal should be on or off. When on, a signal strength of 15 is emitted. - */ - @LuaFunction - public final void setOutput(ComputerSide side, boolean on) { - environment.setOutput(side, on ? 15 : 0); - } - - /** - * Get the current redstone output of a specific side. - * - * @param side The side to get. - * @return Whether the redstone output is on or off. - * @see #setOutput - */ - @LuaFunction - public final boolean getOutput(ComputerSide side) { - return environment.getOutput(side) > 0; - } - - /** - * Get the current redstone input of a specific side. - * - * @param side The side to get. - * @return Whether the redstone input is on or off. - */ - @LuaFunction - public final boolean getInput(ComputerSide side) { - return environment.getInput(side) > 0; - } - - /** - * Set the redstone signal strength for a specific side. - * - * @param side The side to set. - * @param value The signal strength between 0 and 15. - * @throws LuaException If {@code value} is not between 0 and 15. - * @cc.since 1.51 - */ - @LuaFunction({ "setAnalogOutput", "setAnalogueOutput" }) - public final void setAnalogOutput(ComputerSide side, int value) throws LuaException { - if (value < 0 || value > 15) throw new LuaException("Expected number in range 0-15"); - environment.setOutput(side, value); - } - - /** - * Get the redstone output signal strength for a specific side. - * - * @param side The side to get. - * @return The output signal strength, between 0 and 15. - * @cc.since 1.51 - * @see #setAnalogOutput - */ - @LuaFunction({ "getAnalogOutput", "getAnalogueOutput" }) - public final int getAnalogOutput(ComputerSide side) { - return environment.getOutput(side); - } - - /** - * Get the redstone input signal strength for a specific side. - * - * @param side The side to get. - * @return The input signal strength, between 0 and 15. - * @cc.since 1.51 - */ - @LuaFunction({ "getAnalogInput", "getAnalogueInput" }) - public final int getAnalogInput(ComputerSide side) { - return environment.getInput(side); - } - - /** - * Set the bundled cable output for a specific side. - * - * @param side The side to set. - * @param output The colour bitmask to set. - * @cc.see colors.subtract For removing a colour from the bitmask. - * @cc.see colors.combine For adding a color to the bitmask. - */ - @LuaFunction - public final void setBundledOutput(ComputerSide side, int output) { - environment.setBundledOutput(side, output); - } - - /** - * Get the bundled cable output for a specific side. - * - * @param side The side to get. - * @return The bundle cable's output. - */ - @LuaFunction - public final int getBundledOutput(ComputerSide side) { - return environment.getBundledOutput(side); - } - - /** - * Get the bundled cable input for a specific side. - * - * @param side The side to get. - * @return The bundle cable's input. - * @see #testBundledInput To determine if a specific colour is set. - */ - @LuaFunction - public final int getBundledInput(ComputerSide side) { - return environment.getBundledInput(side); - } - - /** - * Determine if a specific combination of colours are on for the given side. - * - * @param side The side to test. - * @param mask The mask to test. - * @return If the colours are on. - * @cc.usage Check if [`colors.white`] and [`colors.black`] are on above the computer. - *
{@code
-     * print(redstone.testBundledInput("top", colors.combine(colors.white, colors.black)))
-     * }
- * @see #getBundledInput - */ - @LuaFunction - public final boolean testBundledInput(ComputerSide side, int mask) { - var input = environment.getBundledInput(side); - return (input & mask) == mask; - } } diff --git a/projects/core/src/main/java/dan200/computercraft/core/apis/RedstoneMethods.java b/projects/core/src/main/java/dan200/computercraft/core/apis/RedstoneMethods.java new file mode 100644 index 0000000000..cd029a3f9c --- /dev/null +++ b/projects/core/src/main/java/dan200/computercraft/core/apis/RedstoneMethods.java @@ -0,0 +1,147 @@ +// Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission. +// +// SPDX-License-Identifier: LicenseRef-CCPL +package dan200.computercraft.core.apis; + +import dan200.computercraft.api.lua.LuaException; +import dan200.computercraft.api.lua.LuaFunction; +import dan200.computercraft.core.computer.ComputerSide; +import dan200.computercraft.core.redstone.RedstoneAccess; + +/** + * A base class for all blocks with redstone integration. + */ +public class RedstoneMethods { + private final RedstoneAccess redstone; + + public RedstoneMethods(RedstoneAccess redstone) { + this.redstone = redstone; + } + + /** + * Turn the redstone signal of a specific side on or off. + * + * @param side The side to set. + * @param on Whether the redstone signal should be on or off. When on, a signal strength of 15 is emitted. + */ + @LuaFunction + public final void setOutput(ComputerSide side, boolean on) { + redstone.setOutput(side, on ? 15 : 0); + } + + /** + * Get the current redstone output of a specific side. + * + * @param side The side to get. + * @return Whether the redstone output is on or off. + * @see #setOutput + */ + @LuaFunction + public final boolean getOutput(ComputerSide side) { + return redstone.getOutput(side) > 0; + } + + /** + * Get the current redstone input of a specific side. + * + * @param side The side to get. + * @return Whether the redstone input is on or off. + */ + @LuaFunction + public final boolean getInput(ComputerSide side) { + return redstone.getInput(side) > 0; + } + + /** + * Set the redstone signal strength for a specific side. + * + * @param side The side to set. + * @param value The signal strength between 0 and 15. + * @throws LuaException If {@code value} is not between 0 and 15. + * @cc.since 1.51 + */ + @LuaFunction({ "setAnalogOutput", "setAnalogueOutput" }) + public final void setAnalogOutput(ComputerSide side, int value) throws LuaException { + if (value < 0 || value > 15) throw new LuaException("Expected number in range 0-15"); + redstone.setOutput(side, value); + } + + /** + * Get the redstone output signal strength for a specific side. + * + * @param side The side to get. + * @return The output signal strength, between 0 and 15. + * @cc.since 1.51 + * @see #setAnalogOutput + */ + @LuaFunction({ "getAnalogOutput", "getAnalogueOutput" }) + public final int getAnalogOutput(ComputerSide side) { + return redstone.getOutput(side); + } + + /** + * Get the redstone input signal strength for a specific side. + * + * @param side The side to get. + * @return The input signal strength, between 0 and 15. + * @cc.since 1.51 + */ + @LuaFunction({ "getAnalogInput", "getAnalogueInput" }) + public final int getAnalogInput(ComputerSide side) { + return redstone.getInput(side); + } + + /** + * Set the bundled cable output for a specific side. + * + * @param side The side to set. + * @param output The colour bitmask to set. + * @cc.see colors.subtract For removing a colour from the bitmask. + * @cc.see colors.combine For adding a color to the bitmask. + */ + @LuaFunction + public final void setBundledOutput(ComputerSide side, int output) { + redstone.setBundledOutput(side, output); + } + + /** + * Get the bundled cable output for a specific side. + * + * @param side The side to get. + * @return The bundle cable's output. + */ + @LuaFunction + public final int getBundledOutput(ComputerSide side) { + return redstone.getBundledOutput(side); + } + + /** + * Get the bundled cable input for a specific side. + * + * @param side The side to get. + * @return The bundle cable's input. + * @see #testBundledInput To determine if a specific colour is set. + */ + @LuaFunction + public final int getBundledInput(ComputerSide side) { + return redstone.getBundledInput(side); + } + + /** + * Determine if a specific combination of colours are on for the given side. + * + * @param side The side to test. + * @param mask The mask to test. + * @return If the colours are on. + * @cc.usage Check if [`colors.white`] and [`colors.black`] are on above this block. + *
{@code
+     * print(redstone.testBundledInput("top", colors.combine(colors.white, colors.black)))
+     * }
+ * @see #getBundledInput + */ + @LuaFunction + public final boolean testBundledInput(ComputerSide side, int mask) { + var input = redstone.getBundledInput(side); + return (input & mask) == mask; + } +} diff --git a/projects/core/src/main/java/dan200/computercraft/core/computer/Computer.java b/projects/core/src/main/java/dan200/computercraft/core/computer/Computer.java index 9b853bab6b..e3cb9f2e73 100644 --- a/projects/core/src/main/java/dan200/computercraft/core/computer/Computer.java +++ b/projects/core/src/main/java/dan200/computercraft/core/computer/Computer.java @@ -12,10 +12,10 @@ import dan200.computercraft.core.apis.IAPIEnvironment; import dan200.computercraft.core.computer.mainthread.MainThreadScheduler; import dan200.computercraft.core.filesystem.FileSystem; +import dan200.computercraft.core.redstone.RedstoneState; import dan200.computercraft.core.terminal.Terminal; import javax.annotation.Nullable; -import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; /** @@ -54,8 +54,7 @@ public class Computer { // Additional state about the computer and its environment. private final Environment internalEnvironment; - - private final AtomicInteger externalOutputChanges = new AtomicInteger(); + private final RedstoneState redstone = new RedstoneState(); private boolean startRequested; private int ticksSinceStart = -1; @@ -87,6 +86,10 @@ public Environment getEnvironment() { return internalEnvironment; } + public RedstoneState getRedstone() { + return redstone; + } + public IAPIEnvironment getAPIEnvironment() { return internalEnvironment; } @@ -157,10 +160,8 @@ public void tick() { executor.tick(); // Update the environment's internal state. + if (redstone.pollInputChanged()) queueEvent("redstone", null); internalEnvironment.tick(); - - // Propagate the environment's output to the world. - externalOutputChanges.accumulateAndGet(internalEnvironment.updateOutput(), (x, y) -> x | y); } /** @@ -168,8 +169,8 @@ public void tick() { * * @return What sides on the computer have changed. */ - public int pollAndResetChanges() { - return externalOutputChanges.getAndSet(0); + public int pollRedstoneChanges() { + return redstone.updateOutput(); } public boolean isBlinking() { diff --git a/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerExecutor.java b/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerExecutor.java index 4abed1117c..d9db834722 100644 --- a/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerExecutor.java +++ b/projects/core/src/main/java/dan200/computercraft/core/computer/ComputerExecutor.java @@ -153,11 +153,11 @@ final class ComputerExecutor implements ComputerScheduler.Worker { luaMethods = context.luaMethods(); executor = context.computerScheduler().createExecutor(this, metrics); - var environment = computer.getEnvironment(); + var environment = computer.getAPIEnvironment(); // Add all default APIs to the loaded list. addApi(new TermAPI(environment)); - addApi(new RedstoneAPI(environment)); + addApi(new RedstoneAPI(computer.getRedstone())); addApi(new FSAPI(environment)); addApi(new PeripheralAPI(environment, context.peripheralMethods())); addApi(new OSAPI(environment)); @@ -434,14 +434,13 @@ private void shutdown() throws InterruptedException { // Shutdown our APIs for (var api : apis) api.shutdown(); computer.getEnvironment().reset(); + computer.getRedstone().clearOutput(); // Unload filesystem if (fileSystem != null) { fileSystem.close(); fileSystem = null; } - - computer.getEnvironment().resetOutput(); } finally { isOnLock.unlock(); } diff --git a/projects/core/src/main/java/dan200/computercraft/core/computer/Environment.java b/projects/core/src/main/java/dan200/computercraft/core/computer/Environment.java index 15d38bfa1d..d1e10d5c45 100644 --- a/projects/core/src/main/java/dan200/computercraft/core/computer/Environment.java +++ b/projects/core/src/main/java/dan200/computercraft/core/computer/Environment.java @@ -16,24 +16,12 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import javax.annotation.Nullable; -import java.util.Arrays; import java.util.Iterator; /** * Represents the "environment" that a {@link Computer} exists in. *

- * This handles storing and updating of peripherals and redstone. - * - *

Redstone

- * We holds three kinds of arrays for redstone, in normal and bundled versions: - *
    - *
  • {@link #internalOutput} is the redstone output which the computer has currently set. This is read on both - * threads, and written on the computer thread.
  • - *
  • {@link #externalOutput} is the redstone output currently propagated to the world. This is only read and written - * on the main thread.
  • - *
  • {@link #input} is the redstone input from external sources. This is read on both threads, and written on the main - * thread.
  • - *
+ * This handles storing and updating of peripherals and timers. * *

Peripheral

* We also keep track of peripherals. These are read on both threads, and only written on the main thread. @@ -43,17 +31,6 @@ public final class Environment implements IAPIEnvironment { private final ComputerEnvironment environment; private final MetricsObserver metrics; - private boolean internalOutputChanged = false; - private final int[] internalOutput = new int[ComputerSide.COUNT]; - private final int[] internalBundledOutput = new int[ComputerSide.COUNT]; - - private final int[] externalOutput = new int[ComputerSide.COUNT]; - private final int[] externalBundledOutput = new int[ComputerSide.COUNT]; - - private boolean inputChanged = false; - private final int[] input = new int[ComputerSide.COUNT]; - private final int[] bundledInput = new int[ComputerSide.COUNT]; - private final IPeripheral[] peripherals = new IPeripheral[ComputerSide.COUNT]; private @Nullable IPeripheralChangeListener peripheralListener = null; @@ -111,76 +88,6 @@ public void queueEvent(String event, @Nullable Object... args) { computer.queueEvent(event, args); } - @Override - public int getInput(ComputerSide side) { - return input[side.ordinal()]; - } - - @Override - public int getBundledInput(ComputerSide side) { - return bundledInput[side.ordinal()]; - } - - @Override - public void setOutput(ComputerSide side, int output) { - var index = side.ordinal(); - synchronized (internalOutput) { - if (internalOutput[index] != output) { - internalOutput[index] = output; - internalOutputChanged = true; - } - } - } - - @Override - public int getOutput(ComputerSide side) { - synchronized (internalOutput) { - return computer.isOn() ? internalOutput[side.ordinal()] : 0; - } - } - - @Override - public void setBundledOutput(ComputerSide side, int output) { - var index = side.ordinal(); - synchronized (internalOutput) { - if (internalBundledOutput[index] != output) { - internalBundledOutput[index] = output; - internalOutputChanged = true; - } - } - } - - @Override - public int getBundledOutput(ComputerSide side) { - synchronized (internalOutput) { - return computer.isOn() ? internalBundledOutput[side.ordinal()] : 0; - } - } - - public int getExternalRedstoneOutput(ComputerSide side) { - return computer.isOn() ? externalOutput[side.ordinal()] : 0; - } - - public int getExternalBundledRedstoneOutput(ComputerSide side) { - return computer.isOn() ? externalBundledOutput[side.ordinal()] : 0; - } - - public void setRedstoneInput(ComputerSide side, int level) { - var index = side.ordinal(); - if (input[index] != level) { - input[index] = level; - inputChanged = true; - } - } - - public void setBundledRedstoneInput(ComputerSide side, int combination) { - var index = side.ordinal(); - if (bundledInput[index] != combination) { - bundledInput[index] = combination; - inputChanged = true; - } - } - /** * Called when the computer starts up or shuts down, to reset any internal state. * @@ -197,11 +104,6 @@ void reset() { * Called on the main thread to update the internal state of the computer. */ void tick() { - if (inputChanged) { - inputChanged = false; - queueEvent("redstone"); - } - synchronized (timers) { // Countdown all of our active timers Iterator> it = timers.int2ObjectEntrySet().iterator(); @@ -218,45 +120,6 @@ void tick() { } } - /** - * Called on the main thread to propagate the internal outputs to the external ones. - * - * @return If the outputs have changed. - */ - int updateOutput() { - // Mark output as changed if the internal redstone has changed - synchronized (internalOutput) { - if (!internalOutputChanged) return 0; - - var changed = 0; - - for (var i = 0; i < ComputerSide.COUNT; i++) { - if (externalOutput[i] != internalOutput[i]) { - externalOutput[i] = internalOutput[i]; - changed |= 1 << i; - } - - if (externalBundledOutput[i] != internalBundledOutput[i]) { - externalBundledOutput[i] = internalBundledOutput[i]; - changed |= 1 << i; - } - } - - internalOutputChanged = false; - - return changed; - } - } - - void resetOutput() { - // Reset redstone output - synchronized (internalOutput) { - Arrays.fill(internalOutput, 0); - Arrays.fill(internalBundledOutput, 0); - internalOutputChanged = true; - } - } - @Nullable @Override public IPeripheral getPeripheral(ComputerSide side) { diff --git a/projects/core/src/main/java/dan200/computercraft/core/redstone/RedstoneAccess.java b/projects/core/src/main/java/dan200/computercraft/core/redstone/RedstoneAccess.java new file mode 100644 index 0000000000..524983e682 --- /dev/null +++ b/projects/core/src/main/java/dan200/computercraft/core/redstone/RedstoneAccess.java @@ -0,0 +1,63 @@ +// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 +package dan200.computercraft.core.redstone; + +import dan200.computercraft.core.apis.RedstoneMethods; +import dan200.computercraft.core.computer.ComputerSide; + +/** + * Common interface between blocks which provide and consume a redstone signal. + * + * @see RedstoneMethods Lua-facing methods wrapping this interface. + * @see RedstoneState A concrete implementation of this class. + */ +public interface RedstoneAccess { + /** + * Set the redstone output on a given side. + * + * @param side The side to set. + * @param output The output level, between 0 and 15. + */ + void setOutput(ComputerSide side, int output); + + /** + * Get the redstone output on a given side. + * + * @param side The side to get. + * @return The output level, between 0 and 15. + */ + int getOutput(ComputerSide side); + + /** + * Get the redstone input on a given side. + * + * @param side The side to get. + * @return The input level, between 0 and 15. + */ + int getInput(ComputerSide side); + + /** + * Set the bundled redstone output on a given side. + * + * @param side The side to set. + * @param output The output state, as a 16-bit bitmask. + */ + void setBundledOutput(ComputerSide side, int output); + + /** + * Get the bundled redstone output on a given side. + * + * @param side The side to get. + * @return The output state, as a 16-bit bitmask. + */ + int getBundledOutput(ComputerSide side); + + /** + * Set the bundled redstone input on a given side. + * + * @param side The side to get. + * @return The input state, as a 16-bit bitmask. + */ + int getBundledInput(ComputerSide side); +} diff --git a/projects/core/src/main/java/dan200/computercraft/core/redstone/RedstoneState.java b/projects/core/src/main/java/dan200/computercraft/core/redstone/RedstoneState.java new file mode 100644 index 0000000000..e2a6f0d9f8 --- /dev/null +++ b/projects/core/src/main/java/dan200/computercraft/core/redstone/RedstoneState.java @@ -0,0 +1,248 @@ +// Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission. +// +// SPDX-License-Identifier: LicenseRef-CCPL +package dan200.computercraft.core.redstone; + +import dan200.computercraft.core.computer.ComputerSide; + +import javax.annotation.Nullable; +import javax.annotation.concurrent.GuardedBy; +import java.util.Arrays; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Manages the state of redstone inputs and ouputs on a computer (or other redstone emitting block). + *

+ * As computers execute on a separate thread to the main Minecraft world, computers cannot immediately read or write + * redstone values. Instead, we maintain a copy of the block's redstone inputs and outputs, and sync that with the + * Minecraft world when needed. + * + *

Input

+ * Redstone inputs should be propagated immediately to the internal state of the computer. Computers (and other redstone + * blocks) listen for block updates, fetch their neighbour's redstone state, and then call + * {@link #setInput(ComputerSide, int, int)}. + *

+ * However, we do not want to immediately schedule a {@code "redstone"} event, as otherwise we could schedule many + * events in a single tick. Instead, the next time the block is ticked, the consumer should call + * {@link #pollInputChanged()} and queue an event if needed. + * + *

Output

+ * In order to reduce block updates, we maintain a separate "internal" and "external" output state. Whenever a computer + * sets a redstone output, the "internal" state is updated, and a dirty flag is set. When the computer is ticked, + * {@link #updateOutput()} should be called, to copy the internal state to the external state. This returns a bitmask + * indicating which sides have changed. The external outputs may then be read with {@link #getExternalOutput(ComputerSide)} + * and {@link #getExternalBundledOutput(ComputerSide)}. + */ +public final class RedstoneState implements RedstoneAccess { + private final @Nullable Runnable onOutputChanged; + + private final ReentrantLock outputLock = new ReentrantLock(); + private @GuardedBy("outputLock") boolean internalOutputChanged = false; + private final @GuardedBy("outputLock") int[] internalOutput = new int[ComputerSide.COUNT]; + private final @GuardedBy("outputLock") int[] internalBundledOutput = new int[ComputerSide.COUNT]; + + private final int[] externalOutput = new int[ComputerSide.COUNT]; + private final int[] externalBundledOutput = new int[ComputerSide.COUNT]; + + private final ReentrantLock inputLock = new ReentrantLock(); + private boolean inputChanged = false; + private final @GuardedBy("inputLock") int[] input = new int[ComputerSide.COUNT]; + private final @GuardedBy("inputLock") int[] bundledInput = new int[ComputerSide.COUNT]; + + public RedstoneState() { + this(null); + } + + /** + * Construct a new {@link RedstoneState}, with a callback function to invoke when the internal output has + * changed. This function is called from the computer thread. + * + * @param outputChanged The function to invoke when output has changed. + */ + public RedstoneState(@Nullable Runnable outputChanged) { + this.onOutputChanged = outputChanged; + } + + @Override + public int getInput(ComputerSide side) { + inputLock.lock(); + try { + return input[side.ordinal()]; + } finally { + inputLock.unlock(); + } + } + + @Override + public int getBundledInput(ComputerSide side) { + inputLock.lock(); + try { + return bundledInput[side.ordinal()]; + } finally { + inputLock.unlock(); + } + } + + @Override + public void setOutput(ComputerSide side, int output) { + var index = side.ordinal(); + + outputLock.lock(); + try { + if (internalOutput[index] == output) return; + internalOutput[index] = output; + setOutputChanged(); + } finally { + outputLock.unlock(); + } + } + + @Override + public int getOutput(ComputerSide side) { + outputLock.lock(); + try { + return internalOutput[side.ordinal()]; + } finally { + outputLock.unlock(); + } + } + + @Override + public void setBundledOutput(ComputerSide side, int output) { + var index = side.ordinal(); + outputLock.lock(); + try { + if (internalBundledOutput[index] == output) return; + internalBundledOutput[index] = output; + setOutputChanged(); + } finally { + outputLock.unlock(); + } + } + + @Override + public int getBundledOutput(ComputerSide side) { + outputLock.lock(); + try { + return internalBundledOutput[side.ordinal()]; + } finally { + outputLock.unlock(); + } + } + + @GuardedBy("outputLock") + private void setOutputChanged() { + if (internalOutputChanged) return; + internalOutputChanged = true; + if (onOutputChanged != null) onOutputChanged.run(); + } + + /** + * Propagate redstone changes from the computer to the outside world. The effective outputs can be acquired with + * {@link #getExternalOutput(ComputerSide)} and {@link #getExternalBundledOutput(ComputerSide)}. + * + * @return A bitmask indicating which sides have changed (indexed via {@link ComputerSide#ordinal()}). + */ + public int updateOutput() { + outputLock.lock(); + try { + if (!internalOutputChanged) return 0; + + var changed = 0; + + for (var i = 0; i < ComputerSide.COUNT; i++) { + if (externalOutput[i] != internalOutput[i]) { + externalOutput[i] = internalOutput[i]; + changed |= 1 << i; + } + + if (externalBundledOutput[i] != internalBundledOutput[i]) { + externalBundledOutput[i] = internalBundledOutput[i]; + changed |= 1 << i; + } + } + + internalOutputChanged = false; + + return changed; + } finally { + outputLock.unlock(); + } + } + + /** + * Get the redstone output for a given side. + * + * @param side The side to get. + * @return The effective redstone output. + */ + public int getExternalOutput(ComputerSide side) { + return externalOutput[side.ordinal()]; + } + + /** + * Get the bundled redstone output for a given side. + * + * @param side The side to get. + * @return The effective bundled redstone output. + */ + public int getExternalBundledOutput(ComputerSide side) { + return externalBundledOutput[side.ordinal()]; + } + + /** + * Reset any redstone output set by the computer. + */ + public void clearOutput() { + outputLock.lock(); + try { + Arrays.fill(internalOutput, 0); + Arrays.fill(internalBundledOutput, 0); + internalOutputChanged = true; + } finally { + outputLock.unlock(); + } + } + + /** + * Set the redstone input for a given side. + * + * @param side The side to update. + * @param level The redstone level. + * @param bundledState The bundled redstone state. + * @return Whether the input has changed. + */ + public boolean setInput(ComputerSide side, int level, int bundledState) { + var index = side.ordinal(); + inputLock.lock(); + try { + var changed = false; + if (input[index] != level) { + input[index] = level; + changed = true; + } + + if (bundledInput[index] != bundledState) { + bundledInput[index] = bundledState; + changed = true; + } + + inputChanged |= changed; + return changed; + } finally { + inputLock.unlock(); + } + } + + /** + * Check whether any redstone inputs set by {@link #setInput(ComputerSide, int, int)} have changed since the last + * call to this function. + * + * @return Whether any redstone inputs has changed. + */ + public boolean pollInputChanged() { + var changed = inputChanged; + inputChanged = false; + return changed; + } +} diff --git a/projects/core/src/testFixtures/java/dan200/computercraft/test/core/apis/BasicApiEnvironment.java b/projects/core/src/testFixtures/java/dan200/computercraft/test/core/apis/BasicApiEnvironment.java index 9e9b76388a..dd75d2a32f 100644 --- a/projects/core/src/testFixtures/java/dan200/computercraft/test/core/apis/BasicApiEnvironment.java +++ b/projects/core/src/testFixtures/java/dan200/computercraft/test/core/apis/BasicApiEnvironment.java @@ -63,34 +63,6 @@ public void shutdown() { public void reboot() { } - @Override - public void setOutput(ComputerSide side, int output) { - } - - @Override - public int getOutput(ComputerSide side) { - return 0; - } - - @Override - public int getInput(ComputerSide side) { - return 0; - } - - @Override - public void setBundledOutput(ComputerSide side, int output) { - } - - @Override - public int getBundledOutput(ComputerSide side) { - return 0; - } - - @Override - public int getBundledInput(ComputerSide side) { - return 0; - } - @Override public void setPeripheralChangeListener(@Nullable IPeripheralChangeListener listener) { } diff --git a/projects/fabric/src/generated/resources/data/computercraft/recipes/redstone_relay.json b/projects/fabric/src/generated/resources/data/computercraft/recipes/redstone_relay.json new file mode 100644 index 0000000000..b3fbd01c1c --- /dev/null +++ b/projects/fabric/src/generated/resources/data/computercraft/recipes/redstone_relay.json @@ -0,0 +1,12 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "redstone", + "key": { + "C": {"item": "computercraft:wired_modem"}, + "R": {"tag": "c:redstone_dusts"}, + "S": {"item": "minecraft:stone"} + }, + "pattern": ["SRS", "RCR", "SRS"], + "result": {"item": "computercraft:redstone_relay"}, + "show_notification": true +} diff --git a/projects/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json b/projects/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json new file mode 100644 index 0000000000..1e95e19adc --- /dev/null +++ b/projects/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json @@ -0,0 +1 @@ +{"replace": false, "values": ["computercraft:lectern"]} diff --git a/projects/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json b/projects/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json index 832d212710..ab90f21ff3 100644 --- a/projects/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json +++ b/projects/fabric/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json @@ -13,6 +13,7 @@ "computercraft:wireless_modem_normal", "computercraft:wireless_modem_advanced", "computercraft:wired_modem_full", - "computercraft:cable" + "computercraft:cable", + "computercraft:redstone_relay" ] } diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java b/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java index b77d74388e..0980ac3ab5 100644 --- a/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java +++ b/projects/fabric/src/main/java/dan200/computercraft/shared/ComputerCraft.java @@ -79,6 +79,7 @@ public static void init() { PeripheralLookup.get().registerForBlockEntity(WirelessModemBlockEntity::getPeripheral, ModRegistry.BlockEntities.WIRELESS_MODEM_ADVANCED.get()); PeripheralLookup.get().registerForBlockEntity(WiredModemFullBlockEntity::getPeripheral, ModRegistry.BlockEntities.WIRED_MODEM_FULL.get()); PeripheralLookup.get().registerForBlockEntity(CableBlockEntity::getPeripheral, ModRegistry.BlockEntities.CABLE.get()); + PeripheralLookup.get().registerForBlockEntity((b, d) -> b.peripheral(), ModRegistry.BlockEntities.REDSTONE_RELAY.get()); WiredElementLookup.get().registerForBlockEntity((b, d) -> b.getElement(), ModRegistry.BlockEntities.WIRED_MODEM_FULL.get()); WiredElementLookup.get().registerForBlockEntity(CableBlockEntity::getWiredElement, ModRegistry.BlockEntities.CABLE.get()); diff --git a/projects/forge/src/generated/resources/data/computercraft/recipes/redstone_relay.json b/projects/forge/src/generated/resources/data/computercraft/recipes/redstone_relay.json new file mode 100644 index 0000000000..df1c72b60d --- /dev/null +++ b/projects/forge/src/generated/resources/data/computercraft/recipes/redstone_relay.json @@ -0,0 +1,12 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "redstone", + "key": { + "C": {"item": "computercraft:wired_modem"}, + "R": {"tag": "forge:dusts/redstone"}, + "S": {"item": "minecraft:stone"} + }, + "pattern": ["SRS", "RCR", "SRS"], + "result": {"item": "computercraft:redstone_relay"}, + "show_notification": true +} diff --git a/projects/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json b/projects/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json new file mode 100644 index 0000000000..6e36891c88 --- /dev/null +++ b/projects/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json @@ -0,0 +1 @@ +{"values": ["computercraft:lectern"]} diff --git a/projects/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json b/projects/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json index e5a4c9d201..7e4df4d4c5 100644 --- a/projects/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json +++ b/projects/forge/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json @@ -12,6 +12,7 @@ "computercraft:wireless_modem_normal", "computercraft:wireless_modem_advanced", "computercraft:wired_modem_full", - "computercraft:cable" + "computercraft:cable", + "computercraft:redstone_relay" ] } diff --git a/projects/forge/src/main/java/dan200/computercraft/shared/ForgeCommonHooks.java b/projects/forge/src/main/java/dan200/computercraft/shared/ForgeCommonHooks.java index eb03e9e6da..5c74b32b2f 100644 --- a/projects/forge/src/main/java/dan200/computercraft/shared/ForgeCommonHooks.java +++ b/projects/forge/src/main/java/dan200/computercraft/shared/ForgeCommonHooks.java @@ -18,6 +18,7 @@ import dan200.computercraft.shared.peripheral.modem.wireless.WirelessModemBlockEntity; import dan200.computercraft.shared.peripheral.monitor.MonitorBlockEntity; import dan200.computercraft.shared.peripheral.printer.PrinterBlockEntity; +import dan200.computercraft.shared.peripheral.redstone.RedstoneRelayBlockEntity; import dan200.computercraft.shared.peripheral.speaker.SpeakerBlockEntity; import dan200.computercraft.shared.turtle.blocks.TurtleBlockEntity; import dan200.computercraft.shared.util.CapabilityProvider; @@ -43,6 +44,7 @@ import net.minecraftforge.items.wrapper.SidedInvWrapper; import static dan200.computercraft.shared.Capabilities.CAPABILITY_PERIPHERAL; +import static dan200.computercraft.shared.Capabilities.CAPABILITY_WIRED_ELEMENT; import static net.minecraftforge.common.capabilities.ForgeCapabilities.ITEM_HANDLER; /** @@ -133,15 +135,15 @@ public static void onCapability(AttachCapabilitiesEvent event) { CapabilityProvider.attach(event, INVENTORY, ITEM_HANDLER, () -> new InvWrapper(diskDrive)); CapabilityProvider.attach(event, PERIPHERAL, CAPABILITY_PERIPHERAL, diskDrive::peripheral); } else if (blockEntity instanceof CableBlockEntity cable) { - var peripheralHandler = SidedCapabilityProvider.attach(event, PERIPHERAL, Capabilities.CAPABILITY_PERIPHERAL, cable::getPeripheral); - var elementHandler = SidedCapabilityProvider.attach(event, WIRED_ELEMENT, Capabilities.CAPABILITY_WIRED_ELEMENT, cable::getWiredElement); + var peripheralHandler = SidedCapabilityProvider.attach(event, PERIPHERAL, CAPABILITY_PERIPHERAL, cable::getPeripheral); + var elementHandler = SidedCapabilityProvider.attach(event, WIRED_ELEMENT, CAPABILITY_WIRED_ELEMENT, cable::getWiredElement); cable.onModemChanged(() -> { peripheralHandler.invalidate(); elementHandler.invalidate(); }); } else if (blockEntity instanceof WiredModemFullBlockEntity modem) { - SidedCapabilityProvider.attach(event, PERIPHERAL, Capabilities.CAPABILITY_PERIPHERAL, modem::getPeripheral); - CapabilityProvider.attach(event, WIRED_ELEMENT, Capabilities.CAPABILITY_WIRED_ELEMENT, modem::getElement); + SidedCapabilityProvider.attach(event, PERIPHERAL, CAPABILITY_PERIPHERAL, modem::getPeripheral); + CapabilityProvider.attach(event, WIRED_ELEMENT, CAPABILITY_WIRED_ELEMENT, modem::getElement); } else if (blockEntity instanceof WirelessModemBlockEntity modem) { var peripheral = SidedCapabilityProvider.attach(event, PERIPHERAL, CAPABILITY_PERIPHERAL, modem::getPeripheral); modem.onModemChanged(peripheral::invalidate); @@ -150,12 +152,14 @@ public static void onCapability(AttachCapabilitiesEvent event) { } else if (blockEntity instanceof SpeakerBlockEntity speaker) { CapabilityProvider.attach(event, PERIPHERAL, CAPABILITY_PERIPHERAL, speaker::peripheral); } else if (blockEntity instanceof PrinterBlockEntity printer) { - CapabilityProvider.attach(event, PERIPHERAL, Capabilities.CAPABILITY_PERIPHERAL, printer::peripheral); + CapabilityProvider.attach(event, PERIPHERAL, CAPABILITY_PERIPHERAL, printer::peripheral); // We don't need to invalidate here as the block's can't be rotated on the X axis! SidedCapabilityProvider.attach( event, INVENTORY, ITEM_HANDLER, s -> s == null ? new InvWrapper(printer) : new SidedInvWrapper(printer, s) ); + } else if (blockEntity instanceof RedstoneRelayBlockEntity redstone) { + CapabilityProvider.attach(event, PERIPHERAL, CAPABILITY_PERIPHERAL, redstone::peripheral); } else if (Config.enableCommandBlock && blockEntity instanceof CommandBlockEntity commandBlock) { CapabilityProvider.attach(event, PERIPHERAL, CAPABILITY_PERIPHERAL, () -> new CommandBlockPeripheral(commandBlock)); } diff --git a/projects/web/src/htmlTransform/export/index.json b/projects/web/src/htmlTransform/export/index.json index 90794b5d78..b44d6e582b 100644 --- a/projects/web/src/htmlTransform/export/index.json +++ b/projects/web/src/htmlTransform/export/index.json @@ -14,6 +14,7 @@ "computercraft:printed_page": "Printed Page", "computercraft:printed_pages": "Printed Pages", "computercraft:printer": "Printer", + "computercraft:redstone_relay": "Redstone Relay", "computercraft:speaker": "Speaker", "computercraft:treasure_disk": "Floppy Disk", "computercraft:turtle_advanced": "Advanced Turtle", @@ -48,6 +49,7 @@ "minecraft:purple_dye": "Purple Dye", "minecraft:red_dye": "Red Dye", "minecraft:redstone": "Redstone Dust", + "minecraft:stick": "Stick", "minecraft:stone": "Stone", "minecraft:string": "String", "minecraft:white_dye": "White Dye", @@ -90,7 +92,7 @@ ["minecraft:gold_ingot"], ["minecraft:gold_ingot"], ["minecraft:gold_ingot"], - ["computercraft:computer_advanced"], + ["computercraft:computer_normal"], ["minecraft:gold_ingot"], ["minecraft:gold_ingot"], null, @@ -281,6 +283,21 @@ "output": "computercraft:printer", "count": 1 }, + "computercraft:redstone_relay": { + "inputs": [ + ["minecraft:stone"], + ["minecraft:redstone"], + ["minecraft:stone"], + ["minecraft:redstone"], + ["computercraft:wired_modem"], + ["minecraft:redstone"], + ["minecraft:stone"], + ["minecraft:redstone"], + ["minecraft:stone"] + ], + "output": "computercraft:redstone_relay", + "count": 1 + }, "computercraft:speaker": { "inputs": [ ["minecraft:stone"], @@ -311,13 +328,43 @@ "output": "computercraft:turtle_advanced", "count": 1 }, + "computercraft:turtle_advanced_overlays/turtle_rainbow_overlay": { + "inputs": [ + ["minecraft:red_dye"], + ["minecraft:orange_dye"], + ["minecraft:yellow_dye"], + ["minecraft:green_dye"], + ["minecraft:blue_dye"], + ["minecraft:purple_dye"], + ["minecraft:stick"], + ["computercraft:turtle_advanced"], + null + ], + "output": "computercraft:turtle_advanced", + "count": 1 + }, + "computercraft:turtle_advanced_overlays/turtle_trans_overlay": { + "inputs": [ + ["minecraft:light_blue_dye"], + ["minecraft:pink_dye"], + ["minecraft:white_dye"], + ["minecraft:stick"], + ["computercraft:turtle_advanced"], + null, + null, + null, + null + ], + "output": "computercraft:turtle_advanced", + "count": 1 + }, "computercraft:turtle_advanced_upgrade": { "inputs": [ ["minecraft:gold_ingot"], ["minecraft:gold_ingot"], ["minecraft:gold_ingot"], ["minecraft:gold_ingot"], - ["computercraft:computer_advanced"], + ["computercraft:turtle_normal"], ["minecraft:gold_ingot"], null, ["minecraft:gold_block"], @@ -341,6 +388,36 @@ "output": "computercraft:turtle_normal", "count": 1 }, + "computercraft:turtle_normal_overlays/turtle_rainbow_overlay": { + "inputs": [ + ["minecraft:red_dye"], + ["minecraft:orange_dye"], + ["minecraft:yellow_dye"], + ["minecraft:green_dye"], + ["minecraft:blue_dye"], + ["minecraft:purple_dye"], + ["minecraft:stick"], + ["computercraft:turtle_normal"], + null + ], + "output": "computercraft:turtle_normal", + "count": 1 + }, + "computercraft:turtle_normal_overlays/turtle_trans_overlay": { + "inputs": [ + ["minecraft:light_blue_dye"], + ["minecraft:pink_dye"], + ["minecraft:white_dye"], + ["minecraft:stick"], + ["computercraft:turtle_normal"], + null, + null, + null, + null + ], + "output": "computercraft:turtle_normal", + "count": 1 + }, "computercraft:wired_modem": { "inputs": [ ["minecraft:stone"], @@ -397,4 +474,4 @@ "count": 1 } } -} +} \ No newline at end of file diff --git a/projects/web/src/htmlTransform/export/items/computercraft/redstone_relay.png b/projects/web/src/htmlTransform/export/items/computercraft/redstone_relay.png new file mode 100644 index 0000000000000000000000000000000000000000..fd4e6e7963b44f2c86b97f3319cb01b9532295ed GIT binary patch literal 1625 zcmXw33s93+7QTP}Bs`Qn2#FyRAcO!vf)EG~69kf&K+rUXfED8Egs=r17YG<1Si!^~ zudEh|x>!UKsfeypTLrPWZ4ipmStMA-qE#9m0?(R+^kvu#+ z$Ye5wLRqtB4V6HkQmLMvo-`VbPN#c$d3lqF-rn9mK0XWv!`IiB$z=NZ`LS3me}De~ z8Z96oATTfxL6Eg;*M@|ItYfi4Lqo&D!r0z)Hk%zD9v%@9!QpTsBO{}tqGDoVxLhue z$BRV}kw_#KixVM`n3yP$NH&EAZ{qP}GMQX1Pf1BpC=_V`N=r-o1VH)u`5KL;5CsYg z3yYLWtyWuHTzu%zp^}o4($Z4BUSA18%>eZk42B@o3V=Vo>qEBx6VfVVsenH`-xWMG+L@meU3jgJ==!) zvt0l%?5wL8adZ>1BZ0|%@A=_vF-&5YR$VBt%V+>BB~J$AUwl3HdEAEqyesR9gm2dl zj@s?^6FV7K9q)WKq1efh+Hf7t*#rqTVL#4cwnS}U$${zX&tS*w@O5(tL(b0{UuUn) z2bRzJk6pBu^CPSjq9m(n^QXWWyu7@}D9&YXeKYjQ7y6JB3ugxl0NV1=z`I?Dxtm$K zzx#B7ugG`o{4+0xF7I$L192{D&3de@EO0>vP8dsm9f6?)>sKTM)t_`Pzvk9*>@fr_ zKJPbc?mlXqIvgEwsglui`R&^+@qesa|J&0BG}A-bm$~)UPJ$-Sb;CIbKK3ehF$uzG zN5_sSeQl3K>WXA@IKe1&6_{ULdh;WuU1(|lr8I@M8$W3ZC$KS0x5x#<#-39*g0+i2 z+ZP&_AL*}@>!SrRXzPKX=iB~fHW@B1jc#t5F8BL6kmk>lTQ;wJ{1|J3DNo?Am9gi) z+mu<1aOaefiSe$zFVnwtLI34pJYKtDV)msAzN%cn;EqpDsQ;j}L_SvuEGP4tk=+OO zP5o%WVfB-73mF|W5_f&Nbu73{J(L&LWvi-)44ES0G>6%!s9X}yLV9acTw3xY@oHe34>NsM;7{;nr<4zR_W1< z8UAfF`qWY6uSHJz;n=mUYT5NZo|a8;Ma<{{02f8bkCeNx07$#wT79iba;_5m9hxzD zwx|NkTBDM;x15hr-LzPUHM$3_>hF@=4(0^S2*|b`A^D$VMrO0wHR)DDFZH*3OT_^h zXnKjQGyTf^Mgv;8agP2%lTKarF9QoToit0orp%mhG8xV&w?naSJ<_$t25w&~&3O4;!?P36A*Gwj;>8kOu|j_mT4+QtVpR}1eBBnC($JYg;WTv^aF&R*k# zvG{Q;=FT>~OU>0sJ>S&ymvNsZPo3XcLC5%ATCa$mH4(Sa(8vD_! z4LZ=K_@$;UzxM8~Z8yDsC`*X05xgJ<6TmiO9+32to<>V2SuS1cFSLh_NKdFPOpM*^M+H$I{cqF~s9|a)JaaOT(l|3mzQM3J5AHl#F0)KFE6P7|WN- u5eG9QdfGt5G!G614UYve%bS}R*%&U>YZk`%JW&A}!r literal 0 HcmV?d00001 diff --git a/projects/web/src/main/java/cc/tweaked/web/stub/ReentrantLock.java b/projects/web/src/main/java/cc/tweaked/web/stub/ReentrantLock.java index ebe15a2f75..28fe99018e 100644 --- a/projects/web/src/main/java/cc/tweaked/web/stub/ReentrantLock.java +++ b/projects/web/src/main/java/cc/tweaked/web/stub/ReentrantLock.java @@ -8,6 +8,9 @@ * A no-op stub for {@link java.util.concurrent.locks.ReentrantLock}. */ public class ReentrantLock { + public void lock() { + } + public boolean tryLock() { return true; } From e7c7919cad1b1834b51356890bc8f3496849f76b Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Tue, 12 Nov 2024 09:17:03 +0000 Subject: [PATCH 22/39] Add test for turtle crafting with remainders See #2007. This isn't an issue on 1.20.1, so it doesn't fix the issue, but good to have the test everywhere. --- .../redstone/RedstoneRelayPeripheral.java | 4 +- .../computercraft/gametest/Turtle_Test.kt | 29 ++++ .../turtle_test.craft_remainder.snbt | 137 ++++++++++++++++++ 3 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 projects/common/src/testMod/resources/data/cctest/structures/turtle_test.craft_remainder.snbt diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayPeripheral.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayPeripheral.java index e0a73a1074..7f03cc9cde 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayPeripheral.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/redstone/RedstoneRelayPeripheral.java @@ -14,7 +14,9 @@ import javax.annotation.Nullable; /** - * The redstone relay is a peripheral that allows reading and outputting redstone signals. + * The redstone relay is a peripheral that allows reading and outputting redstone signals. While this is not very useful + * on its own (as computers have the same functionality [built-in][`redstone`]), this can be used with [wired + * modems][`modem`] to interact with multiple redstone signals from the same computer. *

* The peripheral provides largely identical methods to a computer's built-in {@link RedstoneAPI} API, allowing setting * signals on all six sides of the block ("top", "bottom", "left", "right", "front" and "back"). diff --git a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Turtle_Test.kt b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Turtle_Test.kt index 79e7e10791..df1c91c13d 100644 --- a/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Turtle_Test.kt +++ b/projects/common/src/testMod/kotlin/dan200/computercraft/gametest/Turtle_Test.kt @@ -679,6 +679,35 @@ class Turtle_Test { } } + /** + * `turtle.craft` leaves a remainder + * + * @see [#2007](https://github.com/cc-tweaked/CC-Tweaked/issues/2007) + */ + @GameTest + fun Craft_remainder(helper: GameTestHelper) = helper.sequence { + thenOnComputer { + callPeripheral("left", "craft", 1).assertArrayEquals(true) + } + thenExecute { + val turtle = helper.getBlockEntity(BlockPos(2, 2, 2), ModRegistry.BlockEntities.TURTLE_NORMAL.get()) + + val turtleStack = ItemStack(ModRegistry.Items.TURTLE_NORMAL.get()) + turtleStack.orCreateTag + + assertThat( + "Inventory is as expected.", + turtle.contents, + contains( + isStack(turtleStack), isStack(Items.WET_SPONGE, 1), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), + isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), + isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), + isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), isStack(ItemStack.EMPTY), + ), + ) + } + } + /** * `turtle.equipLeft` equips a tool. */ diff --git a/projects/common/src/testMod/resources/data/cctest/structures/turtle_test.craft_remainder.snbt b/projects/common/src/testMod/resources/data/cctest/structures/turtle_test.craft_remainder.snbt new file mode 100644 index 0000000000..414b09b7d1 --- /dev/null +++ b/projects/common/src/testMod/resources/data/cctest/structures/turtle_test.craft_remainder.snbt @@ -0,0 +1,137 @@ +{ + DataVersion: 3465, + size: [5, 5, 5], + data: [ + {pos: [0, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [0, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [1, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [2, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [3, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 0], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 1], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 2], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 3], state: "minecraft:polished_andesite"}, + {pos: [4, 0, 4], state: "minecraft:polished_andesite"}, + {pos: [0, 1, 0], state: "minecraft:air"}, + {pos: [0, 1, 1], state: "minecraft:air"}, + {pos: [0, 1, 2], state: "minecraft:air"}, + {pos: [0, 1, 3], state: "minecraft:air"}, + {pos: [0, 1, 4], state: "minecraft:air"}, + {pos: [1, 1, 0], state: "minecraft:air"}, + {pos: [1, 1, 1], state: "minecraft:air"}, + {pos: [1, 1, 2], state: "minecraft:air"}, + {pos: [1, 1, 3], state: "minecraft:air"}, + {pos: [1, 1, 4], state: "minecraft:air"}, + {pos: [2, 1, 0], state: "minecraft:air"}, + {pos: [2, 1, 1], state: "minecraft:air"}, + {pos: [2, 1, 2], state: "computercraft:turtle_normal{facing:north,waterlogged:false}", nbt: {ComputerId: 1, Fuel: 0, Items: [{Count: 1b, Slot: 0b, id: "computercraft:turtle_normal", tag: {Color: 13388876}}, {Count: 1b, Slot: 1b, id: "minecraft:wet_sponge"}], Label: "turtle_test.craft_remainder", LeftUpgrade: "minecraft:crafting_table", LeftUpgradeNbt: {}, On: 1b, Slot: 0, id: "computercraft:turtle_normal"}}, + {pos: [2, 1, 3], state: "minecraft:air"}, + {pos: [2, 1, 4], state: "minecraft:air"}, + {pos: [3, 1, 0], state: "minecraft:air"}, + {pos: [3, 1, 1], state: "minecraft:air"}, + {pos: [3, 1, 2], state: "minecraft:air"}, + {pos: [3, 1, 3], state: "minecraft:air"}, + {pos: [3, 1, 4], state: "minecraft:air"}, + {pos: [4, 1, 0], state: "minecraft:air"}, + {pos: [4, 1, 1], state: "minecraft:air"}, + {pos: [4, 1, 2], state: "minecraft:air"}, + {pos: [4, 1, 3], state: "minecraft:air"}, + {pos: [4, 1, 4], state: "minecraft:air"}, + {pos: [0, 2, 0], state: "minecraft:air"}, + {pos: [0, 2, 1], state: "minecraft:air"}, + {pos: [0, 2, 2], state: "minecraft:air"}, + {pos: [0, 2, 3], state: "minecraft:air"}, + {pos: [0, 2, 4], state: "minecraft:air"}, + {pos: [1, 2, 0], state: "minecraft:air"}, + {pos: [1, 2, 1], state: "minecraft:air"}, + {pos: [1, 2, 2], state: "minecraft:air"}, + {pos: [1, 2, 3], state: "minecraft:air"}, + {pos: [1, 2, 4], state: "minecraft:air"}, + {pos: [2, 2, 0], state: "minecraft:air"}, + {pos: [2, 2, 1], state: "minecraft:air"}, + {pos: [2, 2, 2], state: "minecraft:air"}, + {pos: [2, 2, 3], state: "minecraft:air"}, + {pos: [2, 2, 4], state: "minecraft:air"}, + {pos: [3, 2, 0], state: "minecraft:air"}, + {pos: [3, 2, 1], state: "minecraft:air"}, + {pos: [3, 2, 2], state: "minecraft:air"}, + {pos: [3, 2, 3], state: "minecraft:air"}, + {pos: [3, 2, 4], state: "minecraft:air"}, + {pos: [4, 2, 0], state: "minecraft:air"}, + {pos: [4, 2, 1], state: "minecraft:air"}, + {pos: [4, 2, 2], state: "minecraft:air"}, + {pos: [4, 2, 3], state: "minecraft:air"}, + {pos: [4, 2, 4], state: "minecraft:air"}, + {pos: [0, 3, 0], state: "minecraft:air"}, + {pos: [0, 3, 1], state: "minecraft:air"}, + {pos: [0, 3, 2], state: "minecraft:air"}, + {pos: [0, 3, 3], state: "minecraft:air"}, + {pos: [0, 3, 4], state: "minecraft:air"}, + {pos: [1, 3, 0], state: "minecraft:air"}, + {pos: [1, 3, 1], state: "minecraft:air"}, + {pos: [1, 3, 2], state: "minecraft:air"}, + {pos: [1, 3, 3], state: "minecraft:air"}, + {pos: [1, 3, 4], state: "minecraft:air"}, + {pos: [2, 3, 0], state: "minecraft:air"}, + {pos: [2, 3, 1], state: "minecraft:air"}, + {pos: [2, 3, 2], state: "minecraft:air"}, + {pos: [2, 3, 3], state: "minecraft:air"}, + {pos: [2, 3, 4], state: "minecraft:air"}, + {pos: [3, 3, 0], state: "minecraft:air"}, + {pos: [3, 3, 1], state: "minecraft:air"}, + {pos: [3, 3, 2], state: "minecraft:air"}, + {pos: [3, 3, 3], state: "minecraft:air"}, + {pos: [3, 3, 4], state: "minecraft:air"}, + {pos: [4, 3, 0], state: "minecraft:air"}, + {pos: [4, 3, 1], state: "minecraft:air"}, + {pos: [4, 3, 2], state: "minecraft:air"}, + {pos: [4, 3, 3], state: "minecraft:air"}, + {pos: [4, 3, 4], state: "minecraft:air"}, + {pos: [0, 4, 0], state: "minecraft:air"}, + {pos: [0, 4, 1], state: "minecraft:air"}, + {pos: [0, 4, 2], state: "minecraft:air"}, + {pos: [0, 4, 3], state: "minecraft:air"}, + {pos: [0, 4, 4], state: "minecraft:air"}, + {pos: [1, 4, 0], state: "minecraft:air"}, + {pos: [1, 4, 1], state: "minecraft:air"}, + {pos: [1, 4, 2], state: "minecraft:air"}, + {pos: [1, 4, 3], state: "minecraft:air"}, + {pos: [1, 4, 4], state: "minecraft:air"}, + {pos: [2, 4, 0], state: "minecraft:air"}, + {pos: [2, 4, 1], state: "minecraft:air"}, + {pos: [2, 4, 2], state: "minecraft:air"}, + {pos: [2, 4, 3], state: "minecraft:air"}, + {pos: [2, 4, 4], state: "minecraft:air"}, + {pos: [3, 4, 0], state: "minecraft:air"}, + {pos: [3, 4, 1], state: "minecraft:air"}, + {pos: [3, 4, 2], state: "minecraft:air"}, + {pos: [3, 4, 3], state: "minecraft:air"}, + {pos: [3, 4, 4], state: "minecraft:air"}, + {pos: [4, 4, 0], state: "minecraft:air"}, + {pos: [4, 4, 1], state: "minecraft:air"}, + {pos: [4, 4, 2], state: "minecraft:air"}, + {pos: [4, 4, 3], state: "minecraft:air"}, + {pos: [4, 4, 4], state: "minecraft:air"} + ], + entities: [], + palette: [ + "minecraft:polished_andesite", + "minecraft:air", + "computercraft:turtle_normal{facing:north,waterlogged:false}" + ] +} From 87ce41f251671d1cde060969270ee1d979da9b2d Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Tue, 12 Nov 2024 21:11:22 +0000 Subject: [PATCH 23/39] Update Cobalt to 0.9.5 - Fix several issues with large doubles - Fix metatable cache not being cleared --- gradle/libs.versions.toml | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 43504 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cb337ee27c..3c103a0858 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -26,7 +26,7 @@ slf4j = "2.0.1" asm = "9.6" autoService = "1.1.1" checkerFramework = "3.42.0" -cobalt = "0.9.4" +cobalt = { strictly = "0.9.5" } commonsCli = "1.6.0" jetbrainsAnnotations = "24.1.0" jsr305 = "3.0.2" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 2c3521197d7c4586c843d1d3e9090525f1898cde..a4b76b9530d66f5e68d973ea569d8e19de379189 100644 GIT binary patch delta 3990 zcmV;H4{7l5(*nQL0Kr1kzC=_KMxQY0|W5(lc#i zH*M1^P4B}|{x<+fkObwl)u#`$GxKKV&3pg*-y6R6txw)0qU|Clf9Uds3x{_-**c=7 z&*)~RHPM>Rw#Hi1R({;bX|7?J@w}DMF>dQQU2}9yj%iLjJ*KD6IEB2^n#gK7M~}6R zkH+)bc--JU^pV~7W=3{E*4|ZFpDpBa7;wh4_%;?XM-5ZgZNnVJ=vm!%a2CdQb?oTa z70>8rTb~M$5Tp!Se+4_OKWOB1LF+7gv~$$fGC95ToUM(I>vrd$>9|@h=O?eARj0MH zT4zo(M>`LWoYvE>pXvqG=d96D-4?VySz~=tPVNyD$XMshoTX(1ZLB5OU!I2OI{kb) zS8$B8Qm>wLT6diNnyJZC?yp{Kn67S{TCOt-!OonOK7$K)e-13U9GlnQXPAb&SJ0#3 z+vs~+4Qovv(%i8g$I#FCpCG^C4DdyQw3phJ(f#y*pvNDQCRZ~MvW<}fUs~PL=4??j zmhPyg<*I4RbTz|NHFE-DC7lf2=}-sGkE5e!RM%3ohM7_I^IF=?O{m*uUPH(V?gqyc(Rp?-Qu(3bBIL4Fz(v?=_Sh?LbK{nqZMD>#9D_hNhaV$0ef3@9V90|0u#|PUNTO>$F=qRhg1duaE z0`v~X3G{8RVT@kOa-pU+z8{JWyP6GF*u2e8eKr7a2t1fuqQy)@d|Qn(%YLZ62TWtoX@$nL}9?atE#Yw`rd(>cr0gY;dT9~^oL;u)zgHUvxc2I*b&ZkGM-iq=&(?kyO(3}=P! zRp=rErEyMT5UE9GjPHZ#T<`cnD)jyIL!8P{H@IU#`e8cAG5jMK zVyKw7--dAC;?-qEu*rMr$5@y535qZ6p(R#+fLA_)G~!wnT~~)|s`}&fA(s6xXN`9j zP#Fd3GBa#HeS{5&8p?%DKUyN^X9cYUc6vq}D_3xJ&d@=6j(6BZKPl?!k1?!`f3z&a zR4ZF60Mx7oBxLSxGuzA*Dy5n-d2K=+)6VMZh_0KetK|{e;E{8NJJ!)=_E~1uu=A=r zrn&gh)h*SFhsQJo!f+wKMIE;-EOaMSMB@aXRU(UcnJhZW^B^mgs|M9@5WF@s6B0p& zm#CTz)yiQCgURE{%hjxHcJ6G&>G9i`7MyftL!QQd5 z@RflRs?7)99?X`kHNt>W3l7YqscBpi*R2+fsgABor>KVOu(i(`03aytf2UA!&SC9v z!E}whj#^9~=XHMinFZ;6UOJjo=mmNaWkv~nC=qH9$s-8roGeyaW-E~SzZ3Gg>j zZ8}<320rg4=$`M0nxN!w(PtHUjeeU?MvYgWKZ6kkzABK;vMN0|U;X9abJleJA(xy<}5h5P(5 z{RzAFPvMnX2m0yH0Jn2Uo-p`daE|(O`YQiC#jB8;6bVIUf?SY(k$#C0`d6qT`>Xe0+0}Oj0=F&*D;PVe=Z<=0AGI<6$gYLwa#r` zm449x*fU;_+J>Mz!wa;T-wldoBB%&OEMJgtm#oaI60TSYCy7;+$5?q!zi5K`u66Wq zvg)Fx$s`V3Em{=OEY{3lmh_7|08ykS&U9w!kp@Ctuzqe1JFOGz6%i5}Kmm9>^=gih z?kRxqLA<3@e=}G4R_?phW{4DVr?`tPfyZSN@R=^;P;?!2bh~F1I|fB7P=V=9a6XU5 z<#0f>RS0O&rhc&nTRFOW7&QhevP0#>j0eq<1@D5yAlgMl5n&O9X|Vq}%RX}iNyRFF z7sX&u#6?E~bm~N|z&YikXC=I0E*8Z$v7PtWfjy)$e_Ez25fnR1Q=q1`;U!~U>|&YS zaOS8y!^ORmr2L4ik!IYR8@Dcx8MTC=(b4P6iE5CnrbI~7j7DmM8em$!da&D!6Xu)!vKPdLG z9f#)se|6=5yOCe)N6xDhPI!m81*dNe7u985zi%IVfOfJh69+#ag4ELzGne?o`eA`42K4T)h3S+s)5IT97%O>du- z0U54L8m4}rkRQ?QBfJ%DLssy^+a7Ajw;0&`NOTY4o;0-ivm9 zBz1C%nr_hQ)X)^QM6T1?=yeLkuG9Lf50(eH}`tFye;01&(p?8i+6h};VV-2B~qdxeC#=X z(JLlzy&fHkyi9Ksbcs~&r^%lh^2COldLz^H@X!s~mr9Dr6z!j+4?zkD@Ls7F8(t(f z9`U?P$Lmn*Y{K}aR4N&1N=?xtQ1%jqf1~pJyQ4SgBrEtR`j4lQuh7cqP49Em5cO=I zB(He2`iPN5M=Y0}h(IU$37ANTGx&|b-u1BYA*#dE(L-lptoOpo&th~E)_)y-`6kSH z3vvyVrcBwW^_XYReJ=JYd9OBQrzv;f2AQdZH#$Y{Y+Oa33M70XFI((fs;mB4e`<<{ ze4dv2B0V_?Ytsi>>g%qs*}oDGd5d(RNZ*6?7qNbdp7wP4T72=F&r?Ud#kZr8Ze5tB z_oNb7{G+(o2ajL$!69FW@jjPQ2a5C)m!MKKRirC$_VYIuVQCpf9rIms0GRDf)8AH${I`q^~5rjot@#3$2#zT2f`(N^P7Z;6(@EK$q*Jgif00I6*^ZGV+XB5uw*1R-@23yTw&WKD{s1;HTL;dO)%5i#`dc6b7;5@^{KU%N|A-$zsYw4)7LA{3`Zp>1 z-?K9_IE&z)dayUM)wd8K^29m-l$lFhi$zj0l!u~4;VGR6Y!?MAfBC^?QD53hy6VdD z@eUZIui}~L%#SmajaRq1J|#> z4m=o$vZ*34=ZWK2!QMNEcp2Lbc5N1q!lEDq(bz0b;WI9;e>l=CG9^n#ro`w>_0F$Q zfZ={2QyTkfByC&gy;x!r*NyXXbk=a%~~(#K?< zTke0HuF5{Q+~?@!KDXR|g+43$+;ab`^flS%miup_0OUTm=nIc%d5nLP)i308PIjl_YMF6cpQ__6&$n6it8K- z8PIjl_YMF6cpQ_!r)L8IivW`WdK8mBs6PXdjR2DYdK8nCs73=4j{uVadK8oNjwX|E wpAeHLsTu^*Y>Trk?aBtSQ(D-o$(D8Px^?ZI-PUB? z*1fv!{YdHme3Fc8%cR@*@zc5A_nq&2=R47Hp@$-JF4Fz*;SLw5}K^y>s-s;V!}b2i=5=M- zComP?ju>8Fe@=H@rlwe1l`J*6BTTo`9b$zjQ@HxrAhp0D#u?M~TxGC_!?ccCHCjt| zF*PgJf@kJB`|Ml}cmsyrAjO#Kjr^E5p29w+#>$C`Q|54BoDv$fQ9D?3n32P9LPMIzu?LjNqggOH=1@T{9bMn*u8(GI z!;MLTtFPHal^S>VcJdiYqX0VU|Rn@A}C1xOlxCribxes0~+n2 z6qDaIA2$?e`opx3_KW!rAgbpzU)gFdjAKXh|5w``#F0R|c)Y)Du0_Ihhz^S?k^pk% zP>9|pIDx)xHH^_~+aA=^$M!<8K~Hy(71nJGf6`HnjtS=4X4=Hk^O71oNia2V{HUCC zoN3RSBS?mZCLw;l4W4a+D8qc)XJS`pUJ5X-f^1ytxwr`@si$lAE?{4G|o; zO0l>`rr?;~c;{ZEFJ!!3=7=FdGJ?Q^xfNQh4A?i;IJ4}B+A?4olTK(fN++3CRBP97 ze~lG9h%oegkn)lpW-4F8o2`*WW0mZHwHez`ko@>U1_;EC_6ig|Drn@=DMV9YEUSCa zIf$kHei3(u#zm9I!Jf(4t`Vm1lltJ&lVHy(eIXE8sy9sUpmz%I_gA#8x^Zv8%w?r2 z{GdkX1SkzRIr>prRK@rqn9j2wG|rUvf6PJbbin=yy-TAXrguvzN8jL$hUrIXzr^s5 zVM?H4;eM-QeRFr06@ifV(ocvk?_)~N@1c2ien56UjWXid6W%6ievIh)>dk|rIs##^kY67ib8Kw%#-oVFaXG7$ERyA9(NSJUvWiOA5H(!{uOpcW zg&-?iqPhds%3%tFspHDqqr;A!e@B#iPQjHd=c>N1LoOEGRehVoPOdxJ>b6>yc#o#+ zl8s8!(|NMeqjsy@0x{8^j0d00SqRZjp{Kj)&4UHYGxG+z9b-)72I*&J70?+8e?p_@ z=>-(>l6z5vYlP~<2%DU02b!mA{7mS)NS_eLe=t)sm&+Pmk?asOEKlkPQ)EUvvfC=;4M&*|I!w}(@V_)eUKLA_t^%`o z0PM9LV|UKTLnk|?M3u!|f2S0?UqZsEIH9*NJS-8lzu;A6-rr-ot=dg9SASoluZUkFH$7X; zP=?kYX!K?JL-b~<#7wU;b;eS)O;@?h%sPPk{4xEBxb{!sm0AY|f9cNvx6>$3F!*0c z75H=dy8JvTyO8}g1w{$9T$p~5en}AeSLoCF>_RT9YPMpChUjl310o*$QocjbH& zbnwg#gssR#jDVN{uEi3n(PZ%PFZ|6J2 z5_rBf0-u>e4sFe0*Km49ATi7>Kn0f9!uc|rRMR1Dtt6m1LW8^>qFlo}h$@br=Rmpi z;mI&>OF64Be{dVeHI8utrh)v^wsZ0jii%x8UgZ8TC%K~@I(4E};GFW&(;WVov}3%H zH;IhRkfD^(vt^DjZz(MyHLZxv8}qzPc(%itBkBwf_fC~sDBgh<3XAv5cxxfF3<2U! z03Xe&z`is!JDHbe;mNmfkH+_LFE*I2^mdL@7(@9DfAcP6O04V-ko;Rpgp<%Cj5r8Z zd0`sXoIjV$j)--;jA6Zy^D5&5v$o^>e%>Q?9GLm{i~p^lAn!%ZtF$I~>39XVZxk0b zROh^Bk9cE0AJBLozZIEmy7xG(yHWGztvfnr0(2ro1%>zsGMS^EMu+S$r=_;9 zWwZkgf7Q7`H9sLf2Go^Xy6&h~a&%s2_T@_Csf19MntF$aVFiFkvE3_hUg(B@&Xw@YJ zpL$wNYf78=0c@!QU6_a$>CPiXT7QAGDM}7Z(0z#_ZA=fmLUj{2z7@Ypo71UDy8GHr z-&TLKf6a5WCf@Adle3VglBt4>Z>;xF}}-S~B7<(%B;Y z0QR55{z-buw>8ilNM3u6I+D$S%?)(p>=eBx-HpvZj{7c*_?K=d()*7q?93us}1dq%FAFYLsW8ZTQ_XZLh`P2*6(NgS}qGcfGXVWpwsp#Rs}IuKbk*`2}&) zI^Vsk6S&Q4@oYS?dJ`NwMVBs6f57+RxdqVub#PvMu?$=^OJy5xEl0<5SLsSRy%%a0 zi}Y#1-F3m;Ieh#Y12UgW?-R)|eX>ZuF-2cc!1>~NS|XSF-6In>zBoZg+ml!6%fk7U zw0LHcz8VQk(jOJ+Yu)|^|15ufl$KQd_1eUZZzj`aC%umU6F1&D5XVWce_wAe(qCSZ zpX-QF4e{EmEVN9~6%bR5U*UT{eMHfcUo`jw*u?4r2s_$`}U{?NjvEm(u&<>B|%mq$Q3weshxk z76<``8vh{+nX`@9CB6IE&z)I%IFjR^LH{s1p|eppv=x za(g_jLU|xjWMAn-V7th$f({|LG8zzIE0g?cyW;%Dmtv%C+0@xVxPE^ zyZzi9P%JAD6ynwHptuzP`Kox7*9h7XSMonCalv;Md0i9Vb-c*!f0ubfk?&T&T}AHh z4m8Bz{JllKcdNg?D^%a5MFQ;#1z|*}H^qHLzW)L}wp?2tY7RejtSh8<;Zw)QGJYUm z|MbTxyj*McKlStlT9I5XlSWtQGN&-LTr2XyNU+`490rg?LYLMRnz-@oKqT1hpCGqP zyRXt4=_Woj$%n5ee<3zhLF>5>`?m9a#xQH+Jk_+|RM8Vi;2*XbK- zEL6sCpaGPzP>k8f4Kh|##_imt#zJMB;ir|JrMPGW`rityK1vHXMLy18%qmMQAm4WZ zP)i30KR&5vs15)C+8dM66&$k~i|ZT;KR&5vs15)C+8dJ(sAmGPijyIz6_bsqKLSFH zlOd=TljEpH0>h4zA*dCTK&emy#FCRCs1=i^sZ9bFmXjf<6_X39E(XY)00000#N437 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9355b41557..df97d72b8b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From bdffabc08e2eb9895f966c949acc8334a2bf4475 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Wed, 13 Nov 2024 10:19:10 +0000 Subject: [PATCH 24/39] Clarify docs around registering peripherals --- projects/common-api/build.gradle.kts | 30 +++ .../api/network/wired/WiredElement.java | 2 +- .../shared/computer/apis/CommandAPI.java | 2 +- .../data/HasComputerIdLootCondition.java | 2 +- .../computercraft/api/lua/GenericSource.java | 2 +- .../computercraft/api/package-info.java | 4 +- .../api/peripheral/GenericPeripheral.java | 14 +- .../api/peripheral/IDynamicPeripheral.java | 1 - .../api/peripheral/IPeripheral.java | 24 +- .../api/peripheral/PeripheralType.java | 2 + .../api/peripheral/WorkMonitor.java | 2 +- .../api/peripheral/package-info.java | 205 ++++++++++++++++++ .../mainthread/MainThreadExecutor.java | 2 +- 13 files changed, 270 insertions(+), 22 deletions(-) create mode 100644 projects/core-api/src/main/java/dan200/computercraft/api/peripheral/package-info.java diff --git a/projects/common-api/build.gradle.kts b/projects/common-api/build.gradle.kts index 3bdc0d2823..b00eb56db0 100644 --- a/projects/common-api/build.gradle.kts +++ b/projects/common-api/build.gradle.kts @@ -8,6 +8,8 @@ plugins { id("cc-tweaked.vanilla") } +val mcVersion: String by extra + java { withJavadocJar() } @@ -17,8 +19,36 @@ dependencies { } tasks.javadoc { + title = "CC: Tweaked $version Minecraft $mcVersion" include("dan200/computercraft/api/**/*.java") + options { + (this as StandardJavadocDocletOptions) + + groups = mapOf( + "Common" to listOf( + "dan200.computercraft.api", + "dan200.computercraft.api.lua", + "dan200.computercraft.api.peripheral", + ), + "Upgrades" to listOf( + "dan200.computercraft.api.client.turtle", + "dan200.computercraft.api.pocket", + "dan200.computercraft.api.turtle", + "dan200.computercraft.api.upgrades", + ), + ) + + addBooleanOption("-allow-script-in-comments", true) + bottom( + """ + + + + """.trimIndent(), + ) + } + // Include the core-api in our javadoc export. This is wrong, but it means we can export a single javadoc dump. source(project(":core-api").sourceSets.main.map { it.allJava }) } diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/network/wired/WiredElement.java b/projects/common-api/src/main/java/dan200/computercraft/api/network/wired/WiredElement.java index 0d58975f38..01d197ebdc 100644 --- a/projects/common-api/src/main/java/dan200/computercraft/api/network/wired/WiredElement.java +++ b/projects/common-api/src/main/java/dan200/computercraft/api/network/wired/WiredElement.java @@ -14,7 +14,7 @@ * as a proxy for all network objects. Whilst the node may change networks, an element's node should remain constant * for its lifespan. *

- * Elements are generally tied to a block or tile entity in world. In such as case, one should provide the + * Elements are generally tied to a block or block entity in world. In such as case, one should provide the * {@link WiredElement} capability for the appropriate sides. */ public interface WiredElement extends WiredSender { diff --git a/projects/common/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java b/projects/common/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java index b9574340b3..10b937237e 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java @@ -248,7 +248,7 @@ public final Object[] getBlockPosition() { * Get some basic information about a block. *

* The returned table contains the current name, metadata and block state (as - * with [`turtle.inspect`]). If there is a tile entity for that block, its NBT + * with [`turtle.inspect`]). If there is a block entity for that block, its NBT * will also be returned. * * @param x The x position of the block to query. diff --git a/projects/common/src/main/java/dan200/computercraft/shared/data/HasComputerIdLootCondition.java b/projects/common/src/main/java/dan200/computercraft/shared/data/HasComputerIdLootCondition.java index cb1f4f3192..63c328c927 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/data/HasComputerIdLootCondition.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/data/HasComputerIdLootCondition.java @@ -15,7 +15,7 @@ import java.util.Set; /** - * A loot condition which checks if the tile entity has a non-0 ID. + * A loot condition which checks if the block entity has a computer ID. */ public final class HasComputerIdLootCondition implements LootItemCondition { public static final HasComputerIdLootCondition INSTANCE = new HasComputerIdLootCondition(); diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/lua/GenericSource.java b/projects/core-api/src/main/java/dan200/computercraft/api/lua/GenericSource.java index 515967ed72..99c8493bf0 100644 --- a/projects/core-api/src/main/java/dan200/computercraft/api/lua/GenericSource.java +++ b/projects/core-api/src/main/java/dan200/computercraft/api/lua/GenericSource.java @@ -23,7 +23,7 @@ * *

{@code
  * public class InventoryMethods implements GenericSource {
- *     \@LuaFunction( mainThread = true )
+ *     \@LuaFunction(mainThread = true)
  *     public int size(IItemHandler inventory) {
  *         return inventory.getSlots();
  *     }
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/package-info.java b/projects/core-api/src/main/java/dan200/computercraft/api/package-info.java
index a19a3583d0..9d15df9beb 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/package-info.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/package-info.java
@@ -7,11 +7,13 @@
  * 

* You probably want to start in the following places: *

    - *
  • {@link dan200.computercraft.api.peripheral.IPeripheral} for registering new peripherals.
  • + *
  • {@link dan200.computercraft.api.peripheral} for registering new peripherals.
  • *
  • * {@link dan200.computercraft.api.lua.LuaFunction} and {@link dan200.computercraft.api.lua.IArguments} for * adding methods to your peripheral or Lua objects. *
  • + *
  • {@link dan200.computercraft.api.turtle.ITurtleUpgrade} for turtle upgrades.
  • + *
  • {@link dan200.computercraft.api.pocket.IPocketUpgrade} for pocket upgrades.
  • *
*/ @DefaultQualifier(value = NonNull.class, locations = { diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/GenericPeripheral.java b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/GenericPeripheral.java index bb866976e8..e288ee4494 100644 --- a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/GenericPeripheral.java +++ b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/GenericPeripheral.java @@ -19,17 +19,17 @@ public interface GenericPeripheral extends GenericSource { * Unlike normal {@link IPeripheral}s, {@link GenericPeripheral} do not have to have a type. By default, the * resulting peripheral uses the resource name of the wrapped block entity (for instance {@code minecraft:chest}). *

- * However, in some cases it may be more appropriate to specify a more readable name. Overriding this method allows - * you to do so. + * However, in some cases it may be more appropriate to specify a more readable name, or provide + * {@linkplain PeripheralType#getAdditionalTypes() additional types}. Overriding this method allows you to do so. *

- * When multiple {@link GenericPeripheral}s return a non-empty peripheral type for a single tile entity, the - * lexicographically smallest will be chosen. In order to avoid this conflict, this method should only be - * implemented when your peripheral targets a single tile entity AND it's likely that you're the - * only mod to do so. Similarly this should NOT be implemented when your methods target a - * capability or other interface (such as Forge's {@code IItemHandler}). + * When multiple {@link GenericPeripheral}s provide a {@linkplain PeripheralType#getPrimaryType() primary peripheral + * type} for a single block entity, the lexicographically smallest will be chosen. In order to avoid this conflict, + * primary types should only be used when your peripheral targets a single block entity AND it's + * likely that you're the only mod to do so. * * @return The type of this peripheral or {@link PeripheralType#untyped()}. * @see IPeripheral#getType() + * @see IPeripheral#getAdditionalTypes() */ default PeripheralType getType() { return PeripheralType.untyped(); diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IDynamicPeripheral.java b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IDynamicPeripheral.java index 6d2b96c4a3..230f7694fb 100644 --- a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IDynamicPeripheral.java +++ b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IDynamicPeripheral.java @@ -10,7 +10,6 @@ * A peripheral whose methods are not known at runtime. *

* This behaves similarly to {@link IDynamicLuaObject}, though also accepting the current {@link IComputerAccess}. - * Generally one may use {@link LuaFunction} instead of implementing this interface. */ public interface IDynamicPeripheral extends IPeripheral { /** diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IPeripheral.java b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IPeripheral.java index 3d96075a8b..1b80787f0c 100644 --- a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IPeripheral.java +++ b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/IPeripheral.java @@ -4,19 +4,28 @@ package dan200.computercraft.api.peripheral; +import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.LuaFunction; +import dan200.computercraft.api.lua.LuaTask; import javax.annotation.Nullable; import java.util.Set; /** - * The interface that defines a peripheral. + * A peripheral is an external device that a computer can interact with. *

- * In order to expose a peripheral for your block or block entity, you should either attach a capability (Forge) or - * use the block lookup API (Fabric). This interface cannot be implemented directly on the block entity. + * Peripherals can be supplied by both a block (or block entity), or from + * {@linkplain dan200.computercraft.api.turtle.ITurtleUpgrade#createPeripheral(dan200.computercraft.api.turtle.ITurtleAccess, dan200.computercraft.api.turtle.TurtleSide) turtle} + * or {@linkplain dan200.computercraft.api.pocket.IPocketUpgrade#createPeripheral(dan200.computercraft.api.pocket.IPocketAccess) pocket} + * upgrades. *

- * Peripherals should provide a series of methods to the user, either using {@link LuaFunction} or by implementing - * {@link IDynamicPeripheral}. + * See the {@linkplain dan200.computercraft.api.peripheral package documentation} for more information on registering peripherals. + *

+ * Peripherals should provide a series of methods to the user, typically by annotating Java methods with + * {@link LuaFunction}. Alternatively, {@link IDynamicPeripheral} may be used to provide a dynamic set of methods. + * Remember that peripheral methods are called on the computer thread, and so it is not safe to interact with + * the Minecraft world by default. One should use {@link LuaFunction#mainThread()} or + * {@link ILuaContext#executeMainThreadTask(LuaTask)} to run code on the main server thread. */ public interface IPeripheral { /** @@ -24,6 +33,7 @@ public interface IPeripheral { * This can be queried from lua by calling {@code peripheral.getType()} * * @return A string identifying the type of peripheral. + * @see PeripheralType#getPrimaryType() */ String getType(); @@ -81,7 +91,7 @@ default void detach(IComputerAccess computer) { } /** - * Get the object that this peripheral provides methods for. This will generally be the tile entity + * Get the object that this peripheral provides methods for. This will generally be the block entity * or block, but may be an inventory, entity, etc... * * @return The object this peripheral targets @@ -95,7 +105,7 @@ default Object getTarget() { * Determine whether this peripheral is equivalent to another one. *

* The minimal example should at least check whether they are the same object. However, you may wish to check if - * they point to the same block or tile entity. + * they point to the same block or block entity. * * @param other The peripheral to compare against. This may be {@code null}. * @return Whether these peripherals are equivalent. diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/PeripheralType.java b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/PeripheralType.java index 08cc97448d..e651df0063 100644 --- a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/PeripheralType.java +++ b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/PeripheralType.java @@ -96,6 +96,7 @@ public static PeripheralType ofAdditional(String... additionalTypes) { * Get the name of this peripheral type. This may be {@code null}. * * @return The type of this peripheral. + * @see IPeripheral#getType() */ @Nullable public String getPrimaryType() { @@ -107,6 +108,7 @@ public String getPrimaryType() { * a peripheral might have. * * @return All additional types. + * @see IPeripheral#getAdditionalTypes() */ public Set getAdditionalTypes() { return additionalTypes; diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/WorkMonitor.java b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/WorkMonitor.java index 265285c869..49d44da1ca 100644 --- a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/WorkMonitor.java +++ b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/WorkMonitor.java @@ -11,7 +11,7 @@ * Monitors "work" associated with a computer, keeping track of how much a computer has done, and ensuring every * computer receives a fair share of any processing time. *

- * This is primarily intended for work done by peripherals on the main thread (such as on a tile entity's tick), but + * This is primarily intended for work done by peripherals on the main thread (such as on a block entity's tick), but * could be used for other purposes (such as complex computations done on another thread). *

* Before running a task, one should call {@link #canWork()} to determine if the computer is currently allowed to diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/package-info.java b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/package-info.java new file mode 100644 index 0000000000..dfc48e6709 --- /dev/null +++ b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/package-info.java @@ -0,0 +1,205 @@ +// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 + +/** + * Peripherals for blocks and upgrades. + *

+ * A peripheral is an external device that a computer can interact with. Peripherals can be supplied by both a block (or + * block entity), or from {@linkplain dan200.computercraft.api.turtle.ITurtleUpgrade#createPeripheral(dan200.computercraft.api.turtle.ITurtleAccess, dan200.computercraft.api.turtle.TurtleSide) turtle} + * or {@linkplain dan200.computercraft.api.pocket.IPocketUpgrade#createPeripheral(dan200.computercraft.api.pocket.IPocketAccess) pocket} + * upgrades. + * + *

Creating peripherals for blocks

+ * One of the most common things you'll want to do with ComputerCraft's API is register new peripherals. This is + * relatively simple once you know how to do it, but may be a bit confusing the first time round. + *

+ * There are currently two possible ways to define a peripheral in ComputerCraft: + *

    + *
  • + *

    + * With a {@linkplain dan200.computercraft.api.peripheral.GenericPeripheral generic peripheral}: + * Generic peripherals are a way to add peripheral methods to any block entity, in a trait-based manner. This + * allows multiple mods to add methods to the same block entity. + *

    + * This is the recommended approach if you just want to add a couple of methods, and do not need any advanced + * functionality. + *

  • + *
  • + *

    + * With an {@link dan200.computercraft.api.peripheral.IPeripheral}: If your peripheral needs + * more advanced behaviour, such as knowing which computers it is attached to, then you can use an + * {@link dan200.computercraft.api.peripheral.IPeripheral}. + *

    + * These peripherals are currently NOT compatible with the generic peripheral system, so + * methods added by other mods (including CC's built-in inventory methods) will not be available. + *

  • + *
+ *

+ * In the following examples, we'll write a peripheral method that returns the remaining burn time of a furnace, and + * demonstrate how to register this peripheral. + * + *

Creating a generic peripheral

+ * First, we'll need to create a new {@code final} class, that implements {@link dan200.computercraft.api.peripheral.GenericPeripheral}. + * You'll need to implement {@link dan200.computercraft.api.peripheral.GenericPeripheral#id()}, which should just return + * some namespaced-string with your mod id. + *

+ * Then, we can start adding methods to your block entity. Each method should take its target type as the first + * argument, which in this case is a {@code AbstractFurnaceBlockEntity}. We then annotate this method with + * {@link dan200.computercraft.api.lua.LuaFunction} to expose it to computers. + * + *

{@code
+ * import dan200.computercraft.api.lua.LuaFunction;
+ * import dan200.computercraft.api.peripheral.GenericPeripheral;
+ * import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
+ *
+ * public final class FurnacePeripheral implements GenericPeripheral {
+ *     @Override
+ *     public String id() {
+ *         return "mymod:furnace";
+ *     }
+ *
+ *     @LuaFunction(mainThread = true)
+ *     public int getBurnTime(AbstractFurnaceBlockEntity furnace) {
+ *         return furnace.litTime;
+ *     }
+ * }
+ * }
+ *

+ * Finally, we need to register our peripheral, so that ComputerCraft is aware of it: + * + *

{@code
+ * import dan200.computercraft.api.ComputerCraftAPI;
+ *
+ * public class ComputerCraftCompat {
+ *     public static void register() {
+ *         ComputerCraftAPI.registerGenericSource(new FurnacePeripheral());
+ *     }
+ * }
+ * }
+ * + *

Creating a {@code IPeripheral}

+ * First, we'll need to create a new class that implements {@link dan200.computercraft.api.peripheral.IPeripheral}. This + * requires a couple of boilerplate methods: one to get the type of the peripheral, and an equality function. + *

+ * We can then start adding peripheral methods to our class. Each method should be {@code final}, and annotated with + * {@link dan200.computercraft.api.lua.LuaFunction}. + * + *

{@code
+ * import dan200.computercraft.api.lua.LuaFunction;
+ * import dan200.computercraft.api.peripheral.IPeripheral;
+ * import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
+ * import org.jetbrains.annotations.Nullable;
+ *
+ * public class FurnacePeripheral implements IPeripheral {
+ *     private final AbstractFurnaceBlockEntity furnace;
+ *
+ *     public FurnacePeripheral(AbstractFurnaceBlockEntity furnace) {
+ *         this.furnace = furnace;
+ *     }
+ *
+ *     @Override
+ *     public String getType() {
+ *         return "furnace";
+ *     }
+ *
+ *     @LuaFunction(mainThread = true)
+ *     public final int getBurnTime() {
+ *         return furnace.litTime;
+ *     }
+ *
+ *     @Override
+ *     public boolean equals(@Nullable IPeripheral other) {
+ *         return this == other || other instanceof FurnacePeripheral p && furnace == p.furnace;
+ *     }
+ * }
+ * }
+ *

+ * Finally, we'll need to register our peripheral. This is done with capabilities on Forge, or the block lookup API on + * Fabric. + * + *

Registering {@code IPeripheral} on Forge

+ * Registering a peripheral on Forge can be done by attaching the {@link dan200.computercraft.api.peripheral.IPeripheral} + * to a block entity. Unfortunately, this requires quite a lot of boilerplate, due to the awkward nature of + * {@code ICapabilityProvider}. If you've got an existing system for dealing with this, we recommend you use that, + * otherwise you can use something similar to the code below: + * + *
{@code
+ * import dan200.computercraft.api.peripheral.IPeripheral;
+ * import net.minecraft.core.Direction;
+ * import net.minecraft.resources.ResourceLocation;
+ * import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
+ * import net.minecraft.world.level.block.entity.BlockEntity;
+ * import net.minecraftforge.common.capabilities.Capability;
+ * import net.minecraftforge.common.capabilities.CapabilityManager;
+ * import net.minecraftforge.common.capabilities.CapabilityToken;
+ * import net.minecraftforge.common.capabilities.ICapabilityProvider;
+ * import net.minecraftforge.common.util.LazyOptional;
+ * import net.minecraftforge.event.AttachCapabilitiesEvent;
+ * import org.jetbrains.annotations.Nullable;
+ *
+ * import java.util.function.Function;
+ *
+ * public class ComputerCraftCompat {
+ *     public static final Capability CAPABILITY_PERIPHERAL = CapabilityManager.get(new CapabilityToken<>() {
+ *     });
+ *     private static final ResourceLocation PERIPHERAL = new ResourceLocation("mymod", "peripheral");
+ *
+ *     public static void register(AttachCapabilitiesEvent event) {
+ *         if (event.getObject() instanceof AbstractFurnaceBlockEntity furnace) {
+ *             PeripheralProvider.attach(event, furnace, FurnacePeripheral::new);
+ *         }
+ *     }
+ *
+ *     // A {@link ICapabilityProvider} that lazily creates an {@link IPeripheral} when required.
+ *     private static class PeripheralProvider implements ICapabilityProvider {
+ *         private final O blockEntity;
+ *         private final Function factory;
+ *         private @Nullable LazyOptional peripheral;
+ *
+ *         private PeripheralProvider(O blockEntity, Function factory) {
+ *             this.blockEntity = blockEntity;
+ *             this.factory = factory;
+ *         }
+ *
+ *         private static  void attach(AttachCapabilitiesEvent event, O blockEntity, Function factory) {
+ *             var provider = new PeripheralProvider<>(blockEntity, factory);
+ *             event.addCapability(PERIPHERAL, provider);
+ *             event.addListener(provider::invalidate);
+ *         }
+ *
+ *         private void invalidate() {
+ *             if (peripheral != null) peripheral.invalidate();
+ *             peripheral = null;
+ *         }
+ *
+ *         @Override
+ *         public  LazyOptional getCapability(Capability capability, @Nullable Direction direction) {
+ *             if (capability != CAPABILITY_PERIPHERAL) return LazyOptional.empty();
+ *             if (blockEntity.isRemoved()) return LazyOptional.empty();
+ *
+ *             var peripheral = this.peripheral;
+ *             return (peripheral == null ? (this.peripheral = LazyOptional.of(() -> factory.apply(blockEntity))) : peripheral).cast();
+ *         }
+ *     }
+ * }
+ * }
+ * + *

Registering {@code IPeripheral} on Fabric

+ * Registering a peripheral on Fabric can be done using the block lookup API, via {@code PeripheralLookup}. + * + *
{@code
+ * import dan200.computercraft.api.peripheral.PeripheralLookup;
+ * import dan200.computercraft.example.FurnacePeripheral;
+ * import net.minecraft.world.level.block.entity.BlockEntityType;
+ *
+ * public class ComputerCraftCompat {
+ *     public static void register() {
+ *         PeripheralLookup.get().registerForBlockEntity((f, s) -> new FurnacePeripheral(f), BlockEntityType.FURNACE);
+ *         PeripheralLookup.get().registerForBlockEntity((f, s) -> new FurnacePeripheral(f), BlockEntityType.BLAST_FURNACE);
+ *         PeripheralLookup.get().registerForBlockEntity((f, s) -> new FurnacePeripheral(f), BlockEntityType.SMOKER);
+ *     }
+ * }
+ * }
+ */ +package dan200.computercraft.api.peripheral; diff --git a/projects/core/src/main/java/dan200/computercraft/core/computer/mainthread/MainThreadExecutor.java b/projects/core/src/main/java/dan200/computercraft/core/computer/mainthread/MainThreadExecutor.java index adf92fa7e8..e72978d253 100644 --- a/projects/core/src/main/java/dan200/computercraft/core/computer/mainthread/MainThreadExecutor.java +++ b/projects/core/src/main/java/dan200/computercraft/core/computer/mainthread/MainThreadExecutor.java @@ -30,7 +30,7 @@ *

* Now, if anywhere during this period, we use more than our allocated time slice, the executor is marked as * {@link State#HOT}. This means it will no longer be able to execute {@link MainThread} tasks (though will still - * execute tile entity tasks, in order to prevent the main thread from exhausting work every tick). + * execute block entity tasks, in order to prevent the main thread from exhausting work every tick). *

* At the beginning of the next tick, we increment the budget e by {@link MainThreadConfig#maxComputerTime()} and any * {@link State#HOT} executors are marked as {@link State#COOLING}. They will remain cooling until their budget is fully From ad52117f0f668308f32eee0cd10f96d8a271d9eb Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Wed, 13 Nov 2024 11:00:46 +0000 Subject: [PATCH 25/39] Syntax highlight more docstrings This is going to conflict horribly with MC 1.21 (where we started using @snippet), but hopefully this still helps. --- .../java/dan200/computercraft/api/ComputerCraftAPI.java | 2 +- .../computercraft/api/turtle/TurtleUpgradeSerialiser.java | 6 +++--- .../computercraft/api/upgrades/UpgradeDataProvider.java | 2 +- .../src/main/java/dan200/computercraft/api/lua/Coerced.java | 2 +- .../java/dan200/computercraft/api/lua/GenericSource.java | 4 ++-- .../computercraft/api/peripheral/AttachedComputerSet.java | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java b/projects/common-api/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java index bf82da6cb8..3f57e43ad0 100644 --- a/projects/common-api/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java +++ b/projects/common-api/src/main/java/dan200/computercraft/api/ComputerCraftAPI.java @@ -173,7 +173,7 @@ public static PacketNetwork getWirelessNetwork(MinecraftServer server) { * This may be used with {@link IComputerSystem#getComponent(ComputerComponent)} to only attach APIs to specific * computers. For example, one can add an additional API just to turtles with the following code: * - *

{@code
+     * 
{@code
      * ComputerCraftAPI.registerAPIFactory(computer -> {
      *   // Read the turtle component.
      *   var turtle = computer.getComponent(ComputerComponents.TURTLE);
diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeSerialiser.java b/projects/common-api/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeSerialiser.java
index 863f36fa0a..6f9d2a7af9 100644
--- a/projects/common-api/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeSerialiser.java
+++ b/projects/common-api/src/main/java/dan200/computercraft/api/turtle/TurtleUpgradeSerialiser.java
@@ -28,7 +28,7 @@
  * {@link #simple(Function)} or {@link #simpleWithCustomItem(BiFunction)} to create a basic upgrade serialiser.
  *
  * 

Example (Forge)

- *
{@code
+ * 
{@code
  * static final DeferredRegister> SERIALISERS = DeferredRegister.create( TurtleUpgradeSerialiser.TYPE, "my_mod" );
  *
  * // Register a new upgrade serialiser called "my_upgrade".
@@ -42,9 +42,9 @@
  * We can then define a new upgrade using JSON by placing the following in
  * {@literal data//computercraft/turtle_upgrades/.json}}.
  *
- * 
{@code
+ * 
{@code
  * {
- *     "type": my_mod:my_upgrade",
+ *     "type": "my_mod:my_upgrade",
  * }
  * }
*

diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeDataProvider.java b/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeDataProvider.java index eae2be3d58..b405a1cf6b 100644 --- a/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeDataProvider.java +++ b/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeDataProvider.java @@ -86,7 +86,7 @@ public final Upgrade simpleWithCustomItem(ResourceLocation id, R serialiser, * Add all turtle or pocket computer upgrades. *

* Example usage: - *

{@code
+     * 
{@code
      * protected void addUpgrades(Consumer>> addUpgrade) {
      *     simple(new ResourceLocation("mymod", "speaker"), SPEAKER_SERIALISER.get()).add(addUpgrade);
      * }
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/lua/Coerced.java b/projects/core-api/src/main/java/dan200/computercraft/api/lua/Coerced.java
index 50b40bcdfa..1af2cda211 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/lua/Coerced.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/lua/Coerced.java
@@ -11,7 +11,7 @@
  * the given type, rather than requiring an exact type.
  *
  * 

Example:

- *
{@code
+ * 
{@code
  * @LuaFunction
  * public final void doSomething(Coerced myString) {
  *   var value = myString.value();
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/lua/GenericSource.java b/projects/core-api/src/main/java/dan200/computercraft/api/lua/GenericSource.java
index 99c8493bf0..09b8ff9d68 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/lua/GenericSource.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/lua/GenericSource.java
@@ -21,9 +21,9 @@
  * 

* For example, the main CC: Tweaked mod defines a generic source for inventories, which works on {@code IItemHandler}s: * - *

{@code
+ * 
{@code
  * public class InventoryMethods implements GenericSource {
- *     \@LuaFunction(mainThread = true)
+ *     @LuaFunction(mainThread = true)
  *     public int size(IItemHandler inventory) {
  *         return inventory.getSlots();
  *     }
diff --git a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/AttachedComputerSet.java b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/AttachedComputerSet.java
index aef0ec0354..e5fcd589b4 100644
--- a/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/AttachedComputerSet.java
+++ b/projects/core-api/src/main/java/dan200/computercraft/api/peripheral/AttachedComputerSet.java
@@ -27,7 +27,7 @@
  *
  * 

Example

* - *
{@code
+ * 
{@code
  * public class MyPeripheral implements IPeripheral {
  *     private final AttachedComputerSet computers = new ComputerCollection();
  *

From f39e86bb10a94b6a9d4e0a7e8673ef115c018618 Mon Sep 17 00:00:00 2001
From: Jonathan Coates 
Date: Thu, 14 Nov 2024 11:01:23 +0000
Subject: [PATCH 26/39] Bump NeoGradle version

This uses a shared asset directory (previously it was per-version), so
much more disk friendly.
---
 gradle/libs.versions.toml                |   2 +-
 gradle/wrapper/gradle-wrapper.jar        | Bin 43504 -> 43583 bytes
 gradle/wrapper/gradle-wrapper.properties |   2 +-
 projects/forge/build.gradle.kts          |   4 ++--
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index e5b6c2fd26..47433d5ec7 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -69,7 +69,7 @@ ideaExt = "1.1.7"
 illuaminate = "0.1.0-73-g43ee16c"
 lwjgl = "3.3.3"
 minotaur = "2.8.7"
-neoGradle = "7.0.152"
+neoGradle = "7.0.170"
 nullAway = "0.10.25"
 shadow = "8.3.1"
 spotless = "6.23.3"
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 2c3521197d7c4586c843d1d3e9090525f1898cde..a4b76b9530d66f5e68d973ea569d8e19de379189 100644
GIT binary patch
delta 3990
zcmV;H4{7l5(*nQL0Kr1kzC=_KMxQY0|W5(lc#i
zH*M1^P4B}|{x<+fkObwl)u#`$GxKKV&3pg*-y6R6txw)0qU|Clf9Uds3x{_-**c=7
z&*)~RHPM>Rw#Hi1R({;bX|7?J@w}DMF>dQQU2}9yj%iLjJ*KD6IEB2^n#gK7M~}6R
zkH+)bc--JU^pV~7W=3{E*4|ZFpDpBa7;wh4_%;?XM-5ZgZNnVJ=vm!%a2CdQb?oTa
z70>8rTb~M$5Tp!Se+4_OKWOB1LF+7gv~$$fGC95ToUM(I>vrd$>9|@h=O?eARj0MH
zT4zo(M>`LWoYvE>pXvqG=d96D-4?VySz~=tPVNyD$XMshoTX(1ZLB5OU!I2OI{kb)
zS8$B8Qm>wLT6diNnyJZC?yp{Kn67S{TCOt-!OonOK7$K)e-13U9GlnQXPAb&SJ0#3
z+vs~+4Qovv(%i8g$I#FCpCG^C4DdyQw3phJ(f#y*pvNDQCRZ~MvW<}fUs~PL=4??j
zmhPyg<*I4RbTz|NHFE-DC7lf2=}-sGkE5e!RM%3ohM7_I^IF=?O{m*uUPH(V?gqyc(Rp?-Qu(3bBIL4Fz(v?=_Sh?LbK{nqZMD>#9D_hNhaV$0ef3@9V90|0u#|PUNTO>$F=qRhg1duaE
z0`v~X3G{8RVT@kOa-pU+z8{JWyP6GF*u2e8eKr7a2t1fuqQy)@d|Qn(%YLZ62TWtoX@$nL}9?atE#Yw`rd(>cr0gY;dT9~^oL;u)zgHUvxc2I*b&ZkGM-iq=&(?kyO(3}=P!
zRp=rErEyMT5UE9GjPHZ#T<`cnD)jyIL!8P{H@IU#`e8cAG5jMK
zVyKw7--dAC;?-qEu*rMr$5@y535qZ6p(R#+fLA_)G~!wnT~~)|s`}&fA(s6xXN`9j
zP#Fd3GBa#HeS{5&8p?%DKUyN^X9cYUc6vq}D_3xJ&d@=6j(6BZKPl?!k1?!`f3z&a
zR4ZF60Mx7oBxLSxGuzA*Dy5n-d2K=+)6VMZh_0KetK|{e;E{8NJJ!)=_E~1uu=A=r
zrn&gh)h*SFhsQJo!f+wKMIE;-EOaMSMB@aXRU(UcnJhZW^B^mgs|M9@5WF@s6B0p&
zm#CTz)yiQCgURE{%hjxHcJ6G&>G9i`7MyftL!QQd5
z@RflRs?7)99?X`kHNt>W3l7YqscBpi*R2+fsgABor>KVOu(i(`03aytf2UA!&SC9v
z!E}whj#^9~=XHMinFZ;6UOJjo=mmNaWkv~nC=qH9$s-8roGeyaW-E~SzZ3Gg>j
zZ8}<320rg4=$`M0nxN!w(PtHUjeeU?MvYgWKZ6kkzABK;vMN0|U;X9abJleJA(xy<}5h5P(5
z{RzAFPvMnX2m0yH0Jn2Uo-p`daE|(O`YQiC#jB8;6bVIUf?SY(k$#C0`d6qT`>Xe0+0}Oj0=F&*D;PVe=Z<=0AGI<6$gYLwa#r`
zm449x*fU;_+J>Mz!wa;T-wldoBB%&OEMJgtm#oaI60TSYCy7;+$5?q!zi5K`u66Wq
zvg)Fx$s`V3Em{=OEY{3lmh_7|08ykS&U9w!kp@Ctuzqe1JFOGz6%i5}Kmm9>^=gih
z?kRxqLA<3@e=}G4R_?phW{4DVr?`tPfyZSN@R=^;P;?!2bh~F1I|fB7P=V=9a6XU5
z<#0f>RS0O&rhc&nTRFOW7&QhevP0#>j0eq<1@D5yAlgMl5n&O9X|Vq}%RX}iNyRFF
z7sX&u#6?E~bm~N|z&YikXC=I0E*8Z$v7PtWfjy)$e_Ez25fnR1Q=q1`;U!~U>|&YS
zaOS8y!^ORmr2L4ik!IYR8@Dcx8MTC=(b4P6iE5CnrbI~7j7DmM8em$!da&D!6Xu)!vKPdLG
z9f#)se|6=5yOCe)N6xDhPI!m81*dNe7u985zi%IVfOfJh69+#ag4ELzGne?o`eA`42K4T)h3S+s)5IT97%O>du-
z0U54L8m4}rkRQ?QBfJ%DLssy^+a7Ajw;0&`NOTY4o;0-ivm9
zBz1C%nr_hQ)X)^QM6T1?=yeLkuG9Lf50(eH}`tFye;01&(p?8i+6h};VV-2B~qdxeC#=X
z(JLlzy&fHkyi9Ksbcs~&r^%lh^2COldLz^H@X!s~mr9Dr6z!j+4?zkD@Ls7F8(t(f
z9`U?P$Lmn*Y{K}aR4N&1N=?xtQ1%jqf1~pJyQ4SgBrEtR`j4lQuh7cqP49Em5cO=I
zB(He2`iPN5M=Y0}h(IU$37ANTGx&|b-u1BYA*#dE(L-lptoOpo&th~E)_)y-`6kSH
z3vvyVrcBwW^_XYReJ=JYd9OBQrzv;f2AQdZH#$Y{Y+Oa33M70XFI((fs;mB4e`<<{
ze4dv2B0V_?Ytsi>>g%qs*}oDGd5d(RNZ*6?7qNbdp7wP4T72=F&r?Ud#kZr8Ze5tB
z_oNb7{G+(o2ajL$!69FW@jjPQ2a5C)m!MKKRirC$_VYIuVQCpf9rIms0GRDf)8AH${I`q^~5rjot@#3$2#zT2f`(N^P7Z;6(@EK$q*Jgif00I6*^ZGV+XB5uw*1R-@23yTw&WKD{s1;HTL;dO)%5i#`dc6b7;5@^{KU%N|A-$zsYw4)7LA{3`Zp>1
z-?K9_IE&z)dayUM)wd8K^29m-l$lFhi$zj0l!u~4;VGR6Y!?MAfBC^?QD53hy6VdD
z@eUZIui}~L%#SmajaRq1J|#>
z4m=o$vZ*34=ZWK2!QMNEcp2Lbc5N1q!lEDq(bz0b;WI9;e>l=CG9^n#ro`w>_0F$Q
zfZ={2QyTkfByC&gy;x!r*NyXXbk=a%~~(#K?<
zTke0HuF5{Q+~?@!KDXR|g+43$+;ab`^flS%miup_0OUTm=nIc%d5nLP)i308PIjl_YMF6cpQ__6&$n6it8K-
z8PIjl_YMF6cpQ_!r)L8IivW`WdK8mBs6PXdjR2DYdK8nCs73=4j{uVadK8oNjwX|E
wpAeHLsTu^*Y>Trk?aBtSQ(D-o$(D8Px^?ZI-PUB?
z*1fv!{YdHme3Fc8%cR@*@zc5A_nq&2=R47Hp@$-JF4Fz*;SLw5}K^y>s-s;V!}b2i=5=M-
zComP?ju>8Fe@=H@rlwe1l`J*6BTTo`9b$zjQ@HxrAhp0D#u?M~TxGC_!?ccCHCjt|
zF*PgJf@kJB`|Ml}cmsyrAjO#Kjr^E5p29w+#>$C`Q|54BoDv$fQ9D?3n32P9LPMIzu?LjNqggOH=1@T{9bMn*u8(GI
z!;MLTtFPHal^S>VcJdiYqX0VU|Rn@A}C1xOlxCribxes0~+n2
z6qDaIA2$?e`opx3_KW!rAgbpzU)gFdjAKXh|5w``#F0R|c)Y)Du0_Ihhz^S?k^pk%
zP>9|pIDx)xHH^_~+aA=^$M!<8K~Hy(71nJGf6`HnjtS=4X4=Hk^O71oNia2V{HUCC
zoN3RSBS?mZCLw;l4W4a+D8qc)XJS`pUJ5X-f^1ytxwr`@si$lAE?{4G|o;
zO0l>`rr?;~c;{ZEFJ!!3=7=FdGJ?Q^xfNQh4A?i;IJ4}B+A?4olTK(fN++3CRBP97
ze~lG9h%oegkn)lpW-4F8o2`*WW0mZHwHez`ko@>U1_;EC_6ig|Drn@=DMV9YEUSCa
zIf$kHei3(u#zm9I!Jf(4t`Vm1lltJ&lVHy(eIXE8sy9sUpmz%I_gA#8x^Zv8%w?r2
z{GdkX1SkzRIr>prRK@rqn9j2wG|rUvf6PJbbin=yy-TAXrguvzN8jL$hUrIXzr^s5
zVM?H4;eM-QeRFr06@ifV(ocvk?_)~N@1c2ien56UjWXid6W%6ievIh)>dk|rIs##^kY67ib8Kw%#-oVFaXG7$ERyA9(NSJUvWiOA5H(!{uOpcW
zg&-?iqPhds%3%tFspHDqqr;A!e@B#iPQjHd=c>N1LoOEGRehVoPOdxJ>b6>yc#o#+
zl8s8!(|NMeqjsy@0x{8^j0d00SqRZjp{Kj)&4UHYGxG+z9b-)72I*&J70?+8e?p_@
z=>-(>l6z5vYlP~<2%DU02b!mA{7mS)NS_eLe=t)sm&+Pmk?asOEKlkPQ)EUvvfC=;4M&*|I!w}(@V_)eUKLA_t^%`o
z0PM9LV|UKTLnk|?M3u!|f2S0?UqZsEIH9*NJS-8lzu;A6-rr-ot=dg9SASoluZUkFH$7X;
zP=?kYX!K?JL-b~<#7wU;b;eS)O;@?h%sPPk{4xEBxb{!sm0AY|f9cNvx6>$3F!*0c
z75H=dy8JvTyO8}g1w{$9T$p~5en}AeSLoCF>_RT9YPMpChUjl310o*$QocjbH&
zbnwg#gssR#jDVN{uEi3n(PZ%PFZ|6J2
z5_rBf0-u>e4sFe0*Km49ATi7>Kn0f9!uc|rRMR1Dtt6m1LW8^>qFlo}h$@br=Rmpi
z;mI&>OF64Be{dVeHI8utrh)v^wsZ0jii%x8UgZ8TC%K~@I(4E};GFW&(;WVov}3%H
zH;IhRkfD^(vt^DjZz(MyHLZxv8}qzPc(%itBkBwf_fC~sDBgh<3XAv5cxxfF3<2U!
z03Xe&z`is!JDHbe;mNmfkH+_LFE*I2^mdL@7(@9DfAcP6O04V-ko;Rpgp<%Cj5r8Z
zd0`sXoIjV$j)--;jA6Zy^D5&5v$o^>e%>Q?9GLm{i~p^lAn!%ZtF$I~>39XVZxk0b
zROh^Bk9cE0AJBLozZIEmy7xG(yHWGztvfnr0(2ro1%>zsGMS^EMu+S$r=_;9
zWwZkgf7Q7`H9sLf2Go^Xy6&h~a&%s2_T@_Csf19MntF$aVFiFkvE3_hUg(B@&Xw@YJ
zpL$wNYf78=0c@!QU6_a$>CPiXT7QAGDM}7Z(0z#_ZA=fmLUj{2z7@Ypo71UDy8GHr
z-&TLKf6a5WCf@Adle3VglBt4>Z>;xF}}-S~B7<(%B;Y
z0QR55{z-buw>8ilNM3u6I+D$S%?)(p>=eBx-HpvZj{7c*_?K=d()*7q?93us}1dq%FAFYLsW8ZTQ_XZLh`P2*6(NgS}qGcfGXVWpwsp#Rs}IuKbk*`2}&)
zI^Vsk6S&Q4@oYS?dJ`NwMVBs6f57+RxdqVub#PvMu?$=^OJy5xEl0<5SLsSRy%%a0
zi}Y#1-F3m;Ieh#Y12UgW?-R)|eX>ZuF-2cc!1>~NS|XSF-6In>zBoZg+ml!6%fk7U
zw0LHcz8VQk(jOJ+Yu)|^|15ufl$KQd_1eUZZzj`aC%umU6F1&D5XVWce_wAe(qCSZ
zpX-QF4e{EmEVN9~6%bR5U*UT{eMHfcUo`jw*u?4r2s_$`}U{?NjvEm(u&<>B|%mq$Q3weshxk
z76<``8vh{+nX`@9CB6IE&z)I%IFjR^LH{s1p|eppv=x
za(g_jLU|xjWMAn-V7th$f({|LG8zzIE0g?cyW;%Dmtv%C+0@xVxPE^
zyZzi9P%JAD6ynwHptuzP`Kox7*9h7XSMonCalv;Md0i9Vb-c*!f0ubfk?&T&T}AHh
z4m8Bz{JllKcdNg?D^%a5MFQ;#1z|*}H^qHLzW)L}wp?2tY7RejtSh8<;Zw)QGJYUm
z|MbTxyj*McKlStlT9I5XlSWtQGN&-LTr2XyNU+`490rg?LYLMRnz-@oKqT1hpCGqP
zyRXt4=_Woj$%n5ee<3zhLF>5>`?m9a#xQH+Jk_+|RM8Vi;2*XbK-
zEL6sCpaGPzP>k8f4Kh|##_imt#zJMB;ir|JrMPGW`rityK1vHXMLy18%qmMQAm4WZ
zP)i30KR&5vs15)C+8dM66&$k~i|ZT;KR&5vs15)C+8dJ(sAmGPijyIz6_bsqKLSFH
zlOd=TljEpH0>h4zA*dCTK&emy#FCRCs1=i^sZ9bFmXjf<6_X39E(XY)00000#N437

diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 9355b41557..df97d72b8b 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
 networkTimeout=10000
 validateDistributionUrl=true
 zipStoreBase=GRADLE_USER_HOME
diff --git a/projects/forge/build.gradle.kts b/projects/forge/build.gradle.kts
index 2b8f2feda0..343de48e27 100644
--- a/projects/forge/build.gradle.kts
+++ b/projects/forge/build.gradle.kts
@@ -54,12 +54,12 @@ runs {
 
     val server by registering {
         workingDirectory(file("run/server"))
-        programArgument("--nogui")
+        argument("--nogui")
     }
 
     val data by registering {
         workingDirectory(file("run"))
-        programArguments.addAll(
+        arguments.addAll(
             "--mod", "computercraft", "--all",
             "--output", layout.buildDirectory.dir("generatedResources").getAbsolutePath(),
             "--existing", project(":common").file("src/main/resources/").absolutePath,

From 0c8e75731405c8354af68114d9bd7c37b51258fd Mon Sep 17 00:00:00 2001
From: Jonathan Coates 
Date: Fri, 15 Nov 2024 07:31:49 +0000
Subject: [PATCH 27/39] Several cleanup to turtle crafting upgrade

 - Don't construct a fake player when crafting: vanilla now has its own
   automated crafting, so no longer requires the presence of a player.

 - Fix remainder stack not being set in some situations. Closes #2007.
---
 .../shared/platform/PlatformHelper.java       | 22 -------------------
 .../turtle/core/TurtleCraftCommand.java       |  1 +
 .../upgrades/TurtleInventoryCrafting.java     | 14 ++++--------
 .../computercraft/TestPlatformHelper.java     | 12 ----------
 .../shared/platform/PlatformHelperImpl.java   | 11 ----------
 .../shared/platform/PlatformHelperImpl.java   | 16 --------------
 6 files changed, 5 insertions(+), 71 deletions(-)

diff --git a/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java b/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java
index 2892a8c8e2..c80f3f1fcd 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/platform/PlatformHelper.java
@@ -33,8 +33,6 @@
 import net.minecraft.world.item.DyeColor;
 import net.minecraft.world.item.Item;
 import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.item.crafting.CraftingInput;
-import net.minecraft.world.item.crafting.Recipe;
 import net.minecraft.world.level.Level;
 import net.minecraft.world.level.block.entity.BlockEntity;
 import net.minecraft.world.level.block.state.BlockState;
@@ -216,26 +214,6 @@ default void invalidateComponent(BlockEntity owner) {
      */
     ItemStack getCraftingRemainingItem(ItemStack stack);
 
-    /**
-     * A more general version of {@link #getCraftingRemainingItem(ItemStack)} which gets all remaining items for a
-     * recipe.
-     *
-     * @param player    The player performing the crafting.
-     * @param recipe    The recipe currently doing the crafting.
-     * @param container The crafting container.
-     * @return A list of items to return to the player after crafting.
-     */
-    List getRecipeRemainingItems(ServerPlayer player, Recipe recipe, CraftingInput container);
-
-    /**
-     * Fire an event after crafting has occurred.
-     *
-     * @param player    The player performing the crafting.
-     * @param container The current crafting container.
-     * @param stack     The resulting stack from crafting.
-     */
-    void onItemCrafted(ServerPlayer player, CraftingInput container, ItemStack stack);
-
     /**
      * Check whether we should notify neighbours in a particular direction.
      *
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCraftCommand.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCraftCommand.java
index 015c74168f..67e6a4a15b 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCraftCommand.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleCraftCommand.java
@@ -26,6 +26,7 @@ public TurtleCommandResult execute(ITurtleAccess turtle) {
 
         // Store or drop any remainders
         for (var stack : results) TurtleUtil.storeItemOrDrop(turtle, stack);
+        turtle.getInventory().setChanged();
 
         if (!results.isEmpty()) turtle.playAnimation(TurtleAnimation.WAIT);
         return TurtleCommandResult.success();
diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java
index 1e66b71af3..594bef5732 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleInventoryCrafting.java
@@ -5,9 +5,7 @@
 package dan200.computercraft.shared.turtle.upgrades;
 
 import dan200.computercraft.api.turtle.ITurtleAccess;
-import dan200.computercraft.shared.platform.PlatformHelper;
 import dan200.computercraft.shared.turtle.blocks.TurtleBlockEntity;
-import dan200.computercraft.shared.turtle.core.TurtlePlayer;
 import net.minecraft.server.level.ServerLevel;
 import net.minecraft.world.Container;
 import net.minecraft.world.item.ItemStack;
@@ -82,18 +80,15 @@ public static List craft(ITurtleAccess turtle, int maxCount) {
         var xStart = candidate.xStart();
         var yStart = candidate.yStart();
 
-        var player = TurtlePlayer.get(turtle).player();
-
         var results = new ArrayList();
         for (var i = 0; i < maxCount && recipe.matches(input, level); i++) {
             var result = recipe.assemble(input, level.registryAccess());
             if (result.isEmpty()) break;
             results.add(result);
 
-            result.onCraftedBy(level, player, result.getCount());
-            PlatformHelper.get().onItemCrafted(player, input, result);
+            result.onCraftedBySystem(level);
 
-            var remainders = PlatformHelper.get().getRecipeRemainingItems(player, recipe, input);
+            var remainders = recipe.getRemainingItems(input);
             for (var y = 0; y < input.height(); y++) {
                 for (var x = 0; x < input.width(); x++) {
                     var slot = xStart + x + (y + yStart) * TurtleBlockEntity.INVENTORY_WIDTH;
@@ -110,10 +105,9 @@ public static List craft(ITurtleAccess turtle, int maxCount) {
                     // Either update the current stack or add it to the remainder list (to be inserted into the inventory
                     // afterwards).
                     if (existing.isEmpty()) {
-                        inventory.setItem(slot, existing);
-                    } else if (ItemStack.isSameItemSameComponents(existing, remainder)) {
-                        remainder.grow(existing.getCount());
                         inventory.setItem(slot, remainder);
+                    } else if (ItemStack.isSameItemSameComponents(existing, remainder)) {
+                        existing.grow(remainder.getCount());
                     } else {
                         results.add(remainder);
                     }
diff --git a/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java b/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java
index fae335b787..6636304bc3 100644
--- a/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java
+++ b/projects/common/src/test/java/dan200/computercraft/TestPlatformHelper.java
@@ -34,8 +34,6 @@
 import net.minecraft.world.item.CreativeModeTab;
 import net.minecraft.world.item.Item;
 import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.item.crafting.CraftingInput;
-import net.minecraft.world.item.crafting.Recipe;
 import net.minecraft.world.level.Level;
 import net.minecraft.world.level.block.entity.BlockEntity;
 import net.minecraft.world.level.block.state.BlockState;
@@ -160,16 +158,6 @@ public ContainerTransfer getContainer(ServerLevel level, BlockPos pos, Direction
         throw new UnsupportedOperationException("Cannot interact with the world inside tests");
     }
 
-    @Override
-    public List getRecipeRemainingItems(ServerPlayer player, Recipe recipe, CraftingInput container) {
-        throw new UnsupportedOperationException("Cannot query recipes inside tests");
-    }
-
-    @Override
-    public void onItemCrafted(ServerPlayer player, CraftingInput container, ItemStack stack) {
-        throw new UnsupportedOperationException("Cannot interact with the world inside tests");
-    }
-
     @Override
     public String getInstalledVersion() {
         return "1.0";
diff --git a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java
index 35568523dc..0c770ea5ef 100644
--- a/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java
+++ b/projects/fabric/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java
@@ -55,9 +55,7 @@
 import net.minecraft.world.inventory.MenuType;
 import net.minecraft.world.item.*;
 import net.minecraft.world.item.context.UseOnContext;
-import net.minecraft.world.item.crafting.CraftingInput;
 import net.minecraft.world.item.crafting.Ingredient;
-import net.minecraft.world.item.crafting.Recipe;
 import net.minecraft.world.level.Level;
 import net.minecraft.world.level.block.entity.BlockEntity;
 import net.minecraft.world.level.block.state.BlockState;
@@ -197,15 +195,6 @@ public ItemStack getCraftingRemainingItem(ItemStack stack) {
         return stack.getRecipeRemainder();
     }
 
-    @Override
-    public List getRecipeRemainingItems(ServerPlayer player, Recipe recipe, CraftingInput container) {
-        return recipe.getRemainingItems(container);
-    }
-
-    @Override
-    public void onItemCrafted(ServerPlayer player, CraftingInput container, ItemStack stack) {
-    }
-
     @Override
     public boolean onNotifyNeighbour(Level level, BlockPos pos, BlockState block, Direction direction) {
         return true;
diff --git a/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java b/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java
index d0698b5769..c6d5bc27f4 100644
--- a/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java
+++ b/projects/forge/src/main/java/dan200/computercraft/shared/platform/PlatformHelperImpl.java
@@ -15,7 +15,6 @@
 import dan200.computercraft.api.peripheral.PeripheralCapability;
 import dan200.computercraft.impl.Peripherals;
 import dan200.computercraft.shared.config.ConfigFile;
-import dan200.computercraft.shared.container.ListContainer;
 import dan200.computercraft.shared.network.container.ContainerData;
 import dan200.computercraft.shared.util.InventoryUtil;
 import net.minecraft.commands.synchronization.ArgumentTypeInfo;
@@ -42,9 +41,7 @@
 import net.minecraft.world.item.Item;
 import net.minecraft.world.item.ItemStack;
 import net.minecraft.world.item.context.UseOnContext;
-import net.minecraft.world.item.crafting.CraftingInput;
 import net.minecraft.world.item.crafting.Ingredient;
-import net.minecraft.world.item.crafting.Recipe;
 import net.minecraft.world.level.Level;
 import net.minecraft.world.level.block.entity.BlockEntity;
 import net.minecraft.world.level.block.state.BlockState;
@@ -192,19 +189,6 @@ public ItemStack getCraftingRemainingItem(ItemStack stack) {
         return stack.getCraftingRemainingItem();
     }
 
-    @Override
-    public List getRecipeRemainingItems(ServerPlayer player, Recipe recipe, CraftingInput container) {
-        CommonHooks.setCraftingPlayer(player);
-        var result = recipe.getRemainingItems(container);
-        CommonHooks.setCraftingPlayer(null);
-        return result;
-    }
-
-    @Override
-    public void onItemCrafted(ServerPlayer player, CraftingInput container, ItemStack stack) {
-        EventHooks.firePlayerCraftingEvent(player, stack, new ListContainer(container.items()));
-    }
-
     @Override
     public boolean onNotifyNeighbour(Level level, BlockPos pos, BlockState block, Direction direction) {
         return !EventHooks.onNeighborNotify(level, pos, block, EnumSet.of(direction), false).isCanceled();

From 9b19a93ab9f6420f94f6e1c8f7ac004bf0cf2c98 Mon Sep 17 00:00:00 2001
From: Jonathan Coates 
Date: Fri, 15 Nov 2024 08:14:06 +0000
Subject: [PATCH 28/39] Sync translations from Crowdin

Ended up writing my own janky script to do this, rather than use the GH
integration. I'm not proud of this, but it works.
---
 .../cc/tweaked/gradle/CCTweakedExtension.kt   |   2 +-
 .../assets/computercraft/lang/de_de.json      |  20 +--
 .../assets/computercraft/lang/es_es.json      | 165 ++++++++++++++++++
 .../assets/computercraft/lang/it_it.json      |  16 --
 .../assets/computercraft/lang/nb_no.json      |   9 -
 .../assets/computercraft/lang/pt_br.json      | 152 ++++++++++++++++
 .../assets/computercraft/lang/uk_ua.json      |   8 +
 7 files changed, 336 insertions(+), 36 deletions(-)

diff --git a/buildSrc/src/main/kotlin/cc/tweaked/gradle/CCTweakedExtension.kt b/buildSrc/src/main/kotlin/cc/tweaked/gradle/CCTweakedExtension.kt
index 09be926cb8..70b3d1f3e9 100644
--- a/buildSrc/src/main/kotlin/cc/tweaked/gradle/CCTweakedExtension.kt
+++ b/buildSrc/src/main/kotlin/cc/tweaked/gradle/CCTweakedExtension.kt
@@ -269,7 +269,7 @@ abstract class CCTweakedExtension(
     companion object {
         private val COMMIT_COUNTS = Pattern.compile("""^\s*[0-9]+\s+(.*)$""")
         private val IGNORED_USERS = setOf(
-            "GitHub", "Daniel Ratcliffe", "Weblate",
+            "GitHub", "Daniel Ratcliffe", "NotSquidDev", "Weblate",
         )
 
         private fun  gitProvider(project: Project, default: T, supplier: () -> T): Provider {
diff --git a/projects/common/src/main/resources/assets/computercraft/lang/de_de.json b/projects/common/src/main/resources/assets/computercraft/lang/de_de.json
index 83093dba96..c18c52d8bc 100644
--- a/projects/common/src/main/resources/assets/computercraft/lang/de_de.json
+++ b/projects/common/src/main/resources/assets/computercraft/lang/de_de.json
@@ -1,13 +1,13 @@
 {
     "argument.computercraft.argument_expected": "Parameter erwartet",
-    "argument.computercraft.computer.family": "Computerfamilie",
+    "argument.computercraft.computer.family": "Computer familie",
     "argument.computercraft.computer.id": "Computer ID",
     "argument.computercraft.computer.instance": "einzigartige Instanz ID",
-    "argument.computercraft.computer.label": "Computername",
+    "argument.computercraft.computer.label": "Computer name",
     "argument.computercraft.computer.many_matching": "Mehrere Computer passen auf '%s' (Instanzen %s)",
     "argument.computercraft.computer.no_matching": "Kein Computer passt auf '%s'",
     "argument.computercraft.tracking_field.no_field": "Unbekanntes Feld '%s'",
-    "argument.computercraft.unknown_computer_family": "Unbekannte Computerfamilie '%s'",
+    "argument.computercraft.unknown_computer_family": "Unbekannte computer familie '%s'",
     "block.computercraft.cable": "Netzwerkkabel",
     "block.computercraft.computer_advanced": "Erweiterter Computer",
     "block.computercraft.computer_command": "Befehlscomputer",
@@ -60,7 +60,7 @@
     "commands.computercraft.track.start.stop": "Führe %s aus um die Aufzeichnung zu stoppen und die Ergebnisse anzusehen",
     "commands.computercraft.track.start.synopsis": "Startet die Aufzeichnung von Computern",
     "commands.computercraft.track.stop.action": "Klicke um die Aufzeichnung zu stoppen",
-    "commands.computercraft.track.stop.desc": "Stopt die Aufzeichnung aller Computer-Events und Laufzeiten",
+    "commands.computercraft.track.stop.desc": "Stopt die Aufzeichnung aller Computer Events und Laufzeiten",
     "commands.computercraft.track.stop.not_enabled": "Momentan werden keine Computer aufgezeichnet",
     "commands.computercraft.track.stop.synopsis": "Stoppt die Aufzeichnung aller Computer",
     "commands.computercraft.track.synopsis": "Zeichnet die Laufzeiten von Computern auf.",
@@ -78,22 +78,22 @@
     "gui.computercraft.config.default_computer_settings": "Computer-Standardeinstellungen",
     "gui.computercraft.config.default_computer_settings.tooltip": "eine mit Komma separierte Liste an standardmäßige Systemeinstellungen für neuen Computern.\nBeispiel: \"shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false\"\nwürde jegliche Autovervollständigung deaktivieren.",
     "gui.computercraft.config.disabled_generic_methods": "Generische Methoden deaktiviert.",
-    "gui.computercraft.config.disabled_generic_methods.tooltip": "Eine Liste an generischen Methoden oder Methodenquellen zum deaktivieren.\nGenerische Methoden sind Methoden die zu einem Block oder Blockentity hinzugefügt werden, insofern kein expliziter Peripheral Provider\ngefunden wurde. Mitbetroffen sind Inventarmethoden (d.h. inventory.getItemDetail,\ninventory.pushItems) und, wenn in Forge gespielt wird, die fluid_storage und energy_storage\nMethoden.\nMethoden in dieser Liste können entweder Gruppen von Methoden (wie computercraft:inventory)\noder einzelne Methoden (wie computercraft:inventory#pushItems) sein.\n",
+    "gui.computercraft.config.disabled_generic_methods.tooltip": "Eine Liste an generischen Methoden oder Methodenquellen zum deaktivieren.\nGenerische Methoden sind Methoden die zu einem block/block entity hinzugefügt werden, insofern kein expliziter Peripheral Provider\ngefunden wurde. Mitbetroffen sind Inventarmethoden (d.h. inventory.getItemDetail,\ninventory.pushItems) und, wenn in Forge gespielt wird, die fluid_storage und energy_storage\nMethoden.\nMethoden in dieser Liste können entweder Gruppen von Methoden (wie computercraft:inventory)\noder einzelne Methoden (wie computercraft:inventory#pushItems) sein.\n",
     "gui.computercraft.config.execution": "Ausführung",
     "gui.computercraft.config.execution.computer_threads": "Computer Threads",
     "gui.computercraft.config.execution.computer_threads.tooltip": "Setzt die Anzahl an Hintergrundprozessen fest, auf denen Computer laufen können. Eine hohe Nummer heißt,\ndass mehrere Computer zur selben Zeit laufen können, jedoch aber auch ggf. mehr Verzögerungen verursachen. Bitte beachte, dass manche mods\nnicht mit einer Anzahl an Hintergrundprozessen laufen, die höher als 1 ist. Benutze also mit bedacht.\nBereich: > 1",
     "gui.computercraft.config.execution.max_main_computer_time": "Computer Servertick Zeitlimit",
     "gui.computercraft.config.execution.max_main_computer_time.tooltip": "Die ideale maximale Zeit, in der ein Computer laufen kann im innerhalb von einem tick in Millisekunden.\nBeachte, dass wir wahrscheinlich über diesen Limit gehen werden, da es unmöglich ist zu bestimmen,\nwie lange ein Computer brauchen wird. Dies wird also die höhere Grenze der durchschnittlichen Zeit darstellen.\nBereich: > 1",
     "gui.computercraft.config.execution.max_main_global_time": "Globales Servertick Zeitlimit",
-    "gui.computercraft.config.execution.max_main_global_time.tooltip": "Die maximale Zeit in Millisekunden, in der Aufgaben ausgeführt werden.\nAnmerkung: Diese Zeit wird höchstwarscheinlich überschritten und dient nur als ungefähre Grenze.\nLimit: > 1",
+    "gui.computercraft.config.execution.max_main_global_time.tooltip": "Die maximale Zeit in millisekunden, in der Aufgaben ausgeführt werden.\nAnmerkung: Diese Zeit wird höchstwarscheinlich überschritten und dient nur als ungefähre Grenze.\nLimit: > 1",
     "gui.computercraft.config.floppy_space_limit": "Speicherplatz von Disketten (Bytes)",
     "gui.computercraft.config.floppy_space_limit.tooltip": "Die maximale Dateisystem Größe von Disketten (in bytes).",
     "gui.computercraft.config.http": "HTTP",
     "gui.computercraft.config.http.bandwidth": "Bandbreite",
-    "gui.computercraft.config.http.bandwidth.global_download": "Globale Downloadbandbreite",
-    "gui.computercraft.config.http.bandwidth.global_download.tooltip": "Die maximale Bandbreite aller Computer in bytes/s mit der heruntergeladen werden kann.\nBereich: > 1",
-    "gui.computercraft.config.http.bandwidth.global_upload": "Globale Uploadbandbreite",
-    "gui.computercraft.config.http.bandwidth.global_upload.tooltip": "Die maximale Bandbreite aller Computer in bytes/s mit der hochgeladen werden kann.\nBereich: > 1",
+    "gui.computercraft.config.http.bandwidth.global_download": "Globales download limit",
+    "gui.computercraft.config.http.bandwidth.global_download.tooltip": "Die maximale Geschwindigkeit aller Computer in bytes/s mit der Heruntergeladen werden kann.\nBereich: > 1",
+    "gui.computercraft.config.http.bandwidth.global_upload": "Globales upload limit",
+    "gui.computercraft.config.http.bandwidth.global_upload.tooltip": "Die maximale Hochladungs Geschwindigkeit aller Computer in bytes/s.\nBereich: > 1",
     "gui.computercraft.config.http.bandwidth.tooltip": "Limitiert die Bandbreite der Computer.",
     "gui.computercraft.config.http.enabled": "HTTP-API aktivieren",
     "gui.computercraft.config.http.max_requests": "Maximale Anzahl gleichzeitiger Anfragen",
diff --git a/projects/common/src/main/resources/assets/computercraft/lang/es_es.json b/projects/common/src/main/resources/assets/computercraft/lang/es_es.json
index 510805689a..e3f06e0be7 100644
--- a/projects/common/src/main/resources/assets/computercraft/lang/es_es.json
+++ b/projects/common/src/main/resources/assets/computercraft/lang/es_es.json
@@ -1,6 +1,14 @@
 {
     "argument.computercraft.argument_expected": "Argumento esperado",
+    "argument.computercraft.computer.distance": "Distancia a entidad",
+    "argument.computercraft.computer.family": "Familia de computadoras",
+    "argument.computercraft.computer.id": "ID de la computadora",
+    "argument.computercraft.computer.instance": "ID de instancia único",
+    "argument.computercraft.computer.label": "Etiqueta de la computadora",
     "argument.computercraft.computer.many_matching": "Varias computadoras que coinciden con ' %s' (instancias %s)",
+    "argument.computercraft.computer.no_matching": "No hay ordenadores que coincidan con '%s'",
+    "argument.computercraft.tracking_field.no_field": "Campo desconocido '%s'",
+    "argument.computercraft.unknown_computer_family": "Familia de ordenadores desconocida '%s'",
     "block.computercraft.cable": "Cable de red",
     "block.computercraft.computer_advanced": "Ordenador avanzado",
     "block.computercraft.computer_command": "Ordenador de Comandos",
@@ -22,29 +30,167 @@
     "block.computercraft.wireless_modem_normal": "Módem sin cables",
     "chat.computercraft.wired_modem.peripheral_connected": "El periférico \"%s\" se conectó a la red",
     "chat.computercraft.wired_modem.peripheral_disconnected": "El periférico \"%s\" se desconectó de la red",
+    "commands.computercraft.desc": "El comando /computercraft proporciona varias herramientas de depuración y administración para controlar e interactuar con computadoras.",
+    "commands.computercraft.dump.action": "Ver más info acerca de esta computadora",
+    "commands.computercraft.dump.desc": "Muestra el estado de todas las computadoras o información específica sobre una computadora. Puedes especificar el id de instancia de la computadora (ej. 123), el id de la computadora (ej. #123) o su etiqueta (ej. \"@Mi computadora\").",
+    "commands.computercraft.dump.open_path": "Ver los archivos de esta computadora",
+    "commands.computercraft.dump.synopsis": "Mostrar el estado de las computadoras.",
     "commands.computercraft.generic.additional_rows": "%d filas adicionales…",
+    "commands.computercraft.generic.exception": "Excepción no controlada (%s)",
     "commands.computercraft.generic.no": "N",
     "commands.computercraft.generic.yes": "Y",
     "commands.computercraft.help.desc": "Muestra este mensaje de ayuda",
+    "commands.computercraft.help.no_children": "%s no tiene sub-comandos",
     "commands.computercraft.help.no_command": "Sin comando '%s'",
+    "commands.computercraft.help.synopsis": "Provee ayuda para un comando específico",
+    "commands.computercraft.queue.desc": "Envía un evento computer_command a un ordenador de comandos, pasándole los argumentos adicionales. Esto está diseñado principalmente para los map makers, actuando como una versión más amigable con el ordenador de /trigger. Cualquier jugador puede ejecutar el comando, lo que probablemente se haría a través de un evento de clic de un componente de texto.",
+    "commands.computercraft.queue.synopsis": "Envía un evento computer_command a un ordenador de comandos",
+    "commands.computercraft.shutdown.desc": "Apagar las computadoras listadas o todas si ninguna se especifica. Puedes especificar el id de la instancia de la computadora (ej. 123), el id de la computadora (ej. #123) o la etiqueta (ej. \"@Mi Computadora\").",
     "commands.computercraft.shutdown.done": "Apague %s/%s computadoras",
     "commands.computercraft.shutdown.synopsis": "Apague las computadoras de forma remota.",
+    "commands.computercraft.synopsis": "Varios comandos para controlar computadoras.",
+    "commands.computercraft.tp.action": "Teletransportarse a esta computadora",
+    "commands.computercraft.tp.desc": "Teletransportarse a la ubicación de una computadora. Puedes especificar tanto el id de la instancia de la computadora (ej. 123) o el id de la computadora (ej. #123).",
+    "commands.computercraft.tp.synopsis": "Teletransportarse a una computadora específica.",
+    "commands.computercraft.track.desc": "Seguimiento de qué tanto se ejecutan las computadoras, y también cuántos eventos manejan. Esto presenta información en una manera similar a /forge track y puede ser útil para diagnosticar lag.",
+    "commands.computercraft.track.dump.computer": "Computadora",
+    "commands.computercraft.track.dump.desc": "Volcar los últimos resultados del seguimiento de computadoras.",
+    "commands.computercraft.track.dump.no_timings": "No hay temporizaciones disponibles",
+    "commands.computercraft.track.dump.synopsis": "Volcar los últimos resultados de seguimiento",
+    "commands.computercraft.track.start.desc": "Comenzar el seguimiento de todos los tiempos y conteo de eventos de las computadoras. Esto va a descartar los resultados de ejecuciones previas.",
+    "commands.computercraft.track.start.stop": "Ejecute %s para detener el seguimiento y ver los resultados",
+    "commands.computercraft.track.start.synopsis": "Comenzar el seguimiento de todas las computadoras",
+    "commands.computercraft.track.stop.action": "Clic para detener el seguimiento",
+    "commands.computercraft.track.stop.desc": "Detener el seguimiento de todos los eventos y tiempos de ejecución de las computadoras",
+    "commands.computercraft.track.stop.not_enabled": "Actualmente no hay computadoras en seguimiento",
+    "commands.computercraft.track.stop.synopsis": "Dejar de seguir a todas las computadoras",
+    "commands.computercraft.track.synopsis": "Seguimiento de tiempos de ejecución para computadoras.",
+    "commands.computercraft.turn_on.desc": "Encender las computadoras listadas. Puedes especificar el id de la instancia de la computadora (ej. 123), el id de la computadora (ej. #123) o la etiqueta (ej. \"@Mi computadora\").",
+    "commands.computercraft.turn_on.done": "Encendidas %s/%s computadoras",
+    "commands.computercraft.turn_on.synopsis": "Encender computadoras remotamente.",
+    "commands.computercraft.view.action": "Ver esta computadora",
+    "commands.computercraft.view.desc": "Abrir la terminal de una computadora, permitiendo el control remoto de esta. Esto no proporciona acceso al inventario de tortugas. Puede tanto especificar el Id de instancia de la computadora (ej. 123) o el Id de la computadora (ej. #123).",
+    "commands.computercraft.view.not_player": "No se puede abrir la terminal para un no-jugador",
+    "commands.computercraft.view.synopsis": "Ver la terminal de una computadora",
+    "gui.computercraft.config.command_require_creative": "Las computadoras de comando requieren creativo",
+    "gui.computercraft.config.command_require_creative.tooltip": "Requiere que los jugadores estén en modo creativo y sean operadores para\ninteractuar con las computadoras de comandos. Este es el comportamiento\npredeterminado para los bloques de comandos en vanilla.",
     "gui.computercraft.config.computer_space_limit": "Límite de memoria de ordenadores (en bytes)",
+    "gui.computercraft.config.computer_space_limit.tooltip": "Límite de espacio en disco para computadoras y tortugas, en bytes.",
     "gui.computercraft.config.default_computer_settings": "Configuración de Ordenador por defecto",
+    "gui.computercraft.config.default_computer_settings.tooltip": "Una lista separada por comas de los ajustes predeterminados para establecer en nuevas computadoras.\nEjemplo: \"shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false\"\ndeshabilitará todo el autocompletado.",
+    "gui.computercraft.config.disabled_generic_methods": "Métodos genéricos desactivados",
+    "gui.computercraft.config.disabled_generic_methods.tooltip": "Una lista de métodos genéricos o métodos de fuente para deshabilitar. Los\nmétodos genéricos son métodos añadidos a un bloque/block entity cuando no hay\nun proveedor de periférico explícito. Esto incluye métodos de inventario (ej.\ninventory.getItemDetail, inventory.pushItems), y (si está en Forge), los\nmétodos fluid_storage y energy_storage.\nLos métodos en esta lista pueden ser tanto un grupo entero de métodos\n(computercraft:inventory) o un método en particular\n(computercraft:inventory#pushItems).\n",
+    "gui.computercraft.config.execution": "Ejecución",
+    "gui.computercraft.config.execution.computer_threads": "Hilos de la computadora",
+    "gui.computercraft.config.execution.computer_threads.tooltip": "Establece el número de hilos en los que las computadoras pueden correr. Un número\nmás alto significa que más computadoras pueden ejecutarse a la vez, pero podrían\ninducir lag. Ten en cuenta que algunos mods podrían no funcionar con un número de\nhilos mayor a 1. Usar con precaución.\nRango: > 1",
+    "gui.computercraft.config.execution.max_main_computer_time": "Límite de tiempo de la computadora en un tick del servidor",
+    "gui.computercraft.config.execution.max_main_global_time": "Límite de tiempo global en un tick del servidor",
+    "gui.computercraft.config.execution.tooltip": "Controla el comportamiento de ejecución de las computadoras. Esto es\nen gran medida destinado al control fino para servidores, y generalmente no\ndebería ser cambiado.",
     "gui.computercraft.config.floppy_space_limit": "Límite de memoria de disquetes (en bytes)",
+    "gui.computercraft.config.floppy_space_limit.tooltip": "El límite de espacio en disco para los disquetes, en bytes.",
+    "gui.computercraft.config.http": "HTTP",
+    "gui.computercraft.config.http.bandwidth": "Ancho de banda",
+    "gui.computercraft.config.http.bandwidth.global_download": "Límite de descarga global",
+    "gui.computercraft.config.http.bandwidth.global_download.tooltip": "El número de bytes que se pueden descargar por segundo. Esto es compartido para todas las computadoras. (bytes/s).\nRango: > 1",
+    "gui.computercraft.config.http.bandwidth.global_upload": "Límite de subida global",
+    "gui.computercraft.config.http.bandwidth.global_upload.tooltip": "El número de bytes que se pueden subir por segundo. Esto es compartido para todas las computadoras. (bytes/s).\nRango: > 1",
+    "gui.computercraft.config.http.bandwidth.tooltip": "Limita el ancho de banda usado por las computadoras.",
     "gui.computercraft.config.http.enabled": "Habilitar API de HTTP",
+    "gui.computercraft.config.http.enabled.tooltip": "Habilitar la API \"http\" en computadoras. Deshabilitar esto también desactiva los\nprogramas \"pastebin\" y \"wget\", los cuales muchos usuarios dependen. Se recomienda\ndejar esto encendido y usar la opción \"reglas\" en configuración para imponer un\ncontrol más fino.",
+    "gui.computercraft.config.http.max_requests": "Máximo de solicitudes simultáneas",
+    "gui.computercraft.config.http.max_requests.tooltip": "El número de solicitudes http que un equipo puede hacer a la vez. Las solicitudes\nadicionales se pondrán en cola, y se enviarán cuando las solicitudes en ejecución\nhayan finalizado. Establezca 0 para ilimitado.\nRango: > 0",
+    "gui.computercraft.config.http.max_websockets": "Máximos websockets concurrentes",
+    "gui.computercraft.config.http.max_websockets.tooltip": "El número de websockets que una computadora puede tener abierto\nen el mismo momento.\nRango: > 1",
+    "gui.computercraft.config.http.proxy": "Proxy",
+    "gui.computercraft.config.http.proxy.host": "Nombre del host",
+    "gui.computercraft.config.http.proxy.host.tooltip": "El nombre del host o la dirección IP del servidor proxy.",
+    "gui.computercraft.config.http.proxy.port": "Puerto",
+    "gui.computercraft.config.http.proxy.port.tooltip": "El puerto del servidor proxy.\nRango: 1 ~ 65536",
+    "gui.computercraft.config.http.proxy.tooltip": "Pasa los pedidos HTTP y websocket a través de un servidor proxy. Solo afecta a las\nreglas HTTP con \"use_proxy\" puesto en verdadero (falso por defecto).\nSi se requiere autenticación para el proxy, crea un archivo\n\"computercraft-proxy.pw\" en la misma carpeta que se encuentra\n\"computercraft-server.toml\", conteniendo el nombre de usuario y contraseña\nseparada por dos puntos, por ejemplo: \"miusuario:micontraseña\". Para proxys\nSOCKS4 solo se requiere el nombre de usuario.",
+    "gui.computercraft.config.http.proxy.type": "Tipo de proxy",
+    "gui.computercraft.config.http.proxy.type.tooltip": "El tipo de proxy a utilizar.\nValores permitidos: HTTP, HTTPS, SOCKS4, SOCKS5",
+    "gui.computercraft.config.http.rules": "Reglas de permitir/denegar",
+    "gui.computercraft.config.http.rules.tooltip": "Una lista de reglas que controlan el comportamiento de la API \"http\" para dominios\nespecíficos o IPs. Cada regla aplica a un hostname y un puerto opcional, y luego\nestablece varias propiedades para el pedido. Las reglas son evaluadas en orden,\nlo que quiere decir que las reglas primeras sobreescriben a las de después.\n\nPropiedades válidas:\n - \"host\" (requerido): El dominio o dirección IP con el que la regla va a operar.\n   Este puede ser nombre de dominio (\"pastebin.com\"), wildcard (\"*.pastebin.com\")\n   o notación CIDR (\"127.0.0.0/8\").\n - \"port\" (opcional): Solo aplicar a pedidos para un puerto específico, como 80\n   o 443.\n - \"action\" (opcional): Permitir o denegar este pedido.\n - \"max_download\" (opcional): El tamaño máximo (en bytes) que una computadora \n   puede descargar en este pedido.\n - \"max_upload\" (opcional): El tamaño máximo (en bytes) que una computadora puede\n   subir en este pedido.\n - \"max_websocket_message\" (opcional): El tamaño máximo (en bytes) que una\n   computadora puede enviar en un paquete websocket.\n - \"use_proxy\" (opcional): Habilitar el uso de el proxy HTTP/SOCKS si está\n   configurado.",
+    "gui.computercraft.config.http.tooltip": "Controla la API HTTP",
+    "gui.computercraft.config.http.websocket_enabled": "Habilitar websockets",
+    "gui.computercraft.config.http.websocket_enabled.tooltip": "Habilita el uso de websockets http. Esto requiere que la opción \"http_enable\" sea verdadera.",
     "gui.computercraft.config.log_computer_errors": "Grabar errores periféricos",
+    "gui.computercraft.config.log_computer_errors.tooltip": "Registra excepciones lanzadas por los periféricos y otros objetos de Lua. Esto facilita\ndepurar problemas para los autores de mods, pero puede resultar en spam en el\nregistro si la gente utiliza métodos con errores potenciales.",
     "gui.computercraft.config.maximum_open_files": "Archivos abiertos máximos por cada ordenador",
+    "gui.computercraft.config.maximum_open_files.tooltip": "Establece cuántos archivos puede tener abiertos una computadora al mismo tiempo. Establezca 0 para ilimitados.\nRango: > 0",
+    "gui.computercraft.config.monitor_distance": "Distancia al monitor",
+    "gui.computercraft.config.monitor_distance.tooltip": "La distancia máxima a la que los monitores se renderizarán. El valor\npredeterminado es el límite de los tile entities, pero puede ser extendido si quieres\nconstruir monitores más grandes.\nRango: 16 ~ 1024",
+    "gui.computercraft.config.monitor_renderer": "Renderizador del monitor",
+    "gui.computercraft.config.monitor_renderer.tooltip": "El renderizador a usar en monitores. Generalmente esto debe estar en \"BEST\"\n(mejor) - si los monitores tienen problemas de rendimiento, podrías querer\nexperimentar con renderizadores alternativos.\nValores permitidos: BEST, TBO, VBO",
+    "gui.computercraft.config.peripheral": "Periféricos",
     "gui.computercraft.config.peripheral.command_block_enabled": "Habilitar bloque de comandos periférico",
+    "gui.computercraft.config.peripheral.command_block_enabled.tooltip": "Habilitar soporte del periférico Bloque de Comandos",
     "gui.computercraft.config.peripheral.max_notes_per_tick": "Notas máximas que un ordenador puede tocar a la vez",
+    "gui.computercraft.config.peripheral.max_notes_per_tick.tooltip": "Cantidad máxima de notas que un parlante puede reproducir a la vez.\nRango: > 1",
     "gui.computercraft.config.peripheral.modem_high_altitude_range": "Rango del módem (en altitud)",
+    "gui.computercraft.config.peripheral.modem_high_altitude_range.tooltip": "El rango de los Modems inalámbricos a máxima altitud en clima despejado, en metros.\nRango: 0 ~ 100000",
     "gui.computercraft.config.peripheral.modem_high_altitude_range_during_storm": "Rango del módem (en altitud con mal tiempo)",
+    "gui.computercraft.config.peripheral.modem_high_altitude_range_during_storm.tooltip": "El rango de los Modems inalámbricos a máxima altitud durante las tormentas, en metros.\nRango: 0 ~ 100000",
     "gui.computercraft.config.peripheral.modem_range": "Rango del módem (Por defecto)",
+    "gui.computercraft.config.peripheral.modem_range.tooltip": "El rango de los Modems inalámbricos a baja altitud en clima despejado, en metros.\nRango: 0 ~ 100000",
     "gui.computercraft.config.peripheral.modem_range_during_storm": "Rango del módem (mal tiempo)",
+    "gui.computercraft.config.peripheral.modem_range_during_storm.tooltip": "El rango de los Modems inalámbricos a baja altitud durante las tormentas, en metros.\nRango: 0 ~ 100000",
+    "gui.computercraft.config.peripheral.monitor_bandwidth": "Ancho de banda del monitor",
+    "gui.computercraft.config.peripheral.monitor_bandwidth.tooltip": "El límite de datos que un monitor puede enviar *por tick* Nota:\n - El ancho de banda es medido antes de la compresión, así que los datos enviados\n   al cliente son más pequeños.\n - Esto ignora el número de jugadores a los que se les envían los paquetes.\n   Actualizar un monitor para un jugador consume lo mismo que actualizarlo para\n   20.\n - Un monitor del tamaño más grande envía ~25kb de datos. Así que el límite\n   predeterminado (1MB) permite actualizar ~40 monitores en un solo tick.\nEstablezca en 0 para desactivar.\nRango: > 0",
+    "gui.computercraft.config.peripheral.tooltip": "Varias opciones relacionadas con los periféricos.",
+    "gui.computercraft.config.term_sizes": "Tamaños de la terminal",
+    "gui.computercraft.config.term_sizes.computer": "Computadora",
+    "gui.computercraft.config.term_sizes.computer.height": "Altura de la terminal",
+    "gui.computercraft.config.term_sizes.computer.height.tooltip": "Rango: 1 ~ 255",
+    "gui.computercraft.config.term_sizes.computer.tooltip": "Tamaño de la terminal de las computadoras.",
+    "gui.computercraft.config.term_sizes.computer.width": "Ancho de la terminal",
+    "gui.computercraft.config.term_sizes.computer.width.tooltip": "Rango: 1 ~ 255",
+    "gui.computercraft.config.term_sizes.monitor": "Monitor",
+    "gui.computercraft.config.term_sizes.monitor.height": "Altura máxima del monitor",
+    "gui.computercraft.config.term_sizes.monitor.height.tooltip": "Rango: 1 ~ 32",
+    "gui.computercraft.config.term_sizes.monitor.tooltip": "Tamaño máximo de los monitores (en bloques).",
+    "gui.computercraft.config.term_sizes.monitor.width": "Anchura máxima del monitor",
+    "gui.computercraft.config.term_sizes.monitor.width.tooltip": "Rango: 1 ~ 32",
+    "gui.computercraft.config.term_sizes.pocket_computer": "Computadora de bolsillo",
+    "gui.computercraft.config.term_sizes.pocket_computer.height": "Altura de la terminal",
+    "gui.computercraft.config.term_sizes.pocket_computer.height.tooltip": "Rango: 1 ~ 255",
+    "gui.computercraft.config.term_sizes.pocket_computer.tooltip": "Tamaño de la terminal de las computadoras de bolsillo.",
+    "gui.computercraft.config.term_sizes.pocket_computer.width": "Ancho de la terminal",
+    "gui.computercraft.config.term_sizes.pocket_computer.width.tooltip": "Rango: 1 ~ 255",
+    "gui.computercraft.config.term_sizes.tooltip": "Configura el tamaño de las terminales de varias computadoras.\nTerminales más grandes requieren mayor ancho de banda, así que úselo con cuidado.",
+    "gui.computercraft.config.turtle": "Tortugas",
     "gui.computercraft.config.turtle.advanced_fuel_limit": "Límite de combustible de las tortugas avanzadas",
+    "gui.computercraft.config.turtle.advanced_fuel_limit.tooltip": "El límite de combustible para Tortugas Avanzadas.\nRango: > 0",
     "gui.computercraft.config.turtle.can_push": "Las tortugas pueden empujar entidades",
+    "gui.computercraft.config.turtle.can_push.tooltip": "Si es verdadero, las tortugas empujarán a las entidades de su camino en\nlugar de detenerse si hay espacio para hacerlo.",
     "gui.computercraft.config.turtle.need_fuel": "Habilitar combustible",
+    "gui.computercraft.config.turtle.need_fuel.tooltip": "Establece si las tortugas requieren combustible para moverse.",
     "gui.computercraft.config.turtle.normal_fuel_limit": "Límite de combustible de las tortugas",
+    "gui.computercraft.config.turtle.normal_fuel_limit.tooltip": "Límite de combustible para las Tortugas.\nRango: > 0",
+    "gui.computercraft.config.turtle.tooltip": "Varias opciones relacionadas con las tortugas.",
+    "gui.computercraft.config.upload_max_size": "Límite de tamaño del archivo subido (bytes)",
+    "gui.computercraft.config.upload_max_size.tooltip": "El límite de subida por archivo, en bytes. Debe estar en un rango de entre 1 KiB y 16 MiB.\nTen en cuenta que las subidas son procesadas en un un solo tick - archivos grandes o\nun rendimiento de internet malo puede paralizar el hilo de red. Y tamién ten en cuenta el espacio en disco!\nRango: 1024 ~ 16777216",
+    "gui.computercraft.config.upload_nag_delay": "Retraso de subida nag",
+    "gui.computercraft.config.upload_nag_delay.tooltip": "El retraso en segundos después de los cuales notificaremos las importaciones no manejadas. Establecer en 0 para deshabilitar.\nRango: 0 ~ 60",
+    "gui.computercraft.pocket_computer_overlay": "Computadora de bolsillo abierta. Pulsa ESC para cerrar.",
+    "gui.computercraft.terminal": "Terminal de la Computadora",
+    "gui.computercraft.tooltip.computer_id": "ID de la Computadora: %s",
+    "gui.computercraft.tooltip.copy": "Copiar al portapapeles",
+    "gui.computercraft.tooltip.disk_id": "ID del disquete: %s",
+    "gui.computercraft.tooltip.terminate": "Detener el código en ejecución",
+    "gui.computercraft.tooltip.terminate.key": "Mantenga Ctrl+T",
+    "gui.computercraft.tooltip.turn_off": "Apagar esta computadora",
+    "gui.computercraft.tooltip.turn_off.key": "Mantenga Ctrl+S",
+    "gui.computercraft.tooltip.turn_on": "Encender esta computadora",
+    "gui.computercraft.upload.failed": "Subida fallida",
+    "gui.computercraft.upload.failed.computer_off": "Debes encender la computadora antes de subir archivos.",
+    "gui.computercraft.upload.failed.corrupted": "Archivos corruptos al subir. Por favor, inténtelo de nuevo.",
+    "gui.computercraft.upload.failed.generic": "Error al subir archivos (%s)",
+    "gui.computercraft.upload.failed.name_too_long": "Los nombres de los archivos son demasiado largos para ser cargados.",
+    "gui.computercraft.upload.failed.too_many_files": "No se pueden subir tantos archivos.",
+    "gui.computercraft.upload.failed.too_much": "Tus archivos son demasiado grandes para ser subidos.",
+    "gui.computercraft.upload.no_response": "Transfiriendo archivos",
+    "gui.computercraft.upload.no_response.msg": "Tu computadora no ha usado tus archivos transferidos. Es posible que debas ejecutar el programa %s e intentar de nuevo.",
     "item.computercraft.disk": "Disquete",
     "item.computercraft.pocket_computer_advanced": "Ordenador de bolsillo avanzado",
     "item.computercraft.pocket_computer_advanced.upgraded": "Ordenador de bolsillo %s avanzado",
@@ -54,6 +200,25 @@
     "item.computercraft.printed_page": "Página impresa",
     "item.computercraft.printed_pages": "Páginas impresas",
     "item.computercraft.treasure_disk": "Disquete (Tesoro)",
+    "itemGroup.computercraft": "ComputerCraft",
+    "tag.item.computercraft.computer": "Computadoras",
+    "tag.item.computercraft.monitor": "Monitores",
+    "tag.item.computercraft.turtle": "Tortugas",
+    "tag.item.computercraft.wired_modem": "Módems cableados",
+    "tracking_field.computercraft.avg": "%s (promedio)",
+    "tracking_field.computercraft.computer_tasks.name": "Tareas",
+    "tracking_field.computercraft.count": "%s (cuenta)",
+    "tracking_field.computercraft.fs.name": "Operaciones del sistema de archivos",
+    "tracking_field.computercraft.http_download.name": "Descarga HTTP",
+    "tracking_field.computercraft.http_requests.name": "Peticiones HTTP",
+    "tracking_field.computercraft.http_upload.name": "Subida HTTP",
+    "tracking_field.computercraft.java_allocation.name": "Asignaciones de Java",
+    "tracking_field.computercraft.max": "%s (max)",
+    "tracking_field.computercraft.peripheral.name": "Llamadas del periférico",
+    "tracking_field.computercraft.server_tasks.name": "Tareas del servidor",
+    "tracking_field.computercraft.turtle_ops.name": "Operaciones de la Tortuga",
+    "tracking_field.computercraft.websocket_incoming.name": "Websocket entrante",
+    "tracking_field.computercraft.websocket_outgoing.name": "Websocket saliente",
     "upgrade.computercraft.speaker.adjective": "ruidosa",
     "upgrade.computercraft.wireless_modem_advanced.adjective": "ender",
     "upgrade.computercraft.wireless_modem_normal.adjective": "sin cables",
diff --git a/projects/common/src/main/resources/assets/computercraft/lang/it_it.json b/projects/common/src/main/resources/assets/computercraft/lang/it_it.json
index d5ace0c940..e328c054ca 100644
--- a/projects/common/src/main/resources/assets/computercraft/lang/it_it.json
+++ b/projects/common/src/main/resources/assets/computercraft/lang/it_it.json
@@ -12,10 +12,8 @@
     "block.computercraft.cable": "Cavo Di Rete",
     "block.computercraft.computer_advanced": "Computer Avanzato",
     "block.computercraft.computer_command": "Computer Comando",
-    "block.computercraft.computer_normal": "Computer",
     "block.computercraft.disk_drive": "Lettore Di Dischi",
     "block.computercraft.monitor_advanced": "Monitor Avanzato",
-    "block.computercraft.monitor_normal": "Monitor",
     "block.computercraft.printer": "Stampante",
     "block.computercraft.speaker": "Altoparlante",
     "block.computercraft.turtle_advanced": "Tartaruga Avanzata",
@@ -37,7 +35,6 @@
     "commands.computercraft.dump.synopsis": "Mostra lo stato dei computer.",
     "commands.computercraft.generic.additional_rows": "%d colonne aggiuntive…",
     "commands.computercraft.generic.exception": "Eccezione non gestita (%s)",
-    "commands.computercraft.generic.no": "N",
     "commands.computercraft.generic.yes": "S",
     "commands.computercraft.help.desc": "Mostra questo messaggio d'aiuto",
     "commands.computercraft.help.no_children": "%s non ha sottocomandi",
@@ -53,7 +50,6 @@
     "commands.computercraft.tp.desc": "Teletrasporta alla posizione di un computer. Puoi specificare il computer con l'instance id (e.g. 123) o con l'id (e.g. #123).",
     "commands.computercraft.tp.synopsis": "Teletrasporta al computer specificato.",
     "commands.computercraft.track.desc": "Monitora per quanto tempo i computer vengono eseguiti e quanti eventi ricevono. Questo comando fornisce le informazioni in modo simile a /forge track e può essere utile per diagnosticare il lag.",
-    "commands.computercraft.track.dump.computer": "Computer",
     "commands.computercraft.track.dump.desc": "Cancella gli ultimi risultati del monitoraggio dei computer.",
     "commands.computercraft.track.dump.no_timings": "No ci sono tempi disponibili",
     "commands.computercraft.track.dump.synopsis": "Cancella gli ultimi risultati monitorati",
@@ -90,7 +86,6 @@
     "gui.computercraft.config.execution.tooltip": "Controlla comportamento esecuzione dei computer. Questo è largamente utilizzato\nper ritoccare la performance dei server, e generale non dovrebbe essere toccato.",
     "gui.computercraft.config.floppy_space_limit": "Limite spazio Disco Floppy (bytes)",
     "gui.computercraft.config.floppy_space_limit.tooltip": "Limite di spazio di archiviazione per i dischi floppy, in byte.",
-    "gui.computercraft.config.http": "HTTP",
     "gui.computercraft.config.http.bandwidth": "Banda larga",
     "gui.computercraft.config.http.bandwidth.global_download": "Limite download globale",
     "gui.computercraft.config.http.bandwidth.global_download.tooltip": "Numero di byte che possono essere scaricati in un secondo. Questo è condiviso tra tutti i computer. (bytes/s).\nRange: > 1",
@@ -103,7 +98,6 @@
     "gui.computercraft.config.http.max_requests.tooltip": "Il numero di richieste http che un computer può fare alla volta. Ulteriori richieste\nverranno messe in coda, ed inviate quando le richieste correnti sono terminate.\nImposta a 0 per illimitato.\nRange: > 0",
     "gui.computercraft.config.http.max_websockets": "Connessioni websocket massime",
     "gui.computercraft.config.http.max_websockets.tooltip": "Il numero di websocket che un computer può avere aperte allo stesso momento.\nImposta a 0 per illimitato.\nRange: > 1",
-    "gui.computercraft.config.http.proxy": "Proxy",
     "gui.computercraft.config.http.proxy.host": "Nome host",
     "gui.computercraft.config.http.proxy.host.tooltip": "Il nome dell'host o l'indirizzo IP del server proxy.",
     "gui.computercraft.config.http.proxy.port": "Porta",
@@ -141,24 +135,17 @@
     "gui.computercraft.config.peripheral.monitor_bandwidth.tooltip": "Il limite di quanti dati dei monitor possono essere inviati *al tick*. Nota:\n - La banda larga è misurata prima della compressione, così che il dato inviato al client è\n   più piccolo.\n - Questo ignora il numero di giocatori a cui viene inviato il pacchetto. Aggiornare un monitor\n   per un giocatore consuma lo stesso limite di banda larga dell'invio a 20 giocatori.\n - Un monitor alla massima grandezza invia ~25kb di dati. Quindi il valore predefinito (1MB) concede\n   ~40 monitor di essere aggiornati in un singolo tick.\nImposta a 0 per disattivare.\nRange: > 0",
     "gui.computercraft.config.peripheral.tooltip": "Opzioni varie riguardo le periferiche.",
     "gui.computercraft.config.term_sizes": "Dimensioni terminale",
-    "gui.computercraft.config.term_sizes.computer": "Computer",
     "gui.computercraft.config.term_sizes.computer.height": "Altezza terminale",
-    "gui.computercraft.config.term_sizes.computer.height.tooltip": "Range: 1 ~ 255",
     "gui.computercraft.config.term_sizes.computer.tooltip": "Dimensioni del terminale dei computer.",
     "gui.computercraft.config.term_sizes.computer.width": "Larghezza terminale",
     "gui.computercraft.config.term_sizes.computer.width.tooltip": "Intervallo: 1 ~ 255",
-    "gui.computercraft.config.term_sizes.monitor": "Monitor",
     "gui.computercraft.config.term_sizes.monitor.height": "Massima altezza del monitor",
-    "gui.computercraft.config.term_sizes.monitor.height.tooltip": "Range: 1 ~ 32",
     "gui.computercraft.config.term_sizes.monitor.tooltip": "Massima grandezza dei monitor (in blocchi).",
     "gui.computercraft.config.term_sizes.monitor.width": "Larghezza massima del monitor",
-    "gui.computercraft.config.term_sizes.monitor.width.tooltip": "Range: 1 ~ 32",
     "gui.computercraft.config.term_sizes.pocket_computer": "Computer Tascabile",
     "gui.computercraft.config.term_sizes.pocket_computer.height": "Altezza terminale",
-    "gui.computercraft.config.term_sizes.pocket_computer.height.tooltip": "Range: 1 ~ 255",
     "gui.computercraft.config.term_sizes.pocket_computer.tooltip": "Dimensioni del terminale dei computer tascabili.",
     "gui.computercraft.config.term_sizes.pocket_computer.width": "Larghezza terminale",
-    "gui.computercraft.config.term_sizes.pocket_computer.width.tooltip": "Range: 1 ~ 255",
     "gui.computercraft.config.term_sizes.tooltip": "Configura le dimensioni dei terminali di vari computer.\nTerminali più grandi richiedono più banda larga, usa con cautela.",
     "gui.computercraft.config.turtle": "Tartarughe",
     "gui.computercraft.config.turtle.advanced_fuel_limit": "Limite carburante tartarughe avanzate",
@@ -202,7 +189,6 @@
     "item.computercraft.printed_page": "Pagina Stampata",
     "item.computercraft.printed_pages": "Pagine Stampate",
     "item.computercraft.treasure_disk": "Disco Floppy",
-    "itemGroup.computercraft": "ComputerCraft",
     "tag.item.computercraft.computer": "Computer",
     "tag.item.computercraft.monitor": "Monitor",
     "tag.item.computercraft.turtle": "Tartarughe",
@@ -222,8 +208,6 @@
     "tracking_field.computercraft.websocket_incoming.name": "Websocket in arrivo",
     "tracking_field.computercraft.websocket_outgoing.name": "Websocket in uscita",
     "upgrade.computercraft.speaker.adjective": "Rumoroso",
-    "upgrade.computercraft.wireless_modem_advanced.adjective": "Ender",
-    "upgrade.computercraft.wireless_modem_normal.adjective": "Wireless",
     "upgrade.minecraft.crafting_table.adjective": "Artigiana",
     "upgrade.minecraft.diamond_axe.adjective": "Taglialegna",
     "upgrade.minecraft.diamond_hoe.adjective": "Contadina",
diff --git a/projects/common/src/main/resources/assets/computercraft/lang/nb_no.json b/projects/common/src/main/resources/assets/computercraft/lang/nb_no.json
index 7d3269bd28..d54d002dc6 100644
--- a/projects/common/src/main/resources/assets/computercraft/lang/nb_no.json
+++ b/projects/common/src/main/resources/assets/computercraft/lang/nb_no.json
@@ -10,7 +10,6 @@
     "block.computercraft.disk_drive": "Diskstasjon",
     "block.computercraft.monitor_advanced": "Avansert Skjerm",
     "block.computercraft.monitor_normal": "Skjerm",
-    "block.computercraft.printer": "Printer",
     "block.computercraft.speaker": "Høytaler",
     "block.computercraft.turtle_advanced": "Avansert Skilpadde",
     "block.computercraft.turtle_advanced.upgraded": "Avansert %s Skilpadde",
@@ -20,7 +19,6 @@
     "block.computercraft.turtle_normal.upgraded_twice": "%s %s Skilpadde",
     "block.computercraft.wired_modem": "Kablet Modem",
     "block.computercraft.wired_modem_full": "Kablet Modem",
-    "block.computercraft.wireless_modem_advanced": "Ender Modem",
     "block.computercraft.wireless_modem_normal": "Trådløst Modem",
     "chat.computercraft.wired_modem.peripheral_connected": "Perifer \"%s\" koblet til nettverk",
     "chat.computercraft.wired_modem.peripheral_disconnected": "Perifer \"%s\" koblet fra nettverk",
@@ -31,7 +29,6 @@
     "commands.computercraft.dump.synopsis": "Viser statusen av datamaskiner.",
     "commands.computercraft.generic.additional_rows": "%d flere rader…",
     "commands.computercraft.generic.exception": "Uhåndtert unntak (%s)",
-    "commands.computercraft.generic.no": "N",
     "commands.computercraft.generic.yes": "J",
     "commands.computercraft.help.desc": "Viser denne hjelpemeldingen",
     "commands.computercraft.help.no_children": "%s har ingen underkommandoer",
@@ -67,7 +64,6 @@
     "commands.computercraft.view.not_player": "Kan kun åpne terminal for spillere",
     "commands.computercraft.view.synopsis": "Vis terminal til en datamaskin.",
     "gui.computercraft.config.command_require_creative": "Kommando datamaskiner trenger kreativ",
-    "gui.computercraft.config.http": "HTTP",
     "gui.computercraft.config.http.enabled": "Slå på HTTP APIen",
     "gui.computercraft.config.http.rules": "Godta/Avslå regler",
     "gui.computercraft.config.monitor_distance": "Skjerm distanse",
@@ -86,7 +82,6 @@
     "gui.computercraft.terminal": "Datamaskin terminal",
     "gui.computercraft.tooltip.computer_id": "Datamaskin ID: %s",
     "gui.computercraft.tooltip.copy": "Kopier til utklippstavle",
-    "gui.computercraft.tooltip.disk_id": "Disk ID: %s",
     "gui.computercraft.tooltip.terminate": "Stopp den kjørende koden",
     "gui.computercraft.tooltip.terminate.key": "Hold Ctrl + T",
     "gui.computercraft.tooltip.turn_off": "Skru denne datamaskinen av",
@@ -100,7 +95,6 @@
     "gui.computercraft.upload.failed.too_many_files": "Kan ikke laste opp så mange filer.",
     "gui.computercraft.upload.failed.too_much": "Filene dine er for store for å kunne bli lastet opp.",
     "gui.computercraft.upload.no_response": "Overfører Filer",
-    "item.computercraft.disk": "Floppy Disk",
     "item.computercraft.pocket_computer_advanced": "Avansert Lomme Datamaskin",
     "item.computercraft.pocket_computer_advanced.upgraded": "Avansert %s Lomme Datamaskin",
     "item.computercraft.pocket_computer_normal": "Lomme datamaskin",
@@ -108,8 +102,6 @@
     "item.computercraft.printed_book": "Printet Bok",
     "item.computercraft.printed_page": "Printet Side",
     "item.computercraft.printed_pages": "Printet Sider",
-    "item.computercraft.treasure_disk": "Floppy Disk",
-    "itemGroup.computercraft": "ComputerCraft",
     "tracking_field.computercraft.computer_tasks.name": "Oppgaver",
     "tracking_field.computercraft.count": "%s (antall)",
     "tracking_field.computercraft.fs.name": "Filsystem operasjoner",
@@ -121,7 +113,6 @@
     "tracking_field.computercraft.websocket_incoming.name": "Innkommende Websocket",
     "tracking_field.computercraft.websocket_outgoing.name": "Utgående Websocket",
     "upgrade.computercraft.speaker.adjective": "Høylydt",
-    "upgrade.computercraft.wireless_modem_advanced.adjective": "Ender",
     "upgrade.computercraft.wireless_modem_normal.adjective": "Trådløs",
     "upgrade.minecraft.crafting_table.adjective": "Håndverks",
     "upgrade.minecraft.diamond_axe.adjective": "Hoggende",
diff --git a/projects/common/src/main/resources/assets/computercraft/lang/pt_br.json b/projects/common/src/main/resources/assets/computercraft/lang/pt_br.json
index 15ae05a885..a813aad5ab 100644
--- a/projects/common/src/main/resources/assets/computercraft/lang/pt_br.json
+++ b/projects/common/src/main/resources/assets/computercraft/lang/pt_br.json
@@ -1,4 +1,14 @@
 {
+    "argument.computercraft.argument_expected": "Argumento esperado",
+    "argument.computercraft.computer.distance": "Distância para a entidade",
+    "argument.computercraft.computer.family": "Família de Computadores",
+    "argument.computercraft.computer.id": "ID do Computador",
+    "argument.computercraft.computer.instance": "ID de Instância Única",
+    "argument.computercraft.computer.label": "Rótulo do Computador",
+    "argument.computercraft.computer.many_matching": "Vários computadores correspondendo a '%s' (instâncias %s)",
+    "argument.computercraft.computer.no_matching": "Sem computadores correspondentes a '%s'",
+    "argument.computercraft.tracking_field.no_field": "Campo desconhecido '%s'",
+    "argument.computercraft.unknown_computer_family": "Família de computador desconhecida '%s'",
     "block.computercraft.cable": "Cabo de Rede",
     "block.computercraft.computer_advanced": "Computador Avançado",
     "block.computercraft.computer_command": "Computador de Comandos",
@@ -23,43 +33,166 @@
     "commands.computercraft.desc": "O comando /computercraft providencia várias ferramentas de depuração e administração para controle e interação com computadores.",
     "commands.computercraft.dump.action": "Ver mais informação sobre este computador",
     "commands.computercraft.dump.desc": "Mostra o status de todos os computadores ou uma informação específica sobre um computador. Você pode especificar o id de instância do computador (ex.: 123), id do computador (ex.: #123) ou o rótulo (ex.: \"@MeuComputador\").",
+    "commands.computercraft.dump.open_path": "Ver arquivos deste computador",
     "commands.computercraft.dump.synopsis": "Mostra status de computadores.",
+    "commands.computercraft.generic.additional_rows": "%d linhas adicionais…",
+    "commands.computercraft.generic.exception": "Exceção não tratada (%s)",
+    "commands.computercraft.generic.no": "N",
+    "commands.computercraft.generic.yes": "S",
     "commands.computercraft.help.desc": "Mostra essa mensagem de ajuda",
     "commands.computercraft.help.no_children": "%s não tem sub-comandos",
     "commands.computercraft.help.no_command": "Comando '%s' não existe",
     "commands.computercraft.help.synopsis": "Providencia ajuda para um comando específico",
+    "commands.computercraft.queue.desc": "Envie um evento computer_command para um computador de comando, passando os argumentos adicionais. Isso é projetado principalmente para criadores de mapas, funcionando como uma versão mais amigável do computador do comando /trigger. Qualquer jogador pode executar o comando, que provavelmente será feito por meio do evento de clique de um componente de texto.",
+    "commands.computercraft.queue.synopsis": "Envie um evento computer_command para um computador de comando",
     "commands.computercraft.shutdown.desc": "Desliga os computadores em escuta ou todos caso não tenha sido especificado. Você pode especificar o id de instância do computador (ex.: 123), id do computador (ex.: #123) ou o rótulo (ex.: \"@MeuComputador\").",
     "commands.computercraft.shutdown.done": "Desliga %s/%s computadores",
     "commands.computercraft.shutdown.synopsis": "Desliga computadores remotamente.",
     "commands.computercraft.synopsis": "Vários comandos para controlar computadores.",
+    "commands.computercraft.tp.action": "Teletransportar para este computador",
+    "commands.computercraft.tp.desc": "Teletransporte para a localização de um computador. Você pode especificar o Id da instância do computador (por exemplo, 123) ou o Id do computador (por exemplo, #123).",
     "commands.computercraft.tp.synopsis": "Teleprota para um computador específico.",
+    "commands.computercraft.track.desc": "Rastreie quanto tempo os computadores executam, bem como quantos eventos eles manipulam. Isso apresenta informações de maneira semelhante ao /forge track e pode ser útil para diagnosticar lag.",
+    "commands.computercraft.track.dump.computer": "Computador",
+    "commands.computercraft.track.dump.desc": "Despeje os últimos resultados do rastreamento de computadores.",
+    "commands.computercraft.track.dump.no_timings": "Nenhum tempo disponível",
+    "commands.computercraft.track.dump.synopsis": "Despeje os últimos resultados de rastreamento",
+    "commands.computercraft.track.start.desc": "Comece a rastrear os tempos de execução e contagens de eventos de todos os computadores. Isso descartará os resultados de execuções anteriores.",
+    "commands.computercraft.track.start.stop": "Execute %s para parar o rastreamento e visualizar os resultados",
+    "commands.computercraft.track.start.synopsis": "Comece a rastrear todos os computadores",
+    "commands.computercraft.track.stop.action": "Clique para parar o rastreamento",
+    "commands.computercraft.track.stop.desc": "Parar de rastrear eventos de todos os computadores e tempos de execução",
+    "commands.computercraft.track.stop.not_enabled": "Não está rastreando computadores",
+    "commands.computercraft.track.stop.synopsis": "Parar de rastrear todos os computadores",
+    "commands.computercraft.track.synopsis": "Acompanhe os tempos de execução para computadores.",
     "commands.computercraft.turn_on.desc": "Liga os computadores em escuta. Você pode especificar o id de instância do computador (ex.: 123), id do computador (ex.: #123) ou o rótulo (ex.: \"@MeuComputador\").",
     "commands.computercraft.turn_on.done": "Ligou %s/%s computadores",
     "commands.computercraft.turn_on.synopsis": "Liga computadores remotamente.",
+    "commands.computercraft.view.action": "Visualizar este computador",
+    "commands.computercraft.view.desc": "Abra o terminal de um computador, permitindo o controle remoto de um computador. Isso não fornece acesso aos inventários das tartarugas. Você pode especificar o Id da instância do computador (por exemplo, 123) ou o Id do computador (por exemplo, #123).",
+    "commands.computercraft.view.not_player": "Não é possível abrir terminal para um não-jogador",
+    "commands.computercraft.view.synopsis": "Ver o terminal de um computador.",
+    "gui.computercraft.config.command_require_creative": "Computadores de comando requerem criativo",
+    "gui.computercraft.config.command_require_creative.tooltip": "Exigir que os jogadores estejam no modo criativo e tenham permissões de operador (opped) para interagir com computadores de comando. Este é o comportamento padrão dos blocos de comando no modo vanilla.",
     "gui.computercraft.config.computer_space_limit": "Limite de espaço dos Computadores (bytes)",
+    "gui.computercraft.config.computer_space_limit.tooltip": "O limite de espaço em disco para computadores e tartarugas, em bytes.",
     "gui.computercraft.config.default_computer_settings": "Configurações padrão para Computadores",
+    "gui.computercraft.config.default_computer_settings.tooltip": "Uma lista separada por vírgulas das configurações padrão do sistema a serem definidas em novos computadores. \nExemplo: \"shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false\" desativará todas as funcionalidades de autocompletar.",
+    "gui.computercraft.config.disabled_generic_methods": "Métodos genéricos desativados",
+    "gui.computercraft.config.disabled_generic_methods.tooltip": "Uma lista de métodos genéricos ou fontes de métodos a serem desativados. Métodos genéricos são aqueles adicionados a um bloco ou entidade de bloco quando não há um provedor de periféricos explícito. Isso inclui métodos de inventário (ou seja, inventory.getItemDetail, inventory.pushItems) e, se estiver usando Forge, os métodos fluid_storage e energy_storage. \nOs métodos nesta lista podem ser um grupo inteiro de métodos (computercraft:inventory) ou um único método (computercraft:inventory#pushItems).\n",
+    "gui.computercraft.config.execution": "Execução",
     "gui.computercraft.config.execution.computer_threads": "Threads por computador",
+    "gui.computercraft.config.execution.computer_threads.tooltip": "Defina o número de threads que os computadores podem utilizar. Um número maior significa que mais computadores podem ser executados ao mesmo tempo, mas pode causar lag. Observe que alguns mods podem não funcionar com uma contagem de threads superior a 1. Use com cautela. \nIntervalo: > 1",
+    "gui.computercraft.config.execution.max_main_computer_time": "Limite de tempo do computador por tick do servidor",
+    "gui.computercraft.config.execution.max_main_computer_time.tooltip": "O tempo máximo ideal que um computador pode executar em um tick, em milissegundos. \nObserve que é bastante provável que ultrapassemos esse limite, pois não há como saber exatamente quanto tempo uma operação levará - isso visa ser o limite superior do tempo médio. \nIntervalo: > 1",
+    "gui.computercraft.config.execution.max_main_global_time": "Limite de tempo global por tick do servidor",
+    "gui.computercraft.config.execution.max_main_global_time.tooltip": "O tempo máximo que pode ser gasto executando tarefas em um único tick, em milissegundos. \nObserve que é bastante provável que ultrapassemos esse limite, pois não há como saber exatamente quanto tempo uma operação levará - isso visa ser o limite superior do tempo médio. \nIntervalo: > 1",
+    "gui.computercraft.config.execution.tooltip": "Controla o comportamento de execução dos computadores. Isso é principalmente destinado ao ajuste fino dos servidores e, geralmente, não deve ser alterado.",
     "gui.computercraft.config.floppy_space_limit": "Limite de espaço dos Disquetes (bytes)",
+    "gui.computercraft.config.floppy_space_limit.tooltip": "O limite de espaço em disco para disquete em bytes.",
     "gui.computercraft.config.http": "HTTP",
+    "gui.computercraft.config.http.bandwidth": "Largura de banda",
+    "gui.computercraft.config.http.bandwidth.global_download": "Limite de download global",
+    "gui.computercraft.config.http.bandwidth.global_download.tooltip": "O número de bytes que podem ser baixados em um segundo. Isso é compartilhado entre todos os computadores. (bytes/s). \nIntervalo: > 1",
+    "gui.computercraft.config.http.bandwidth.global_upload": "Limite de upload global",
+    "gui.computercraft.config.http.bandwidth.global_upload.tooltip": "O número de bytes que podem ser enviados em um segundo. Isso é compartilhado entre todos os computadores. (bytes/s). \nIntervalo: > 1",
+    "gui.computercraft.config.http.bandwidth.tooltip": "Limita a banda usada pelos computadores.",
     "gui.computercraft.config.http.enabled": "Habilitar a biblioteca de HTTP",
+    "gui.computercraft.config.http.enabled.tooltip": "Ative a API \"http\" nos Computadores. Desativar isso também desativa os programas \"pastebin\" e \"wget\", dos quais muitos usuários dependem. É recomendado deixar isso ativado e usar a opção de configuração \"rules\" para impor um controle mais detalhado.",
     "gui.computercraft.config.http.max_requests": "Limite de conexões paralelas",
+    "gui.computercraft.config.http.max_requests.tooltip": "O número de solicitações Http que um computador pode fazer ao mesmo tempo. Solicitações adicionais serão enfileiradas e enviadas quando as solicitações em execução forem concluídas. Defina como 0 para ilimitado.\nIntervalo: > 0",
     "gui.computercraft.config.http.max_websockets": "Limite de conexões websocket",
+    "gui.computercraft.config.http.max_websockets.tooltip": "O número de websockets que um computador pode ter abertos ao mesmo tempo.\nIntervalo: > 1",
+    "gui.computercraft.config.http.proxy": "Proxy",
+    "gui.computercraft.config.http.proxy.host": "Nome de host",
+    "gui.computercraft.config.http.proxy.host.tooltip": "O nome do host ou endereço IP do servidor proxy.",
+    "gui.computercraft.config.http.proxy.port": "Porta",
+    "gui.computercraft.config.http.proxy.port.tooltip": "A porta do servidor proxy.\nIntervalo: 1 ~ 65536",
+    "gui.computercraft.config.http.proxy.tooltip": "Tunéis de solicitações HTTP e websocket através de um servidor proxy. Afeta apenas as regras HTTP com \"use_proxy\" definido como verdadeiro (desligado por padrão). Se a autenticação for necessária para o proxy, crie um arquivo \"computercraft-proxy.pw\" no mesmo diretório que \"computercraft-server.toml\", contendo o nome de usuário e a senha separados por dois pontos, por exemplo, \"meuusuario:minhasenha\". Para proxies SOCKS4, apenas o nome de usuário é necessário.",
+    "gui.computercraft.config.http.proxy.type": "Tipo de proxy",
+    "gui.computercraft.config.http.proxy.type.tooltip": "O tipo de proxy para usar.\nValores permitidos: HTTP, HTTPS, SOCKS4, SOCKS5",
+    "gui.computercraft.config.http.rules": "Regras Permitir/Negar",
+    "gui.computercraft.config.http.rules.tooltip": "Uma lista de regras que controlam o comportamento da API \"http\" para domínios ou IPs específicos. Cada regra corresponde a um nome de host e uma porta opcional, e então define várias propriedades para a solicitação. As regras são avaliadas em ordem, o que significa que regras anteriores sobrescrevem as posteriores.\n\nPropriedades válidas:\n- \"host\" (obrigatório): O domínio ou endereço IP que esta regra corresponde. Isso pode ser um nome de domínio (\"pastebin.com\"), um curinga (\"*.pastebin.com\") ou notação CIDR (\"127.0.0.0/8\").\n- \"port\" (opcional): Corresponder apenas a solicitações para uma porta específica, como 80 ou 443.\n\n- \"action\" (opcional): Se permitir ou negar esta solicitação.\n- \"max_download\" (opcional): O tamanho máximo (em bytes) que um computador pode baixar nesta solicitação.\n- \"max_upload\" (opcional): O tamanho máximo (em bytes) que um computador pode enviar em uma solicitação.\n- \"max_websocket_message\" (opcional): O tamanho máximo (em bytes) que um computador pode enviar ou receber em um pacote websocket.\n- \"use_proxy\" (opcional): Habilitar o uso do proxy HTTP/SOCKS se estiver configurado.",
+    "gui.computercraft.config.http.tooltip": "Controla a API HTTP",
     "gui.computercraft.config.http.websocket_enabled": "Habilitar websockets",
+    "gui.computercraft.config.http.websocket_enabled.tooltip": "Habilitar o uso de websockets Http. Isso requer que a opção \"http_enable\" também esteja definida como verdadeira.",
     "gui.computercraft.config.log_computer_errors": "Registrar erros de computadores",
+    "gui.computercraft.config.log_computer_errors.tooltip": "Registrar exceções lançadas por periféricos e outros objetos Lua. Isso facilita a depuração de problemas para os autores de mods, mas pode resultar em excesso de registros caso as pessoas utilizem métodos com falhas.",
     "gui.computercraft.config.maximum_open_files": "Número máximo de arquivos em um computador",
+    "gui.computercraft.config.maximum_open_files.tooltip": "Defina quantos arquivos um computador pode ter aberto ao mesmo tempo. Defina como 0 para ilimitado.\nIntervalo: > 0",
+    "gui.computercraft.config.monitor_distance": "Distância do monitor",
+    "gui.computercraft.config.monitor_distance.tooltip": "A distância máxima que os monitores renderizarão. Isso padrão é o limite padrão de entidades de tile, mas pode ser estendido se você desejar construir monitores maiores. \nIntervalo: 16 ~ 1024",
+    "gui.computercraft.config.monitor_renderer": "Renderizador do monitor",
+    "gui.computercraft.config.monitor_renderer.tooltip": "O renderizador a ser utilizado para os monitores. Geralmente, isso deve ser mantido em \"best\" - se os monitores apresentarem problemas de desempenho, você pode querer experimentar renderizadores alternativos. \nValores Permitidos: BEST, TBO, VBO",
     "gui.computercraft.config.peripheral": "Periféricos",
     "gui.computercraft.config.peripheral.command_block_enabled": "Habilitar periférico do bloco de comando",
+    "gui.computercraft.config.peripheral.command_block_enabled.tooltip": "Habilitar periférico do bloco de comando",
     "gui.computercraft.config.peripheral.max_notes_per_tick": "Número de notas que um computador pode tocar simultâneamente",
+    "gui.computercraft.config.peripheral.max_notes_per_tick.tooltip": "Quantidade máxima de notas que um alto-falante pode jogar de uma vez.\nIntervalo: > 1",
     "gui.computercraft.config.peripheral.modem_high_altitude_range": "Alcance do modem (altitude elevada)",
+    "gui.computercraft.config.peripheral.modem_high_altitude_range.tooltip": "O intervalo de Modems Sem Fio a altitude máxima em tempo limpo, em metros.\nIntervalo: 0 ~ 100000",
     "gui.computercraft.config.peripheral.modem_high_altitude_range_during_storm": "Alcance do modem (altitude elevada, clima ruim)",
+    "gui.computercraft.config.peripheral.modem_high_altitude_range_during_storm.tooltip": "O intervalo de Modems Sem Fio à altitude máxima em clima tempestuoso, em metros.\nIntervalo: 0 ~ 100000",
     "gui.computercraft.config.peripheral.modem_range": "Alcance do modem (padrão)",
+    "gui.computercraft.config.peripheral.modem_range.tooltip": "O alcance de Modems Sem Fio a baixa altitude em clima limpo, em metros.\nIntervalo: 0 ~ 100000",
     "gui.computercraft.config.peripheral.modem_range_during_storm": "Alcance do modem (clima ruim)",
+    "gui.computercraft.config.peripheral.modem_range_during_storm.tooltip": "A variedade de Modems Sem Fio a baixa altitude em clima tempestuoso, em metros.\nIntervalo: 0 ~ 100000",
+    "gui.computercraft.config.peripheral.monitor_bandwidth": "Monitorar banda",
+    "gui.computercraft.config.peripheral.monitor_bandwidth.tooltip": "O limite de quanta informação de monitor pode ser enviada *por tick*. Nota:\n- A largura de banda é medida antes da compressão, então os dados enviados ao cliente são menores.\n- Isso ignora o número de jogadores para os quais um pacote é enviado. Atualizar um monitor para um jogador consome o mesmo limite de largura de banda que enviar para 20.\n- Um monitor de tamanho completo envia ~25kb de dados. Portanto, o padrão (1MB) permite que ~40 monitores sejam atualizados em um único tick.  \nDefina como 0 para desativar.  \nIntervalo: > 0",
+    "gui.computercraft.config.peripheral.tooltip": "Várias opções relacionadas com os periféricos.",
+    "gui.computercraft.config.term_sizes": "Tamanhos do terminal",
+    "gui.computercraft.config.term_sizes.computer": "Computador",
+    "gui.computercraft.config.term_sizes.computer.height": "Altura do terminal",
+    "gui.computercraft.config.term_sizes.computer.height.tooltip": "Intervalo: 1 ~ 255",
+    "gui.computercraft.config.term_sizes.computer.tooltip": "Tamanho do terminal dos computadores portátil.",
+    "gui.computercraft.config.term_sizes.computer.width": "Largura do terminal",
+    "gui.computercraft.config.term_sizes.computer.width.tooltip": "Intervalo: 1 ~ 255",
+    "gui.computercraft.config.term_sizes.monitor": "Monitor",
+    "gui.computercraft.config.term_sizes.monitor.height": "Altura máxima da monitor",
+    "gui.computercraft.config.term_sizes.monitor.height.tooltip": "Intervalo: 1 ~ 32",
+    "gui.computercraft.config.term_sizes.monitor.tooltip": "Tamanho máximo de monitores (em blocos).",
+    "gui.computercraft.config.term_sizes.monitor.width": "Largura máxima do monitor",
+    "gui.computercraft.config.term_sizes.monitor.width.tooltip": "Intervalo: 1 ~ 32",
+    "gui.computercraft.config.term_sizes.pocket_computer": "Computador Portátil",
+    "gui.computercraft.config.term_sizes.pocket_computer.height": "Altura do terminal",
+    "gui.computercraft.config.term_sizes.pocket_computer.height.tooltip": "Intervalo: 1 ~ 255",
+    "gui.computercraft.config.term_sizes.pocket_computer.tooltip": "Tamanho do terminal dos computadores portátil.",
+    "gui.computercraft.config.term_sizes.pocket_computer.width": "Largura do terminal",
+    "gui.computercraft.config.term_sizes.pocket_computer.width.tooltip": "Intervalo: 1 ~ 255",
+    "gui.computercraft.config.term_sizes.tooltip": "Configure o tamanho dos terminais de vários computadores. Terminais maiores exigem mais largura de banda, portanto, use com cuidado.",
     "gui.computercraft.config.turtle": "Tartarugas",
     "gui.computercraft.config.turtle.advanced_fuel_limit": "Limite de combustível de Tartarugas Avançadas",
+    "gui.computercraft.config.turtle.advanced_fuel_limit.tooltip": "O limite de combustível para Advanced Turtles. \nIntervalo: > 0",
     "gui.computercraft.config.turtle.can_push": "Tartarugas podem empurrar entidades",
+    "gui.computercraft.config.turtle.can_push.tooltip": "Se definido como verdadeiro, as Tartarugas empurrarão entidades para o lado em vez de parar, caso haja espaço para isso.",
     "gui.computercraft.config.turtle.need_fuel": "Habilitar combustível",
+    "gui.computercraft.config.turtle.need_fuel.tooltip": "Defina se as tartarugas requerem combustível para se mover.",
     "gui.computercraft.config.turtle.normal_fuel_limit": "Limite de combustível de Tartarugas",
+    "gui.computercraft.config.turtle.normal_fuel_limit.tooltip": "O limite de combustível para Advanced Turtles. \nIntervalo: > 0",
+    "gui.computercraft.config.turtle.tooltip": "Várias opções relacionadas às Tartarugas.",
+    "gui.computercraft.config.upload_max_size": "Tamanho máximo para upload de arquivos (bytes)",
+    "gui.computercraft.config.upload_max_size.tooltip": "O limite de tamanho de upload de arquivos, em bytes. Deve estar na faixa de 1 KiB a 16 MiB. \nTenha em mente que os uploads são processados em um único tick - arquivos grandes ou desempenho de rede ruim podem travar a thread de rede. E cuidado com o espaço em disco! \nIntervalo: 1024 ~ 16777216",
+    "gui.computercraft.config.upload_nag_delay": "Atraso de notificação de upload",
+    "gui.computercraft.config.upload_nag_delay.tooltip": "O atraso em segundos após o qual seremos notificados sobre importações não tratadas. Defina como 0 para desabilitar. \nIntervalo: 0 ~ 60",
+    "gui.computercraft.pocket_computer_overlay": "Computador portátil aberto. Pressione ESC para fechar.",
+    "gui.computercraft.terminal": "Terminal do Computador",
+    "gui.computercraft.tooltip.computer_id": "ID do Computador: %s",
     "gui.computercraft.tooltip.copy": "Copiar para a área de transferência",
+    "gui.computercraft.tooltip.disk_id": "ID do Disco: %s",
+    "gui.computercraft.tooltip.terminate": "Parar o código atualmente em execução",
+    "gui.computercraft.tooltip.terminate.key": "Segure Ctrl+T",
+    "gui.computercraft.tooltip.turn_off": "Desligar este computador",
+    "gui.computercraft.tooltip.turn_off.key": "Segure Ctrl+S",
+    "gui.computercraft.tooltip.turn_on": "Ligar este computador",
+    "gui.computercraft.upload.failed": "Falha no Upload",
+    "gui.computercraft.upload.failed.computer_off": "Você deve ligar o computador antes de fazer o upload de arquivos.",
+    "gui.computercraft.upload.failed.corrupted": "Arquivos corrompidos ao dar upload. Por favor, tente novamente.",
+    "gui.computercraft.upload.failed.generic": "Upload de arquivos falhou (%s)",
+    "gui.computercraft.upload.failed.name_too_long": "Nomes de arquivos são muito longos para dar upload.",
+    "gui.computercraft.upload.failed.too_many_files": "Não é possível dar upload nesta quantidade de arquivos.",
+    "gui.computercraft.upload.failed.too_much": "Seus arquivos são muito grandes para dar upload.",
+    "gui.computercraft.upload.no_response": "Transferindo Arquivos",
+    "gui.computercraft.upload.no_response.msg": "Seu computador não usou os arquivos transferidos. Você pode precisar executar o programa %s e tentar novamente.",
     "item.computercraft.disk": "Disquete",
     "item.computercraft.pocket_computer_advanced": "Computador Portátil Avançado",
     "item.computercraft.pocket_computer_advanced.upgraded": "Computador Portátil Avançado %s",
@@ -69,6 +202,25 @@
     "item.computercraft.printed_page": "Página Impressa",
     "item.computercraft.printed_pages": "Páginas Impressas",
     "item.computercraft.treasure_disk": "Disquete",
+    "itemGroup.computercraft": "ComputerCraft",
+    "tag.item.computercraft.computer": "Computadores",
+    "tag.item.computercraft.monitor": "Monitores",
+    "tag.item.computercraft.turtle": "Tartarugas",
+    "tag.item.computercraft.wired_modem": "Modems com Fio",
+    "tracking_field.computercraft.avg": "%s (média)",
+    "tracking_field.computercraft.computer_tasks.name": "Tarefas",
+    "tracking_field.computercraft.count": "%s (contagem)",
+    "tracking_field.computercraft.fs.name": "Operações de sistema",
+    "tracking_field.computercraft.http_download.name": "Download HTTP",
+    "tracking_field.computercraft.http_requests.name": "Solicitações HTTP",
+    "tracking_field.computercraft.http_upload.name": "Upload de HTTP",
+    "tracking_field.computercraft.java_allocation.name": "Alocações Java",
+    "tracking_field.computercraft.max": "%s (máximo)",
+    "tracking_field.computercraft.peripheral.name": "Chamadas Periféricas",
+    "tracking_field.computercraft.server_tasks.name": "Tarefas do servidor",
+    "tracking_field.computercraft.turtle_ops.name": "Operações de tartaruga",
+    "tracking_field.computercraft.websocket_incoming.name": "Entrada do Websocket",
+    "tracking_field.computercraft.websocket_outgoing.name": "Saída do Websocket",
     "upgrade.computercraft.speaker.adjective": "(Alto-Falante)",
     "upgrade.computercraft.wireless_modem_advanced.adjective": "Ender",
     "upgrade.computercraft.wireless_modem_normal.adjective": "sem Fio",
diff --git a/projects/common/src/main/resources/assets/computercraft/lang/uk_ua.json b/projects/common/src/main/resources/assets/computercraft/lang/uk_ua.json
index 34b0aeccfb..8aad479d8d 100644
--- a/projects/common/src/main/resources/assets/computercraft/lang/uk_ua.json
+++ b/projects/common/src/main/resources/assets/computercraft/lang/uk_ua.json
@@ -72,6 +72,7 @@
     "gui.computercraft.config.computer_space_limit.tooltip": "Обмеження на займаєме місце на диску комп'ютерами та черепахами, в байтах.",
     "gui.computercraft.config.default_computer_settings": "Налаштування комп'ютера за замовчуванням",
     "gui.computercraft.config.default_computer_settings.tooltip": "Список лашатувань за замовчуванням, розділених комою, що будуть нашалтовані на нових комп'ютерах\nНаприклад: \"shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false\"\nвідключить усі автодоповнення.",
+    "gui.computercraft.config.disabled_generic_methods.tooltip": "Список загальних методів або джерел методів, які слід вимкнути. Загальні методи - це методи, додані до блоку/сутності блоку, коли немає явного постачальника периферії. До них належать методи інвентаризації (наприклад, inventory.getItemDetail, inventory.pushItems), а також (якщо на Forge), методи fluid_storage та energy_storage.\nМетоди у цьому списку можуть бути як цілою групою методів (computercraft:inventory),\nтак і одним методом (computercraft:inventory#pushItems).\n",
     "gui.computercraft.config.execution": "Виконання",
     "gui.computercraft.config.execution.computer_threads": "Потоки для комп'ютерів",
     "gui.computercraft.config.execution.computer_threads.tooltip": "Встановлює кількість потоків, на яких запускаються комп'ютери. Більше число\nозначає більшу кількість комп'ютерів, які працюють паралельно, але може призвести до проблем із продуктивністю.\nЗауважте, що деякі модифікації можуть не працювати із кількістю потоків більше за 1. Використовуйте з обережністю.\nОбмеження: > 1",
@@ -86,6 +87,13 @@
     "gui.computercraft.config.http.bandwidth": "Трафік",
     "gui.computercraft.config.http.bandwidth.global_download": "Глобальне обмеження на завантаження",
     "gui.computercraft.config.http.bandwidth.global_download.tooltip": "Число байтів, які можуть бути завантажені в хвилину. Це обмеження на всі комп'ютери відразу (байти в секунду)\nОбмеження: > 1",
+    "gui.computercraft.config.http.bandwidth.global_upload.tooltip": "Кількість байт, яку можна завантажити за секунду. Вона є спільною для всіх комп'ютерів. (байт/с)",
+    "gui.computercraft.config.http.max_websockets.tooltip": "Кількість вебсокетів, які комп'ютер може мати відкритими одночасно. Діапазон: > 1",
+    "gui.computercraft.config.http.proxy.tooltip": "Тунелює HTTP-запити і запити веб-сокетів через проксі-сервер. Впливає лише на HTTP-правила з параметром \"use_proxy\", встановленим у true (за замовчуванням вимкнено). Якщо для проксі-сервера потрібна автентифікація, створіть файл \"computercraft-proxy.pw\" у тому ж каталозі, що і \"computercraft-server.toml\", що містить ім'я користувача і пароль, розділені двокрапкою, наприклад, \"myuser:mypassword\". Для проксі SOCKS4 потрібно лише ім'я користувача.",
+    "gui.computercraft.config.log_computer_errors.tooltip": "Журнал винятків, спричинених периферійними пристроями та іншими об'єктами Lua. Це полегшує авторам мод налагодження проблем, але може призвести до спаму у журналі, якщо люди використовуватимуть некоректні методи.",
+    "gui.computercraft.config.monitor_distance.tooltip": "Максимальна відстань, на якій будуть візуалізуватись монітори. За замовчуванням це значення дорівнює стандартній відстані між плитками, але може бути збільшено, якщо ви бажаєте створити більші монітори. Діапазон: 16 ~ 1024",
+    "gui.computercraft.config.monitor_renderer": "Візуалізація монітора",
+    "gui.computercraft.config.monitor_renderer.tooltip": "Візуалізатор, який буде використовуватися для моніторів. Зазвичай цей параметр слід залишати на рівні \"найкращий\" - якщо у моніторів є проблеми з продуктивністю, ви можете поекспериментувати з альтернативними Візуалізаторами.\nДопустимі значення: BEST, TBO, VBO",
     "gui.computercraft.pocket_computer_overlay": "Кишеньковий комп'ютер відкритий. Натисніть ESC, щоб закрити.",
     "gui.computercraft.tooltip.computer_id": "Ідентифікатор комп'ютера: %s",
     "gui.computercraft.tooltip.copy": "Скопійовано в Буфер обміну",

From 31da2555cb2f6538fa51be655c3bba32edfee86c Mon Sep 17 00:00:00 2001
From: Jonathan Coates 
Date: Fri, 15 Nov 2024 08:22:05 +0000
Subject: [PATCH 29/39] Bump CC:T to 1.114.0

---
 gradle.properties                                   |  2 +-
 .../data/computercraft/lua/rom/help/changelog.md    | 12 ++++++++++++
 .../data/computercraft/lua/rom/help/whatsnew.md     | 13 ++++++++-----
 3 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/gradle.properties b/gradle.properties
index c63263ae34..6d72cad023 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -10,7 +10,7 @@ kotlin.jvm.target.validation.mode=error
 
 # Mod properties
 isUnstable=false
-modVersion=1.113.1
+modVersion=1.114.0
 
 # Minecraft properties: We want to configure this here so we can read it in settings.gradle
 mcVersion=1.20.1
diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md b/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md
index 6463589096..fd0e90613a 100644
--- a/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md
+++ b/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md
@@ -1,3 +1,15 @@
+# New features in CC: Tweaked 1.114.0
+
+* Add redstone relay peripheral.
+* Add support for `math.atan(x, y)`.
+* Update several translations.
+
+Several bug fixes:
+* Fix pocket upgrades not appearing after crafting.
+* Cancel `rednet.receive` and `Websocket.receive` timers after a message is received.
+* Fix several issues with parsing and printing large doubles.
+* Fix in-hand pocket computer being blank after changing dimension.
+
 # New features in CC: Tweaked 1.113.1
 
 * Update Japanese translation (konumatakaki).
diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md b/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md
index c3684a6322..7828adb8a5 100644
--- a/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md
+++ b/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md
@@ -1,10 +1,13 @@
-New features in CC: Tweaked 1.113.1
+New features in CC: Tweaked 1.114.0
 
-* Update Japanese translation (konumatakaki).
-* Improve performance of `textutils.urlEncode`.
+* Add redstone relay peripheral.
+* Add support for `math.atan(x, y)`.
+* Update several translations.
 
 Several bug fixes:
-* Fix overflow when converting recursive objects from Java to Lua.
-* Fix websocket compression not working under Forge.
+* Fix pocket upgrades not appearing after crafting.
+* Cancel `rednet.receive` and `Websocket.receive` timers after a message is received.
+* Fix several issues with parsing and printing large doubles.
+* Fix in-hand pocket computer being blank after changing dimension.
 
 Type "help changelog" to see the full version history.

From f776b1715055cc825d463a17ec0b9f3264b98ca2 Mon Sep 17 00:00:00 2001
From: Jonathan Coates 
Date: Fri, 15 Nov 2024 15:32:40 +0000
Subject: [PATCH 30/39] Fix argument order of math.atan in changelog

---
 .../main/resources/data/computercraft/lua/rom/help/changelog.md | 2 +-
 .../main/resources/data/computercraft/lua/rom/help/whatsnew.md  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md b/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md
index fd0e90613a..514d9b0503 100644
--- a/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md
+++ b/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md
@@ -1,7 +1,7 @@
 # New features in CC: Tweaked 1.114.0
 
 * Add redstone relay peripheral.
-* Add support for `math.atan(x, y)`.
+* Add support for `math.atan(y, x)`.
 * Update several translations.
 
 Several bug fixes:
diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md b/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md
index 7828adb8a5..a151ee199b 100644
--- a/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md
+++ b/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md
@@ -1,7 +1,7 @@
 New features in CC: Tweaked 1.114.0
 
 * Add redstone relay peripheral.
-* Add support for `math.atan(x, y)`.
+* Add support for `math.atan(y, x)`.
 * Update several translations.
 
 Several bug fixes:

From 63bdc2537cbe5d7b731e43e1fe40951b7d1e0950 Mon Sep 17 00:00:00 2001
From: Jonathan Coates 
Date: Fri, 15 Nov 2024 18:43:28 +0000
Subject: [PATCH 31/39] Fix monitor events using the wrong computer set

Fixes #2010
---
 .../shared/peripheral/monitor/MonitorBlockEntity.java           | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlockEntity.java
index 928590b492..936a753cd0 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlockEntity.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorBlockEntity.java
@@ -485,7 +485,7 @@ private void eachComputer(Consumer fun) {
                 var monitor = getLoadedMonitor(x, y).getMonitor();
                 if (monitor == null) continue;
 
-                computers.forEach(fun);
+                monitor.computers.forEach(fun);
             }
         }
     }

From 1d7d8006d4edc6db09e0dda9f3bd537492f9d3e3 Mon Sep 17 00:00:00 2001
From: Jonathan Coates 
Date: Sat, 16 Nov 2024 15:19:00 +0000
Subject: [PATCH 32/39] Stop publishing to CurseForge

Been dragging my feet over this for a while now, but increasingly
uncomfortable with Overwolf. I'm not going to delete the project (or any
existing versions), just not publish any new versions there.
---
 README.md                                     |  4 +---
 buildSrc/build.gradle.kts                     |  1 -
 .../cc-tweaked.mod-publishing.gradle.kts      | 19 -------------------
 doc/index.md                                  |  3 +--
 gradle/libs.versions.toml                     |  2 --
 5 files changed, 2 insertions(+), 27 deletions(-)

diff --git a/README.md b/README.md
index f37016ec7d..3b1859631c 100644
--- a/README.md
+++ b/README.md
@@ -11,14 +11,13 @@ SPDX-License-Identifier: MPL-2.0
 
 
 [![Current build status](https://github.com/cc-tweaked/CC-Tweaked/workflows/Build/badge.svg)](https://github.com/cc-tweaked/CC-Tweaked/actions "Current build status")
-[![Download CC: Tweaked on CurseForge](https://img.shields.io/static/v1?label=Download&message=CC:%20Tweaked&color=E04E14&logoColor=E04E14&logo=CurseForge)][CurseForge]
 [![Download CC: Tweaked on Modrinth](https://img.shields.io/static/v1?label=Download&color=00AF5C&logoColor=00AF5C&logo=Modrinth&message=CC:%20Tweaked)][Modrinth]
 
 CC: Tweaked is a mod for Minecraft which adds programmable computers, turtles and more to the game. A fork of the
 much-beloved [ComputerCraft], it continues its legacy with improved performance and stability, along with a wealth of
 new features.
 
-CC: Tweaked can be installed from [CurseForge] or [Modrinth]. It runs on both [Minecraft Forge] and [Fabric].
+CC: Tweaked can be installed from [Modrinth]. It runs on both [Minecraft Forge] and [Fabric].
 
 ## Contributing
 Any contribution is welcome, be that using the mod, reporting bugs or contributing code. If you want to get started
@@ -83,7 +82,6 @@ We bundle the API sources with the jar, so documentation should be easily viewab
 the generated documentation [can be browsed online](https://tweaked.cc/javadoc/).
 
 [computercraft]: https://github.com/dan200/ComputerCraft "ComputerCraft on GitHub"
-[curseforge]: https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked from CurseForge"
 [modrinth]: https://modrinth.com/mod/gu7yAYhd "Download CC: Tweaked from Modrinth"
 [Minecraft Forge]: https://files.minecraftforge.net/ "Download Minecraft Forge."
 [Fabric]: https://fabricmc.net/use/installer/ "Download Fabric."
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
index f95a9c1d5d..90b6c23913 100644
--- a/buildSrc/build.gradle.kts
+++ b/buildSrc/build.gradle.kts
@@ -49,7 +49,6 @@ dependencies {
     implementation(libs.kotlin.plugin)
     implementation(libs.spotless)
 
-    implementation(libs.curseForgeGradle)
     implementation(libs.fabric.loom)
     implementation(libs.forgeGradle)
     implementation(libs.ideaExt)
diff --git a/buildSrc/src/main/kotlin/cc-tweaked.mod-publishing.gradle.kts b/buildSrc/src/main/kotlin/cc-tweaked.mod-publishing.gradle.kts
index 35e1da36bb..f83cd9c77c 100644
--- a/buildSrc/src/main/kotlin/cc-tweaked.mod-publishing.gradle.kts
+++ b/buildSrc/src/main/kotlin/cc-tweaked.mod-publishing.gradle.kts
@@ -2,11 +2,9 @@
 //
 // SPDX-License-Identifier: MPL-2.0
 
-import net.darkhax.curseforgegradle.TaskPublishCurseForge
 import cc.tweaked.gradle.setProvider
 
 plugins {
-    id("net.darkhax.curseforgegradle")
     id("com.modrinth.minotaur")
     id("cc-tweaked.publishing")
 }
@@ -25,23 +23,6 @@ val isUnstable = project.properties["isUnstable"] == "true"
 val modVersion: String by extra
 val mcVersion: String by extra
 
-val publishCurseForge by tasks.registering(TaskPublishCurseForge::class) {
-    group = PublishingPlugin.PUBLISH_TASK_GROUP
-    description = "Upload artifacts to CurseForge"
-
-    apiToken = findProperty("curseForgeApiKey") ?: ""
-    enabled = apiToken != ""
-
-    val mainFile = upload("282001", modPublishing.output)
-    mainFile.changelog =
-        "Release notes can be found on the [GitHub repository](https://github.com/cc-tweaked/CC-Tweaked/releases/tag/v$mcVersion-$modVersion)."
-    mainFile.changelogType = "markdown"
-    mainFile.releaseType = if (isUnstable) "alpha" else "release"
-    mainFile.gameVersions.add(mcVersion)
-}
-
-tasks.publish { dependsOn(publishCurseForge) }
-
 modrinth {
     token.set(findProperty("modrinthApiKey") as String? ?: "")
     projectId.set("gu7yAYhd")
diff --git a/doc/index.md b/doc/index.md
index 86f64f65b1..cecb2ac158 100644
--- a/doc/index.md
+++ b/doc/index.md
@@ -16,7 +16,7 @@ CC: Tweaked is a mod for Minecraft which adds programmable computers, turtles an
 much-beloved [ComputerCraft], it continues its legacy with improved performance and stability, along with a wealth of
 new features.
 
-CC: Tweaked can be installed from [CurseForge] or [Modrinth]. It runs on both [Minecraft Forge] and [Fabric].
+CC: Tweaked can be installed from [Modrinth]. It runs on both [Minecraft Forge] and [Fabric].
 
 ## Features
 Controlled using the [Lua programming language][lua], CC: Tweaked's computers provides all the tools you need to start
@@ -62,7 +62,6 @@ CC: Tweaked lives on [GitHub]. If you've got any ideas, feedback or bugs please
 [github]: https://github.com/cc-tweaked/CC-Tweaked/ "CC: Tweaked on GitHub"
 [bug]: https://github.com/cc-tweaked/CC-Tweaked/issues/new/choose
 [computercraft]: https://github.com/dan200/ComputerCraft "ComputerCraft on GitHub"
-[curseforge]: https://minecraft.curseforge.com/projects/cc-tweaked "Download CC: Tweaked from CurseForge"
 [modrinth]: https://modrinth.com/mod/gu7yAYhd "Download CC: Tweaked from Modrinth"
 [forge]: https://files.minecraftforge.net/ "Download Minecraft Forge."
 [Minecraft Forge]: https://files.minecraftforge.net/ "Download Minecraft Forge."
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 3c103a0858..ada42638e2 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -58,7 +58,6 @@ jmh = "1.37"
 # Build tools
 cctJavadoc = "1.8.3"
 checkstyle = "10.14.1"
-curseForgeGradle = "1.0.14"
 errorProne-core = "2.27.0"
 errorProne-plugin = "3.1.0"
 fabric-loom = "1.7.1"
@@ -145,7 +144,6 @@ lwjgl-glfw = { module = "org.lwjgl:lwjgl-glfw" }
 # Build tools
 cctJavadoc = { module = "cc.tweaked:cct-javadoc", version.ref = "cctJavadoc" }
 checkstyle = { module = "com.puppycrawl.tools:checkstyle", version.ref = "checkstyle" }
-curseForgeGradle = { module = "net.darkhax.curseforgegradle:CurseForgeGradle", version.ref = "curseForgeGradle" }
 errorProne-annotations = { module = "com.google.errorprone:error_prone_annotations", version.ref = "errorProne-core" }
 errorProne-api = { module = "com.google.errorprone:error_prone_check_api", version.ref = "errorProne-core" }
 errorProne-core = { module = "com.google.errorprone:error_prone_core", version.ref = "errorProne-core" }

From cddb8fec112abd5c22b377461c3e94c37f4c944a Mon Sep 17 00:00:00 2001
From: Jonathan Coates 
Date: Tue, 19 Nov 2024 21:35:00 +0000
Subject: [PATCH 33/39] Fix crash when lectern has no item

This should never happen in practice, but might happen when using
/setblock or after world corruption, so let's be careful here.

Closes #2014
---
 .../computercraft/shared/lectern/CustomLecternBlockEntity.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/projects/common/src/main/java/dan200/computercraft/shared/lectern/CustomLecternBlockEntity.java b/projects/common/src/main/java/dan200/computercraft/shared/lectern/CustomLecternBlockEntity.java
index ee124ed154..ea27c596dd 100644
--- a/projects/common/src/main/java/dan200/computercraft/shared/lectern/CustomLecternBlockEntity.java
+++ b/projects/common/src/main/java/dan200/computercraft/shared/lectern/CustomLecternBlockEntity.java
@@ -119,7 +119,7 @@ public Packet getUpdatePacket() {
     @Override
     public CompoundTag getUpdateTag() {
         var tag = super.getUpdateTag();
-        tag.put(NBT_ITEM, item.save(new CompoundTag()));
+        if (!item.isEmpty()) tag.put(NBT_ITEM, item.save(new CompoundTag()));
         return tag;
     }
 

From d1a6b043c2e578d9921770f14fee236b6b473af9 Mon Sep 17 00:00:00 2001
From: Jonathan Coates 
Date: Sat, 23 Nov 2024 08:15:28 +0000
Subject: [PATCH 34/39] Clean up monitor cursor rendering

 - Use the correct index count for the cursor quad. Monitors are now
   rendered as quads, rather than triangles.
 - *Skip* rendering the cursor vertex, rather than additionally
   rendering it.

I confess, I'm baffled how this code was ever written. From what I can
tell, this has been broken since it was first introduced in
4228011b848e99de64eb79c26598d81490c32bad, and I'm sure I tested it then.

Fixes #2013. Probably.
---
 .../client/render/monitor/MonitorBlockEntityRenderer.java | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorBlockEntityRenderer.java b/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorBlockEntityRenderer.java
index 8e58d42b2c..43ca16ac7a 100644
--- a/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorBlockEntityRenderer.java
+++ b/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorBlockEntityRenderer.java
@@ -176,7 +176,7 @@ private static void renderTerminal(
                     var size = DirectFixedWidthFontRenderer.getVertexCount(terminal);
 
                     // In an ideal world we could upload these both into one buffer. However, we can't render VBOs with
-                    // and starting and ending offset, and so need to use two buffers instead.
+                    // a starting and ending offset, and so need to use two buffers instead.
 
                     renderToBuffer(backgroundBuffer, size, sink ->
                         DirectFixedWidthFontRenderer.drawTerminalBackground(sink, 0, 0, terminal, yMargin, yMargin, xMargin, xMargin));
@@ -208,10 +208,10 @@ private static void renderTerminal(
                 foregroundBuffer.bind();
                 foregroundBuffer.drawWithShader(
                     matrix, RenderSystem.getProjectionMatrix(), RenderTypes.getTerminalShader(),
-                    // As mentioned in the above comment, render the extra cursor quad if it is visible this frame. Each
-                    // // quad has an index count of 6.
+                    // Skip the cursor quad if it is not visible this frame.
                     FixedWidthFontRenderer.isCursorVisible(terminal) && FrameInfo.getGlobalCursorBlink()
-                        ? foregroundBuffer.getIndexCount() + 6 : foregroundBuffer.getIndexCount()
+                        ? foregroundBuffer.getIndexCount()
+                        : foregroundBuffer.getIndexCount() - RenderTypes.TERMINAL.mode().indexCount(4)
                 );
 
                 // Clear state

From 7af2c1432737d3bc7c55058788dec6e583c3eed0 Mon Sep 17 00:00:00 2001
From: Jonathan Coates 
Date: Sat, 23 Nov 2024 08:53:54 +0000
Subject: [PATCH 35/39] Move block entity component fixes to separate fixer

Some mods run their own datafixer chain, rather than piggybacking on top
of vanilla's. This is A BAD IDEA, but what can you do. If such a mod
tries to use ItemStackComponentizationFix in their own schema, then
CC:T's mixins will try to look up the turtle block entitie, and fail (as
they're not registered under the modded schema).

We now inject the block entity fix as a separate fixer, rather than
abusing ItemStackComponentizationFix.

See #2012
---
 .../computercraft/mixin/DataFixersMixin.java  | 51 +++++++++++++++++++
 .../ItemStackComponentizationFixMixin.java    | 16 +-----
 .../ComponentizationFixers.java               |  2 +-
 .../TurtleUpgradeComponentizationFix.java     | 31 +++++++++++
 .../main/resources/computercraft.mixins.json  |  1 +
 .../computercraft/mixin/V3818_3Mixin.java     |  2 +-
 .../computercraft/mixin/V3818_3Mixin.java     |  2 +-
 7 files changed, 87 insertions(+), 18 deletions(-)
 create mode 100644 projects/common/src/main/java/dan200/computercraft/mixin/DataFixersMixin.java
 rename projects/common/src/main/java/dan200/computercraft/shared/{util => datafix}/ComponentizationFixers.java (99%)
 create mode 100644 projects/common/src/main/java/dan200/computercraft/shared/datafix/TurtleUpgradeComponentizationFix.java

diff --git a/projects/common/src/main/java/dan200/computercraft/mixin/DataFixersMixin.java b/projects/common/src/main/java/dan200/computercraft/mixin/DataFixersMixin.java
new file mode 100644
index 0000000000..7478007018
--- /dev/null
+++ b/projects/common/src/main/java/dan200/computercraft/mixin/DataFixersMixin.java
@@ -0,0 +1,51 @@
+// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers
+//
+// SPDX-License-Identifier: MPL-2.0
+
+package dan200.computercraft.mixin;
+
+import com.llamalad7.mixinextras.sugar.Local;
+import com.mojang.datafixers.DataFixUtils;
+import com.mojang.datafixers.DataFixerBuilder;
+import com.mojang.datafixers.schemas.Schema;
+import dan200.computercraft.shared.datafix.TurtleUpgradeComponentizationFix;
+import net.minecraft.util.datafix.DataFixers;
+import net.minecraft.util.datafix.fixes.ItemStackComponentizationFix;
+import net.minecraft.util.datafix.schemas.V3818_5;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Unique;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.ModifyArg;
+
+@Mixin(DataFixers.class)
+abstract class DataFixersMixin {
+    /**
+     * Register {@link TurtleUpgradeComponentizationFix} alongside {@link ItemStackComponentizationFix}.
+     * 

+ * We use a {@link ModifyArg} to capture the schema passed to {@link ItemStackComponentizationFix}. This is a + * little gross, but is the easiest way to obtain the schema without hard-coding local ordinals. + * + * @param schema The {@link V3818_5} schema. + * @param builder The current datafixer builder + * @return The input schema. + */ + @ModifyArg( + method = "addFixers", + at = @At(value = "INVOKE", target = "Lnet/minecraft/util/datafix/fixes/ItemStackComponentizationFix;(Lcom/mojang/datafixers/schemas/Schema;)V"), + index = 0, + allow = 1 + ) + @SuppressWarnings("UnusedMethod") + private static Schema addComponentizationFixes(Schema schema, @Local DataFixerBuilder builder) { + assertSchemaVersion(schema, DataFixUtils.makeKey(3818, 5)); + builder.addFixer(new TurtleUpgradeComponentizationFix(schema)); + return schema; + } + + @Unique + private static void assertSchemaVersion(Schema schema, int version) { + if (schema.getVersionKey() != version) { + throw new IllegalStateException("Unexpected schema version. Expected " + version + ", got " + schema.getVersionKey()); + } + } +} diff --git a/projects/common/src/main/java/dan200/computercraft/mixin/ItemStackComponentizationFixMixin.java b/projects/common/src/main/java/dan200/computercraft/mixin/ItemStackComponentizationFixMixin.java index f3a92b1cd4..64a4a295e7 100644 --- a/projects/common/src/main/java/dan200/computercraft/mixin/ItemStackComponentizationFixMixin.java +++ b/projects/common/src/main/java/dan200/computercraft/mixin/ItemStackComponentizationFixMixin.java @@ -4,14 +4,11 @@ package dan200.computercraft.mixin; -import com.llamalad7.mixinextras.injector.ModifyReturnValue; import com.mojang.datafixers.DataFix; -import com.mojang.datafixers.TypeRewriteRule; import com.mojang.datafixers.schemas.Schema; import com.mojang.serialization.Dynamic; -import dan200.computercraft.shared.util.ComponentizationFixers; +import dan200.computercraft.shared.datafix.ComponentizationFixers; import net.minecraft.util.datafix.fixes.ItemStackComponentizationFix; -import net.minecraft.util.datafix.fixes.References; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -35,15 +32,4 @@ private ItemStackComponentizationFixMixin(Schema outputSchema, boolean changesTy private static void fixItemStack(ItemStackComponentizationFix.ItemStackData data, Dynamic ops, CallbackInfo ci) { ComponentizationFixers.fixItemComponents(data, ops); } - - @ModifyReturnValue(method = "makeRule", at = @At("RETURN"), remap = false) - @SuppressWarnings("UnusedMethod") - private TypeRewriteRule wrapMakeRule(TypeRewriteRule existing) { - return TypeRewriteRule.seq(existing, fixTypeEverywhereTyped( - "Turtle upgrade componentization", - getInputSchema().getType(References.BLOCK_ENTITY), - getOutputSchema().getType(References.BLOCK_ENTITY), - ComponentizationFixers.makeBlockEntityRewrites(getInputSchema(), getOutputSchema()) - )); - } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/util/ComponentizationFixers.java b/projects/common/src/main/java/dan200/computercraft/shared/datafix/ComponentizationFixers.java similarity index 99% rename from projects/common/src/main/java/dan200/computercraft/shared/util/ComponentizationFixers.java rename to projects/common/src/main/java/dan200/computercraft/shared/datafix/ComponentizationFixers.java index 83baa98689..52336ff5b9 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/util/ComponentizationFixers.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/datafix/ComponentizationFixers.java @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: MPL-2.0 -package dan200.computercraft.shared.util; +package dan200.computercraft.shared.datafix; import com.mojang.datafixers.DSL; import com.mojang.datafixers.Typed; diff --git a/projects/common/src/main/java/dan200/computercraft/shared/datafix/TurtleUpgradeComponentizationFix.java b/projects/common/src/main/java/dan200/computercraft/shared/datafix/TurtleUpgradeComponentizationFix.java new file mode 100644 index 0000000000..63e318ca0d --- /dev/null +++ b/projects/common/src/main/java/dan200/computercraft/shared/datafix/TurtleUpgradeComponentizationFix.java @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: 2024 The CC: Tweaked Developers +// +// SPDX-License-Identifier: MPL-2.0 + +package dan200.computercraft.shared.datafix; + +import com.mojang.datafixers.DataFix; +import com.mojang.datafixers.TypeRewriteRule; +import com.mojang.datafixers.schemas.Schema; +import net.minecraft.util.datafix.fixes.References; + +/** + * Rewrites turtle block entities to store upgrades as components. + * + * @see ComponentizationFixers#makeBlockEntityRewrites(Schema, Schema) + */ +public class TurtleUpgradeComponentizationFix extends DataFix { + public TurtleUpgradeComponentizationFix(Schema outputSchema) { + super(outputSchema, true); + } + + @Override + protected TypeRewriteRule makeRule() { + return fixTypeEverywhereTyped( + "Turtle upgrade componentization", + getInputSchema().getType(References.BLOCK_ENTITY), + getOutputSchema().getType(References.BLOCK_ENTITY), + ComponentizationFixers.makeBlockEntityRewrites(getInputSchema(), getOutputSchema()) + ); + } +} diff --git a/projects/common/src/main/resources/computercraft.mixins.json b/projects/common/src/main/resources/computercraft.mixins.json index 84cd676128..fcaf1e4d2e 100644 --- a/projects/common/src/main/resources/computercraft.mixins.json +++ b/projects/common/src/main/resources/computercraft.mixins.json @@ -7,6 +7,7 @@ "defaultRequire": 1 }, "mixins": [ + "DataFixersMixin", "ItemStackComponentizationFixMixin", "V1460Mixin" ] diff --git a/projects/fabric/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java b/projects/fabric/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java index 26b7806dbe..11c3cd5443 100644 --- a/projects/fabric/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java +++ b/projects/fabric/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java @@ -7,7 +7,7 @@ import com.llamalad7.mixinextras.injector.ModifyReturnValue; import com.mojang.datafixers.schemas.Schema; import com.mojang.datafixers.types.templates.TypeTemplate; -import dan200.computercraft.shared.util.ComponentizationFixers; +import dan200.computercraft.shared.datafix.ComponentizationFixers; import net.minecraft.util.datafix.schemas.V3818_3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; diff --git a/projects/forge/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java b/projects/forge/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java index 710f5c0563..fbc9773d30 100644 --- a/projects/forge/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java +++ b/projects/forge/src/main/java/dan200/computercraft/mixin/V3818_3Mixin.java @@ -7,7 +7,7 @@ import com.llamalad7.mixinextras.injector.ModifyReturnValue; import com.mojang.datafixers.schemas.Schema; import com.mojang.datafixers.types.templates.TypeTemplate; -import dan200.computercraft.shared.util.ComponentizationFixers; +import dan200.computercraft.shared.datafix.ComponentizationFixers; import net.minecraft.util.datafix.schemas.V3818_3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; From 8b1cb09ddf2648daa316d98c6de554dfcee541be Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sat, 23 Nov 2024 09:10:50 +0000 Subject: [PATCH 36/39] Update translations --- .../src/main/resources/assets/computercraft/lang/de_de.json | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/common/src/main/resources/assets/computercraft/lang/de_de.json b/projects/common/src/main/resources/assets/computercraft/lang/de_de.json index c18c52d8bc..3d9dcc1161 100644 --- a/projects/common/src/main/resources/assets/computercraft/lang/de_de.json +++ b/projects/common/src/main/resources/assets/computercraft/lang/de_de.json @@ -16,6 +16,7 @@ "block.computercraft.monitor_advanced": "Erweiterter Monitor", "block.computercraft.monitor_normal": "Monitor", "block.computercraft.printer": "Drucker", + "block.computercraft.redstone_relay": "Redstone Relais", "block.computercraft.speaker": "Lautsprecher", "block.computercraft.turtle_advanced": "Erweiterte Turtle", "block.computercraft.turtle_advanced.upgraded": "Erweiterte Turtle (%s)", From 5e24ad17d79edd6e42c63b1d72e26e265660f926 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sat, 23 Nov 2024 09:14:53 +0000 Subject: [PATCH 37/39] Bump CC:T to 1.114.1 --- gradle.properties | 2 +- .../data/computercraft/lua/rom/help/changelog.md | 7 +++++++ .../data/computercraft/lua/rom/help/whatsnew.md | 13 ++++--------- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/gradle.properties b/gradle.properties index 6d72cad023..66bb787d8e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ kotlin.jvm.target.validation.mode=error # Mod properties isUnstable=false -modVersion=1.114.0 +modVersion=1.114.1 # Minecraft properties: We want to configure this here so we can read it in settings.gradle mcVersion=1.20.1 diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md b/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md index 514d9b0503..9fd71be6eb 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md @@ -1,3 +1,10 @@ +# New features in CC: Tweaked 1.114.1 + +Several bug fixes: +* Fix monitor touch events only firing from one monitor. +* Fix crash when lectern has no item. +* Fix cursor not blinking on monitors. + # New features in CC: Tweaked 1.114.0 * Add redstone relay peripheral. diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md b/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md index a151ee199b..389dfaa36e 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md @@ -1,13 +1,8 @@ -New features in CC: Tweaked 1.114.0 - -* Add redstone relay peripheral. -* Add support for `math.atan(y, x)`. -* Update several translations. +New features in CC: Tweaked 1.114.1 Several bug fixes: -* Fix pocket upgrades not appearing after crafting. -* Cancel `rednet.receive` and `Websocket.receive` timers after a message is received. -* Fix several issues with parsing and printing large doubles. -* Fix in-hand pocket computer being blank after changing dimension. +* Fix monitor touch events only firing from one monitor. +* Fix crash when lectern has no item. +* Fix cursor not blinking on monitors. Type "help changelog" to see the full version history. From 9a06904634314a9a582ad70f00f3ab28973f24ea Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sat, 23 Nov 2024 09:31:04 +0000 Subject: [PATCH 38/39] Only skip cursor if it exists If the cursor is not visible then we'd end up blinking the last character on the screen. And if the screen was empty we'd spew the logs with GL errors. --- .../client/render/monitor/MonitorBlockEntityRenderer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorBlockEntityRenderer.java b/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorBlockEntityRenderer.java index 43ca16ac7a..f539227c40 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorBlockEntityRenderer.java +++ b/projects/common/src/client/java/dan200/computercraft/client/render/monitor/MonitorBlockEntityRenderer.java @@ -209,9 +209,9 @@ private static void renderTerminal( foregroundBuffer.drawWithShader( matrix, RenderSystem.getProjectionMatrix(), RenderTypes.getTerminalShader(), // Skip the cursor quad if it is not visible this frame. - FixedWidthFontRenderer.isCursorVisible(terminal) && FrameInfo.getGlobalCursorBlink() - ? foregroundBuffer.getIndexCount() - : foregroundBuffer.getIndexCount() - RenderTypes.TERMINAL.mode().indexCount(4) + FixedWidthFontRenderer.isCursorVisible(terminal) && !FrameInfo.getGlobalCursorBlink() + ? foregroundBuffer.getIndexCount() - RenderTypes.TERMINAL.mode().indexCount(4) + : foregroundBuffer.getIndexCount() ); // Clear state From 1963e0160f1fea472e5245ae5336061fb298d0d3 Mon Sep 17 00:00:00 2001 From: Jonathan Coates Date: Sat, 23 Nov 2024 09:34:03 +0000 Subject: [PATCH 39/39] Bump CC:T to 1.114.2 Ahhhh, I hate graphics code. --- gradle.properties | 2 +- .../data/computercraft/lua/rom/help/changelog.md | 5 +++++ .../resources/data/computercraft/lua/rom/help/whatsnew.md | 8 +++----- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/gradle.properties b/gradle.properties index 66bb787d8e..6285bdff7e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ kotlin.jvm.target.validation.mode=error # Mod properties isUnstable=false -modVersion=1.114.1 +modVersion=1.114.2 # Minecraft properties: We want to configure this here so we can read it in settings.gradle mcVersion=1.20.1 diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md b/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md index 9fd71be6eb..bdffb08361 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/help/changelog.md @@ -1,3 +1,8 @@ +# New features in CC: Tweaked 1.114.2 + +One bug fix: +* Fix OpenGL errors when rendering empty monitors. + # New features in CC: Tweaked 1.114.1 Several bug fixes: diff --git a/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md b/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md index 389dfaa36e..203143367e 100644 --- a/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md +++ b/projects/core/src/main/resources/data/computercraft/lua/rom/help/whatsnew.md @@ -1,8 +1,6 @@ -New features in CC: Tweaked 1.114.1 +New features in CC: Tweaked 1.114.2 -Several bug fixes: -* Fix monitor touch events only firing from one monitor. -* Fix crash when lectern has no item. -* Fix cursor not blinking on monitors. +One bug fix: +* Fix OpenGL errors when rendering empty monitors. Type "help changelog" to see the full version history.