From 172cb07945a7c95835776ac8904281bd810c817d Mon Sep 17 00:00:00 2001 From: repo_alt Date: Sat, 6 Jun 2020 20:02:49 +0300 Subject: [PATCH 01/19] Added Seismic Prospector data reading support --- .../gregtech/ConverterDataStick.scala | 38 +++++++++++++++++++ .../oc/integration/gregtech/ModGregtech.scala | 1 + 2 files changed, 39 insertions(+) create mode 100644 src/main/scala/li/cil/oc/integration/gregtech/ConverterDataStick.scala diff --git a/src/main/scala/li/cil/oc/integration/gregtech/ConverterDataStick.scala b/src/main/scala/li/cil/oc/integration/gregtech/ConverterDataStick.scala new file mode 100644 index 000000000..a022ecc7b --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/gregtech/ConverterDataStick.scala @@ -0,0 +1,38 @@ +package li.cil.oc.integration.gregtech + +import java.util + +import li.cil.oc.api.driver.Converter +import net.minecraft.item.ItemStack +import net.minecraft.nbt.{NBTTagCompound, NBTTagList, NBTTagString} +import li.cil.oc.util.ExtendedNBT._ +import net.minecraftforge.common.util.Constants.NBT + +import scala.collection.convert.WrapAsScala._ + +class ConverterDataStick extends Converter { + override def convert(value: Any, output: util.Map[AnyRef, AnyRef]): Unit = if (value.isInstanceOf[ItemStack]) { + val stack = value.asInstanceOf[ItemStack] + val nbt = stack.stackTagCompound + if (nbt.hasKey("prospection_tier")) + nbt.getString("title") match { + case "Raw Prospection Data" => getRawProspectionData(output, nbt) + case "Analyzed Prospection Data" => { + getRawProspectionData(output, nbt) + output += "Analyzed Prospection Data" -> + nbt.getTagList("pages", NBT.TAG_STRING) + .toArray[NBTTagString].map( (tag: NBTTagString) => tag.func_150285_a_().split('\n')) + } + case _ => + } + } + def getRawProspectionData(output: util.Map[AnyRef, AnyRef], nbt: NBTTagCompound) = + output += "Raw Prospection Data" -> Map( + "prospection_tier" -> nbt.getByte("prospection_tier"), + "prospection_pos" -> nbt.getString("prospection_pos"), + "prospection_ores" -> nbt.getString("prospection_ores").split('|'), + "prospection_oils" -> nbt.getString("prospection_oils").split('|'), + "prospection_oils_pos" -> nbt.getString("prospection_oils_pos"), + "prospection_radius" -> Integer.parseInt(nbt.getString("prospection_radius")) + ) +} diff --git a/src/main/scala/li/cil/oc/integration/gregtech/ModGregtech.scala b/src/main/scala/li/cil/oc/integration/gregtech/ModGregtech.scala index 67fae1564..b1cf2cbff 100644 --- a/src/main/scala/li/cil/oc/integration/gregtech/ModGregtech.scala +++ b/src/main/scala/li/cil/oc/integration/gregtech/ModGregtech.scala @@ -15,6 +15,7 @@ object ModGregtech extends ModProxy { MinecraftForge.EVENT_BUS.register(EventHandlerGregTech) Driver.add(new DriverEnergyContainer) + Driver.add(new ConverterDataStick) RecipeHandler.init() } From 1cf0910937827eb01ab0607a8401501c83e61a8c Mon Sep 17 00:00:00 2001 From: repo_alt Date: Wed, 24 Apr 2019 18:23:08 +0300 Subject: [PATCH 02/19] Distillation pattern aspect information --- .../ConvertAspectCraftable.scala | 15 +++++++++++++++ .../ModThaumicEnergistics.scala | 1 + 2 files changed, 16 insertions(+) create mode 100644 src/main/scala/li/cil/oc/integration/thaumicenergistics/ConvertAspectCraftable.scala diff --git a/src/main/scala/li/cil/oc/integration/thaumicenergistics/ConvertAspectCraftable.scala b/src/main/scala/li/cil/oc/integration/thaumicenergistics/ConvertAspectCraftable.scala new file mode 100644 index 000000000..c05bff526 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/thaumicenergistics/ConvertAspectCraftable.scala @@ -0,0 +1,15 @@ +package li.cil.oc.integration.thaumicenergistics +import java.util +import cpw.mods.fml.common.registry.GameRegistry +import li.cil.oc.api.driver.Converter +import net.minecraft.item.ItemStack +import scala.collection.convert.WrapAsScala._ + +object ConvertAspectCraftable extends Converter { + private val DistillationPattern = GameRegistry.findItem("thaumicenergistics", "crafting.aspect") + override def convert(value: scala.Any, output: util.Map[AnyRef, AnyRef]): Unit = value match { + case stack: ItemStack if stack.getItem == DistillationPattern && stack.hasTagCompound => + output += "aspect" -> stack.getTagCompound.getString("Aspect") + case _ => + } +} diff --git a/src/main/scala/li/cil/oc/integration/thaumicenergistics/ModThaumicEnergistics.scala b/src/main/scala/li/cil/oc/integration/thaumicenergistics/ModThaumicEnergistics.scala index 7eb2cf180..b485a7fe5 100644 --- a/src/main/scala/li/cil/oc/integration/thaumicenergistics/ModThaumicEnergistics.scala +++ b/src/main/scala/li/cil/oc/integration/thaumicenergistics/ModThaumicEnergistics.scala @@ -14,5 +14,6 @@ object ModThaumicEnergistics extends ModProxy { Driver.add(DriverController.Provider) Driver.add(DriverBlockInterface.Provider) + Driver.add(ConvertAspectCraftable) } } \ No newline at end of file From f74af9cafe257dea80fadaa52d41d63654ae2a81 Mon Sep 17 00:00:00 2001 From: payonel Date: Sat, 6 Jun 2020 21:05:37 -0700 Subject: [PATCH 03/19] send palette change update --- src/main/scala/li/cil/oc/common/component/TextBuffer.scala | 3 +++ .../li/cil/oc/common/component/traits/TextBufferProxy.scala | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/main/scala/li/cil/oc/common/component/TextBuffer.scala b/src/main/scala/li/cil/oc/common/component/TextBuffer.scala index 6194876ce..f3127270f 100644 --- a/src/main/scala/li/cil/oc/common/component/TextBuffer.scala +++ b/src/main/scala/li/cil/oc/common/component/TextBuffer.scala @@ -308,6 +308,9 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi colorDepthChanged } + override def onBufferPaletteChange(index: Int): Unit = + proxy.onBufferPaletteChange(index) + override def onBufferColorChange(): Unit = proxy.onBufferColorChange() diff --git a/src/main/scala/li/cil/oc/common/component/traits/TextBufferProxy.scala b/src/main/scala/li/cil/oc/common/component/traits/TextBufferProxy.scala index ae55093ff..c0c5f9e1d 100644 --- a/src/main/scala/li/cil/oc/common/component/traits/TextBufferProxy.scala +++ b/src/main/scala/li/cil/oc/common/component/traits/TextBufferProxy.scala @@ -20,9 +20,12 @@ trait TextBufferProxy extends api.internal.TextBuffer { override def getColorDepth: TextBuffer.ColorDepth = data.format.depth + def onBufferPaletteChange(index: Int): Unit = {} + override def setPaletteColor(index: Int, color: Int): Unit = data.format match { case palette: PackedColor.MutablePaletteFormat => palette(index) = color + onBufferPaletteChange(index) case _ => throw new Exception("palette not available") } From a84506b8605f859048bd6ed0f6c38574a145ad46 Mon Sep 17 00:00:00 2001 From: payonel Date: Sun, 7 Jun 2020 15:05:11 -0700 Subject: [PATCH 04/19] vt ABCD default is 1 closes #3320 --- .../opencomputers/loot/openos/lib/core/full_vt.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/core/full_vt.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/core/full_vt.lua index dcafc5edc..b2e7fbc83 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/core/full_vt.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/core/full_vt.lua @@ -14,13 +14,13 @@ local function set_cursor(window, x, y) end -- -- These DO NOT SCROLL --- [(%d+)A move cursor up n lines --- [(%d+)B move cursor down n lines --- [(%d+)C move cursor right n lines --- [(%d+)D move cursor left n lines -rules[{"%[", "%d+", "[ABCD]"}] = function(window, _, n, dir) +-- [(%d*)A move cursor up n lines +-- [(%d*)B move cursor down n lines +-- [(%d*)C move cursor right n lines +-- [(%d*)D move cursor left n lines +rules[{"%[", "%d*", "[ABCD]"}] = function(window, _, n, dir) local dx, dy = 0, 0 - n = tonumber(n) + n = tonumber(n) or 1 if dir == "A" then dy = -n elseif dir == "B" then From f73dd9eaca421af783a8c97cc36d0a73977bde8a Mon Sep 17 00:00:00 2001 From: payonel Date: Sun, 7 Jun 2020 16:46:15 -0700 Subject: [PATCH 05/19] allow numbers in gsub pattern, as lua does closes #1999 --- src/main/resources/assets/opencomputers/lua/machine.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/resources/assets/opencomputers/lua/machine.lua b/src/main/resources/assets/opencomputers/lua/machine.lua index 7c42c3b49..583f15755 100644 --- a/src/main/resources/assets/opencomputers/lua/machine.lua +++ b/src/main/resources/assets/opencomputers/lua/machine.lua @@ -621,7 +621,7 @@ do local function str_gsub(s, pattern, repl, n) checkArg(1, s, "string") - checkArg(2, pattern, "string") + checkArg(2, pattern, "string", "number") checkArg(3, repl, "number", "string", "function", "table") checkArg(4, n, "number", "nil") @@ -629,6 +629,7 @@ do return string_gsub(s, pattern, repl, n) end + pattern = tostring(pattern) local src = strptr(s); local p = strptr(pattern) local tr = type(repl) From f74d7d230eac640b080774b6bf8dc02b3cfde30c Mon Sep 17 00:00:00 2001 From: PrismaticYT <45874270+RPMYT@users.noreply.github.com> Date: Sun, 9 Aug 2020 11:56:20 +1200 Subject: [PATCH 06/19] Fix five-year-old typo --- .../assets/opencomputers/doc/en_US/block/transposer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/assets/opencomputers/doc/en_US/block/transposer.md b/src/main/resources/assets/opencomputers/doc/en_US/block/transposer.md index ccc3e07ff..f666883bb 100644 --- a/src/main/resources/assets/opencomputers/doc/en_US/block/transposer.md +++ b/src/main/resources/assets/opencomputers/doc/en_US/block/transposer.md @@ -6,4 +6,4 @@ The transposer bridges the gap between redstone controlled hoppers and [robots]( *Note that this block has no internal inventory.* -Besides moving things around, it can also be used to inspect the contents of the adjacent inventories, like an [adapter](adapter.md) with an [inventory controller upgrade](../item/inventoryControllerUpgrade.md) could, and the contents of adjacent tanks, like and adapter with a [tank controller upgrade](../item/tankControllerUpgrade.md) could. +Besides moving things around, it can also be used to inspect the contents of the adjacent inventories, like an [adapter](adapter.md) with an [inventory controller upgrade](../item/inventoryControllerUpgrade.md) could, and the contents of adjacent tanks, like an adapter with a [tank controller upgrade](../item/tankControllerUpgrade.md) could. From af2db43c53b9690fceabfb813987572bf2258db5 Mon Sep 17 00:00:00 2001 From: David Cook Date: Sat, 5 Sep 2020 13:47:44 -0500 Subject: [PATCH 07/19] Block 0.0.0.0/8 from internet card by default The 0.0.0.0/8 subnet refers to "this network", (c.f. RFC 3330) and in particular, 0.0.0.0 can be used to refer to the local computer. As such, it should be blocked by default, as loopback addresses currently are. This default configuration was relevant to a challenge in the ALLES! CTF 2020 competition, see https://play.allesctf.net/tasks/ALLES!Craft or https://ctftime.org/event/1091. The challenge involved multiple servers interconnected with Waterfall as a proxy, to enable server teleportation. The solution to the challenge was to use an internet card on one of the servers to connect to 0.0.0.0, bypassing the Waterfall proxy, and replay or reverse proxy a Minecraft handshake in Lua, which allowed spoofing as a different user. --- src/main/resources/application.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index 9312cf05f..70b8432c5 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -975,6 +975,7 @@ opencomputers { # mod's context in an appropriate manner, e.g. using a system firewall. blacklist: [ "127.0.0.0/8" + "0.0.0.0/8" "10.0.0.0/8" "192.168.0.0/16" "172.16.0.0/12" From 59fac9b4b601b74e58a2a7b7b4b1216fff84cb9c Mon Sep 17 00:00:00 2001 From: Fingercomp Date: Mon, 8 Jun 2020 16:22:57 +0700 Subject: [PATCH 08/19] Check the channel is set before submitting it to the TCPNotifier --- src/main/scala/li/cil/oc/server/component/InternetCard.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/scala/li/cil/oc/server/component/InternetCard.scala b/src/main/scala/li/cil/oc/server/component/InternetCard.scala index ba33e2842..5faac807a 100644 --- a/src/main/scala/li/cil/oc/server/component/InternetCard.scala +++ b/src/main/scala/li/cil/oc/server/component/InternetCard.scala @@ -246,6 +246,7 @@ object InternetCard { private val id = UUID.randomUUID() private def setupSelector() { + if (channel == null) return TCPNotifier.add((channel, () => { owner match { case Some(internetCard) => From 7928f0c67fb2d8856fe5916d43c0ad40c0df8f61 Mon Sep 17 00:00:00 2001 From: payonel Date: Tue, 11 May 2021 08:09:45 -0700 Subject: [PATCH 09/19] fix remote terminal missing causing null exception. closes #3249 --- .gitignore | 1 + .../scala/li/cil/oc/common/component/TerminalServer.scala | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7988aa7c0..2ce31b1d6 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ # VSCode /.vscode +/saves diff --git a/src/main/scala/li/cil/oc/common/component/TerminalServer.scala b/src/main/scala/li/cil/oc/common/component/TerminalServer.scala index 88abc9e25..5a178960a 100644 --- a/src/main/scala/li/cil/oc/common/component/TerminalServer.scala +++ b/src/main/scala/li/cil/oc/common/component/TerminalServer.scala @@ -287,7 +287,10 @@ object TerminalServer { def find(address: String): Option[TerminalServer] = { completePending() - Some(ready.getOrDefault(address, null)) + ready.getOrDefault(address, null) match { + case term: TerminalServer => Option(term) + case _ => None + } } } } From 1a9feabed7e83d861c97934baf21a3e77fe4224b Mon Sep 17 00:00:00 2001 From: Guilherme Puida Date: Sun, 3 Jan 2021 00:24:45 -0300 Subject: [PATCH 10/19] pt_BR translation update --- .../assets/opencomputers/lang/pt_BR.lang | 141 ++++++++++-------- 1 file changed, 77 insertions(+), 64 deletions(-) diff --git a/src/main/resources/assets/opencomputers/lang/pt_BR.lang b/src/main/resources/assets/opencomputers/lang/pt_BR.lang index 31a23fa6e..d4cd3204f 100644 --- a/src/main/resources/assets/opencomputers/lang/pt_BR.lang +++ b/src/main/resources/assets/opencomputers/lang/pt_BR.lang @@ -1,5 +1,6 @@ -# This is the Brazilian portuguese translation based on master english file. -#Author: Hilton W. Silva (hws689) +# This is the Brazilian portuguese translation based on the en_US.lang file. +# Author: Hilton W. Silva (hws689) +# Updated by guilherme-puida in 03/01/2021 # Blocks tile.oc.accessPoint.name=§cPonto de Acesso§7 @@ -7,6 +8,7 @@ tile.oc.adapter.name=Adaptador tile.oc.assembler.name=Montador Eletrônico tile.oc.cable.name=Cabo tile.oc.capacitor.name=Capacitador +tile.oc.carpetedCapacitor.name=Capacitador com Tapete tile.oc.case1.name=Gabinete (Nível 1) tile.oc.case2.name=Gabinete (Nível 2) tile.oc.case3.name=Gabinete (Nível 3) @@ -56,6 +58,7 @@ item.oc.CircuitBoard.name=Placa de Circuito item.oc.ComponentBus0.name=Componente de Barramento (Nível 1) item.oc.ComponentBus1.name=Componente de Barramento (Nível 2) item.oc.ComponentBus2.name=Componente de Barramento (Nível 3) +item.oc.ComponentBus3.name=Componente de Barramento (Criativo) item.oc.ControlUnit.name=Unidade de Controle (UC) item.oc.CPU0.name=Unidade Central de Processamento (CPU) (Nível 1) item.oc.CPU1.name=Unidade Central de Processamento (CPU) (Nível 2) @@ -101,10 +104,10 @@ item.oc.Microchip2.name=Circuito Integrado (Nível 3) item.oc.MicrocontrollerCase0.name=Carcaça do Microcontrolador (Nível 1) item.oc.MicrocontrollerCase1.name=Carcaça do Microcontrolador (Nível 2) item.oc.MicrocontrollerCase3.name=Carcaça do Microcontrolador (Criativo) -item.oc.Nanomachines.name=Nanomaquinas +item.oc.Nanomachines.name=Nanomáquinas item.oc.NetworkCard.name=Cartão de Rede -item.oc.NumPad.name=Teclado Númerico -item.oc.Present.name=Um pouco de tudo... +item.oc.NumPad.name=Teclado Numérico +item.oc.Present.name=Uma coisinha... item.oc.PrintedCircuitBoard.name=Placa de Circuito Impresso (PCB) item.oc.RawCircuitBoard.name=Placa de Circuito Crua item.oc.RedstoneCard0.name=Cartão de Redstone (Nível 1) @@ -114,9 +117,9 @@ item.oc.Server1.name=Servidor (Nível 2) item.oc.Server2.name=Servidor (Nível 3) item.oc.Server3.name=Servidor (Criativo) item.oc.Tablet.name=Tablet -item.oc.TabletCase0.name=Carcaça do Tablet (Nível 1) -item.oc.TabletCase1.name=Carcaça do Tablet (Nível 2) -item.oc.TabletCase3.name=Carcaça do Tablet (Criativo) +item.oc.TabletCase0.name=Carcaça de Tablet (Nível 1) +item.oc.TabletCase1.name=Carcaça de Tablet (Nível 2) +item.oc.TabletCase3.name=Carcaça de Tablet (Criativo) item.oc.Terminal.name=Terminal Remoto item.oc.TerminalServer.name=Servidor de Terminal item.oc.TexturePicker.name=Selecionador de Textura @@ -143,6 +146,7 @@ item.oc.UpgradeHover1.name=Aprimoramento de Flutuação (Nível 2) item.oc.UpgradeInventory.name=Aprimoramento de Inventário item.oc.UpgradeInventoryController.name=Aprimoramento de Controlador de Inventário item.oc.UpgradeLeash.name=Aprimoramento de Correia +item.oc.UpgradeMF.name=MFU item.oc.UpgradeNavigation.name=Aprimoramento de Navegação item.oc.UpgradePiston.name=Aprimoramento de Pistão item.oc.UpgradeSign.name=Aprimoramento de Sinal de E/S @@ -178,33 +182,35 @@ oc:gui.Assembler.Collect=Saída do coletador oc:gui.Assembler.Complexity=Complexidade: %s/%s oc:gui.Assembler.InsertCase=Insira uma parte base oc:gui.Assembler.InsertCPU=Insira uma CPU -oc:gui.Assembler.InsertRAM=Insera alguma RAM +oc:gui.Assembler.InsertRAM=Insira alguma RAM oc:gui.Assembler.Progress=Progresso: %s%% (%s) -oc:gui.Assembler.Run=Montando +oc:gui.Assembler.Run=Montar oc:gui.Assembler.Warning.BIOS=BIOS oc:gui.Assembler.Warning.GraphicsCard=Placa de Vídeo oc:gui.Assembler.Warning.Inventory=Aprimoramento de Inventário oc:gui.Assembler.Warning.Keyboard=Teclado oc:gui.Assembler.Warning.OS=Mídia Inicializável oc:gui.Assembler.Warning.Screen=Monitor -oc:gui.Assembler.Warnings=§eAtenção§7: Componentes recomendados aussentes. +oc:gui.Assembler.Warnings=§eAtenção§7: Componentes recomendados ausentes. oc:gui.Chat.NewVersion=Uma nova versão está disponível: %s oc:gui.Chat.TextureName=§7Nome da textura é §a%s§f. oc:gui.Chat.WarningClassTransformer=Houve um erro §cerros§f ao rodar o 'class transformer'. Por favor relate isso, junto com o seu arquivo de log (completo!) FML §alatest.log§f/§afml-server-latest.log§f , obrigado! -oc:gui.Chat.WarningFingerprint=§cATENÇÃO§f - impressão digital não reconhecida! Experado '§a%s§f' mas recebido '§e%s§f'. Há não ser que seja um moderador e esteja rodando uma versão desofuscada, é §lextremamente§f recomendável que baixe novamente o OpenComputers, por que o JAR que está usando talvez esteja adulterado. -oc:gui.Chat.WarningLink=Não pode abrir o atalho: %s -oc:gui.Chat.WarningLuaFallback=Bibliotecas de LUA nativas não disponíveis, computadores não serão capazes de persistir seus estados. Eles reiniciarizaram com chunkloaders. -oc:gui.Chat.WarningProjectRed=Você está usando a versão Project: Red que é incompativel com OpenComputers. Tente atualizar sua versão do Project: Red. -oc:gui.Chat.WarningRecipes=Houve erros ao carregar uma ou mais receitas. Algumas não poderão ser construídas. Por favor verifique seu arquivo de log para mais informações. +oc:gui.Chat.WarningFingerprint=§cATENÇÃO§f - impressão digital não reconhecida! Experado '§a%s§f' mas recebido '§e%s§f'. A não ser que você seja um desenvolvedor e esteja rodando uma versão desofuscada, é §lextremamente§f recomendável que baixe novamente o OpenComputers, por que o JAR que está usando talvez esteja adulterado. +oc:gui.Chat.WarningLink=Não foi possível abrir o atalho: %s +oc:gui.Chat.WarningLuaFallback=Bibliotecas nativas do Lua não disponíveis, computadores não serão capazes de persistir seus estados. Eles reinicializarão quando chunks descarregarem. +oc:gui.Chat.WarningProjectRed=Você está usando uma versão do Project: Red que é incompativel com OpenComputers. Tente atualizar sua versão do Project: Red. +oc:gui.Chat.WarningRecipes=Houve erros ao carregar uma ou mais receitas. Alguns itens não poderão ser construídos. Verifique seu arquivo de log para mais informações. oc:gui.Chat.WarningSimpleComponent=Um addon (seu?) usa a interface §aSimpleComponent§f que faz §ealgo errado§f. A lógica de componente não pode ser injetada. Por favor verifique seu arquivo de log para mais informações. oc:gui.Drive.Managed=Gerenciado oc:gui.Drive.Unmanaged=Não Gerenciado +oc:gui.Drive.ReadOnlyLock=Bloqueado +oc:gui.Drive.ReadOnlyLockWarning=§Somente leitura§r. Isso não pode ser removido, exceto quando o disco é formatado. oc:gui.Drive.Warning=§lAtençaõ§r: mudança de modos resultará em perca de todos os dados do disco! oc:gui.Error.ComponentOverflow=Muitos componentes conectados ao computador. oc:gui.Error.InternalError=Erro interno, por favor veja o arquivo de log. Isto é provavelmente um erro. oc:gui.Error.NoCPU=Não há CPU instalada no computador. oc:gui.Error.NoEnergy=Energia insuficiente. -oc:gui.Error.NoRAM=Não há RAM instalda no computador. +oc:gui.Error.NoRAM=Não há RAM instalada no computador. oc:gui.Error.OutOfMemory=Sem memória. oc:gui.Manual.Blocks=Blocos do OpenComputers oc:gui.Manual.Home=Início @@ -213,10 +219,10 @@ oc:gui.Manual.Warning.BlockMissing=Bloco indisponível. oc:gui.Manual.Warning.ImageMissing=Imagem não encontrada. oc:gui.Manual.Warning.ItemMissing=Item indisponível. oc:gui.Manual.Warning.OreDictMissing=Entrada no dicionário de minérios indisponível. -oc:gui.Raid.Warning=§4Adicionando um disco limpe-o.[nl] Removendo um disco limpando o raid. +oc:gui.Raid.Warning=§4Adicionar um disco o formata.[nl] Remover um disco limpa a raid. oc:gui.Robot.Power=Energia oc:gui.Robot.TurnOff=Desligar -oc:gui.Robot.TurnOn=Ligar[nl]§7Use um analizador para verficar problemas.§r +oc:gui.Robot.TurnOn=Ligar[nl]§7Use um Analizador para verficar problemas.§r oc:gui.Rack.Back=Voltar oc:gui.Rack.Bottom=Baixo oc:gui.Rack.Left=Esquerda @@ -224,6 +230,7 @@ oc:gui.Rack.None=Nenhum oc:gui.Rack.Right=Direita oc:gui.Rack.Enabled=Habilitado oc:gui.Rack.Disabled=Disabilitado +oc:gui.Rack.RelayModeTooltip=Modo de relé oc:gui.Rack.Top=Cima oc:gui.Switch.PacketsPerCycle=Pacotes / ciclo oc:gui.Switch.QueueSize=Tamanho da fila @@ -247,7 +254,7 @@ oc:container.Switch=Switch oc:container.TabletWrapper=Tablet # Keybinds -key.clipboardPaste=Copiar para área de transferência +key.clipboardPaste=Colar da área de transferência key.materialCosts=Mostrar custo dos materiais # Item / Block Tooltips @@ -262,6 +269,7 @@ oc:tooltip.Assembler=Permite construir robôs e outros dispositivos com várias oc:tooltip.Cable=Uma maneira barata de conectar os blocos. oc:tooltip.Capacitor=Armazena energia para usar mais tarde. Pode ser enchido e esvaziado rapidamente. oc:tooltip.CardBase=Como o nome diz, este é o bloco de construção básico para os cartões de expansão. +oc:tooltip.CarpetedCapacitor=Armazena energia para uso posterior. Pode ser carregado e descarregado rapidamente. Carrega quando uma ovelha ou jaguatirica anda sobre o mesmo. oc:tooltip.Case=O gabinete é o bloco básico para computadores e guarda os §fcartões de extensão§7, §fRAM§7 e §fdiscos rígidos§7.[nl] Slots: §f%s§7 oc:tooltip.Chamelium=Matéria prima para as imressões 3D. Não ingerir: talvez leve a cegueira e um lapso temporário de presença. oc:tooltip.ChameliumBlock=Agradável e Limpo. Usado para formas coloridas nas impressões 3D, ou para simplesmente ter, um bloco colorido para decorar sua linda e chamativa base. @@ -280,21 +288,22 @@ oc:tooltip.Debugger=Pode ser usado para depurar informações na grade de rede i oc:tooltip.DiamondChip=Um pedacinho de um diamante uma vez impecável. Ele nunca será o mesmo de novo. oc:tooltip.Disassembler=Separa os itens em seus componentes originais. §lAtenção§7: o item retornado tem uma chance de %s%% de quebrar no processo! oc:tooltip.Disk=Uma mídia primitiva que pode ser usada para construir dispositvos de armazenamentos contínuos. -oc:to+oltip.DiskDrive.CC=Disquetes do ComputerCraft são §asuportados§7. +oc:tooltip.DiskDrive.CC=Disquetes do ComputerCraft são §asuportados§7. oc:tooltip.DiskDrive=Permite escrever e ler disquetes. Pode ser instalado em robôs para permitir inserir disquetes mais tarde. oc:tooltip.DiskDriveMountable=Provê a mesma funcionalidade de uma unidade de disco normal, mas só pode ser instalado em um rack. oc:tooltip.DiskUsage=Uso de disco: %s/%s Byte +oc:tooltip.DiskLocked=Bloqueado por: %s oc:tooltip.DiskModeManaged=Modo: Gerenciado oc:tooltip.DiskModeUnmanaged=Modo: Não gerenciado oc:tooltip.Drone=Drones são leves, com reconhecimento rápido de unidades com espaço interno limitado. oc:tooltip.DroneCase=Está carcaça é usada para montar drones no montador. Ele tem um espaço para uma pequena quantidade de componentes e provê levitação com a pedra do fim. -oc:tooltip.EEPROM=Pequeno, espaço programável que contem a BIOS dos computadores usado para inicia-lo. -oc:tooltip.FakeEndstone=Quase igual a coisa real, até mesmo emula sua levitação! -oc:tooltip.Geolyzer=Permite escanear ao redor de área de blocos sólidos. Essa informação pode ser útil para geração de hologramas de área ou para detectar minérios. +oc:tooltip.EEPROM=Pequeno armazenamento programável que contem a BIOS dos computadores usado para iniciá-los. +oc:tooltip.FakeEndstone=Quase igual a coisa real, emula até mesmo sua levitação! +oc:tooltip.Geolyzer=Permite escanear a dureza da área ao redor de blocos sólidos. Essa informação pode ser útil para geração de hologramas de área ou para detectar minérios. oc:tooltip.GraphicsCard=Usado para mudar o que é mostrado nos monitores.[nl] Máxima resolução: §f%sx%s§7[nl] Máxima profundidade de cores: §f%s§7[nl] Operações/tick: §f%s§7 -oc:tooltip.HoverBoots=Pule alto, caia devagar, caminhe melhor. Isso é mais, com as mais novas patentiadas Botas Voadoras (TM). +oc:tooltip.HoverBoots=Pule alto, caia devagar, caminhe melhor. Isso e mais, com as mais novas e patenteadas Botas Voadoras (TM). oc:tooltip.InkCartridge=Usado para carregar tinta nas impressoras 3D. Por razões misteriosas ele não tem que permanecer na impressora. -oc:tooltip.InkCartridgeEmpty=Este cartucho de tinta foi usado até secar. Recarregue isso usando corrantes. Ou jogando fora. Veja minha cara de preocupado -.-. +oc:tooltip.InkCartridgeEmpty=Este cartucho de tinta foi usado até secar. Recarregue isso usando corantes. Ou jogue-o fora. Veja minha cara de preocupado -.-. oc:tooltip.InternetCard=Este cartão faz requisições HTTP usa protocolos TCP reais. oc:tooltip.Interweb=Parabéns, você ganhou um (1) interweb. Você pode conectar a isso usando um Cartão de Internet. Cuidado: não alimente os trolls. oc:tooltip.IronNugget=Uma pepita feita de ferro, por isso é chamado de Pepita de Ferro, darrr... @@ -306,13 +315,13 @@ oc:tooltip.LinkedCard_Channel=§8Canal: %s§7 oc:tooltip.Manual=Toda informaçâo que você provalvemente precisará do OpenComputers. E mais. Por um preço inacreditável de... §opor favor pressiona R para continuar§7. oc:tooltip.MaterialCosts=Segure [§f%s§7] para custos do material. oc:tooltip.Materials=Materiais: -oc:tooltip.Memory=Requerido para fazer os computadores funcionarem. Quanto mais tiver, mais complexo podem ser os programas. -oc:tooltip.Microchip=Um chip reconhecido formalmente como Circuito Integrado. Eu não tenho ideia porque isso funciona com redstone, mas funciona. -oc:tooltip.Microcontroller=Microcontrolador são mini computadores. Eles são usadas para cuidar de tarefas específicas, rodando um único programa que é provido pela EEPROM consruida dentro dele.[nl] §cNão pode conectar com componentes externos.§7 +oc:tooltip.Memory=Requerida para fazer os computadores funcionarem. Quanto mais tiver, mais complexos podem ser os programas. +oc:tooltip.Microchip=Um chip conhecido formalmente como Circuito Integrado. Eu não tenho ideia porque isso funciona com redstone, mas funciona. +oc:tooltip.Microcontroller=Microcontroladores são mini computadores. Eles são usadas para cuidar de tarefas específicas, rodando um único programa que é provido pela EEPROM consruida dentro dele.[nl] §cNão pode conectar com componentes externos.§7 oc:tooltip.MicrocontrollerCase=Componente básico para construir microcontroladores. Coloque-o em um montador para adicionar novos componentes e montar um microcontrolador. -oc:tooltip.MotionSensor=Pode detectar movimento de forma de vidas próximas. Requer uma visão limpa. -oc:tooltip.Nanomachines=Unidade de controle e um grupo de nanomaquinas pra comer, se você quiser. -oc:tooltip.NetworkCard=Permite que computadores distantes conectem por outros blocos (como cabos) para comunicar-se enviando mensagens um pro outro. +oc:tooltip.MotionSensor=Pode detectar movimento de formas de vidas próximas. Requer visão direta. +oc:tooltip.Nanomachines=Unidade de controle e um grupo de nanomáquinas pra ingerir, se você tiver coragem. +oc:tooltip.NetworkCard=Permite que computadores distantes conectem por outros blocos (como cabos) para comunicar-se enviando mensagens um para o outro. oc:tooltip.PowerAcceptor=Velocidade da conversão de energia: §f%s/t§7 oc:tooltip.PowerConverter.BuildCraft=§fBuildCraft MJ§7: §a%s:%s§7 oc:tooltip.PowerConverter.Factorization=§fCarregamento do Factorization§7: §a%s:%s§7 @@ -322,13 +331,13 @@ oc:tooltip.PowerConverter.ThermalExpansion=§fThermal Expansion RF§7: §a%s:%s oc:tooltip.PowerConverter.ResonantEngine=§fResonant Engine Coulombs§7: §a%s:%s§7 oc:tooltip.PowerConverter=Converte energia de outros mods para o tipo de energia interna. Taxa de conversão: oc:tooltip.PowerDistributor=Distribui energia por meio de diferentes redes. Isto é útil para compartilhar fluxo de energia de seu sistema para outro conversor em diferentes sub-redes que podem manter separados. -oc:tooltip.Present=... para seus problemas. Abra este presente para ter uma chance de receber §kum grande tessouro§7![nl]§8Construa itens do OpenComputers até que chegue o tempo certo para ter uma chance de receber presente.§7 +oc:tooltip.Present=... para seus problemas. Abra este presente para ter uma chance de receber §kum grande tesouro§7![nl]§8Construa itens do OpenComputers para ter uma chance de receber presente.§7 oc:tooltip.Print.BeaconBase=§8Funciona como uma base do sinalizador. oc:tooltip.Print.LightValue=§8Luz emitida: %s. oc:tooltip.Print.RedstoneLevel=§8Saída da Redstone: %s. -oc:tooltip.PrintedCircuitBoard=O bloco de construção básico para cartões de expansão e memória e tal. +oc:tooltip.PrintedCircuitBoard=O bloco de construção básico para cartões de expansão, memória e outros. oc:tooltip.Printer=Permite imprimir blocos com forma definida pelo usuário usando o Camaleão (nome lindo?) e Cartucho de Tinta. Deve ser configurado usando um computador. Deixe longe do alcance das crianças. Porque sim. -oc:tooltip.Raid=Permite cobinar três discos rigídos em um único grande arquivo de sistema que pode ser usuado para todos os computadores conectados. +oc:tooltip.Raid=Permite cobinar três discos rigídos em um único grande arquivo de sistema que pode ser usado por todos os computadores conectados. oc:tooltip.RawCircuitBoard=Pode ser endurecido em qualquer fornalha compátivel. oc:tooltip.Redstone=Permite ler e emitir sinais de redstone ao redor do bloco. Pode ser controlado por qualquer computador que o bloco estiver conectado. Isto é básicamente um cartão de redstone externo. oc:tooltip.RedstoneCard.ProjectRed=§fProjectRed§7 é §asuportado§7. @@ -338,28 +347,28 @@ oc:tooltip.RedstoneCard.WirelessCBE=§fWireless Redstone (ChickenBones)§7 é § oc:tooltip.RedstoneCard.WirelessSV=§fWireless Redstone (SlimeVoid)§7 é §asuportado§7. oc:tooltip.RedstoneCard=Permite ler e emitir sinais de redstone ao redor do robô computadorizado. oc:tooltip.Relay=Permite conectar diversas redes uma com a outra. Somente mensagens de rede serão passadas, componentes não serão vísiveis através disto. Use para separar redes e continuar permitindo comunicação usando Cartões de Rede, por exemplo. -oc:tooltip.Robot=Diferente de computadores, robôs podem mover-se por ai e interagir com o mundo parecido com que um jogador faz.[nl] §cNão pode conectar com componentes externos.§7 +oc:tooltip.Robot=Diferente de computadores, robôs podem mover-se por ai e interagir com o mundo parecido com o que um jogador faz.[nl] §cNão pode conectar-se com componentes externos.§7 # The underscore makes sure this isn't hidden with the rest of the tooltip. oc:tooltip.Robot_Level=§fNível§7: §a%s§7 oc:tooltip.Robot_StoredEnergy=§fEnergia armazenada§7: §a%s§7 oc:tooltip.Screen=Mostra texto, controlado por uma placa de vídeo em um Gabinete.[nl] Resolução máxima: §f%sx%s§7[nl] Densidade máxima: §f%s§7 -oc:tooltip.Server=Isto é um servidor, tem muitos como este, mas este pode ser aprimorado com componentes como um gabinete pode ser. Ele pode ser ligado inserindo-o em um rack de servidor. +oc:tooltip.Server=Isto é um servidor: existem muitos como este, mas este pode ser aprimorado com componentes como um gabinete pode ser. Ele pode ser ligado inserindo-o em um rack de servidor. oc:tooltip.Server.Components=Componentes instalados: oc:tooltip.Rack=Permite a instalação de até quatro servidores ou outros montáveis. -oc:tooltip.Switch=Permite conectar várias redes uma com a outra. Somente mensagem de rede será passada, componentes não serão vísiveis. Use-o para separar redes permitindo comunicação usando Cartões de Rede, por exemplo. -oc:tooltip.Tablet=Um tablet, com um Lua saindo do forno. Pode ser forçado a desligar se abaixando e ativando-o. +oc:tooltip.Switch=Permite conectar várias redes uma com a outra. Somente mensagens de rede serão transmitidas, componentes não serão vísiveis. Use-o para separar redes permitindo comunicação usando Cartões de Rede, por exemplo. +oc:tooltip.Tablet=Um tablet, para usar Lua de maneira portátil. Pode ser forçado a desligar se abaixando e ativando-o. oc:tooltip.TabletCase=Carcaça básica para tablets. Coloque-o no montador para adicionar componentes e criar um tablet. oc:tooltip.Terminal=Permite controlar um servidor remotamente, enquanto estiver no seu alcance. Atua como monitor e teclados portateis. Shift + Botão Direito em um servidor em um rack para vincular um terminal. -oc:tooltip.TerminalServer=Backend para que Terminais remotos possam ser conectados para provê controle remoto. Contem um monitor virtual e teclado. +oc:tooltip.TerminalServer=Backend para que Terminais remotos possam ser conectados para prover controle remoto. Contém um monitor virtual e um teclado. oc:tooltip.TexturePicker=Esta ferramente mostra uma string descrevendo uma superfície de bloco, para usar na impressora 3D e definir formas. Não são nomes de texturas, nana nina não. oc:tooltip.Tier=§8Nível %s oc:tooltip.NetSplitter=Atua como um conector dinâmico. Conectividade de cada lado pode ser mudada batendo-a com uma chave. Conectividade de todos os lados podem ser invertidas aplicando um sinal de redstone. oc:tooltip.TooLong=Segure [§f%s§7] para uma dica detalhada. -oc:tooltip.Transistor=Um elemento básico para outras partes de computador. É um pouco retorcido, mas faz seu trabalho. -oc:tooltip.Transposer=Permite transferir automaticamente itens e fluídos entre inventários adjacentes e recipientes de fluidos. -oc:tooltip.UpgradeAngel=Permite robôs colocar blocos no ar, mesmo sem um ponto de apoio. +oc:tooltip.Transistor=Um elemento básico para outras partes de computador. É um pouco torto, mas faz seu trabalho. +oc:tooltip.Transposer=Permite transferir automaticamente itens e fluidos entre inventários adjacentes e recipientes de fluidos. +oc:tooltip.UpgradeAngel=Permite que robôs coloquem blocos no ar, mesmo sem um ponto de apoio. oc:tooltip.UpgradeBattery=Aumenta a quantidade de energia que o dispositivo pode armazenar, permitindo que trabalhe mais tempo sem precisa recarregar. [nl] Capacidade: §f%s§7 -oc:tooltip.UpgradeChunkloader=Se um robô move-se em uma floresta e ninguém é capaz de ver ele, ele está se mechendo ou não? Este aprimoramento faz ter certeza que sim. Isto mantêm um chunk, um dispositvo está carregado, mas consome energia continua enquanto ativo. +oc:tooltip.UpgradeChunkloader=Se um robô move-se em uma floresta e ninguém é capaz de ver ele, ele está se mexendo ou não? Este aprimoramento faz ter certeza que sim. Isto mantêm um chunk em que um dispositvo está carregado, mas consome energia continuamente enquanto ativo. oc:tooltip.UpgradeContainerCard=Este aprimoramento de contêiner permite dinamicamente instalar e remover um cartão de um dispositivo montado. [nl] Nível máximo: §f%s§7 oc:tooltip.UpgradeContainerUpgrade=Este aprimoramento de contêiner permite dinamicamente instalar e remover outro aprimoramento de um dispositivo montado. [nl] Nível máximo: §f%s§7 oc:tooltip.UpgradeCrafting=Permite que robôs usem o canto superior esquerdo de seu inventário para construir objetos. Os itens devem estar posicionados como se estivessem numa mesa de trabalho. @@ -369,17 +378,21 @@ oc:tooltip.UpgradeGenerator=Pode ser usado para gerar combustível em movimento. oc:tooltip.UpgradeHover=Este aprimoramento permite que robôs voem acima do solo sem precisar escalar paredes.[nl] Altura máxima: §f%s§7 oc:tooltip.UpgradeInventory=Este aprimoramento provê espaço no inventário para robôs ou drones. Sem um destes, eles não serão capazes de armazenar itens internamente. oc:tooltip.UpgradeInventoryController=Este aprimoramento permite que robôs e drones tenham mais controle de como eles interagem com o inventário externo, e permite que robôs troquem sua ferramenta equipada com algum item do seu inventário. +oc:tooltip.UpgradeMF=Permite que adaptadores acessem blocos não adjacentes. +oc:tooltip.UpgradeMF.Linked=§fConexão estabelecida§7 +oc:tooltip.UpgradeMF.Unlinked=§fSem conexão§7 oc:tooltip.UpgradeLeash=Permite que alguns dispostivos, como drones, coloquem animais em coleiras. MUITOSSSS ANIMAIIIIIIss. oc:tooltip.UpgradeNavigation=Pode ser usado para determinar a posição e orientação de um dispositivo. A posição é relativa ao centro do mapa que foi usado para construir este aprimoramento. -oc:tooltip.UpgradePiston=Este aprimoramento tem um movimento sexy. Permite mexer blocos, como se estive-se usando um pistão. Isto §lnão§7 move entidades. -oc:tooltip.UpgradeSign=Permite escrever texto nele e escrever placa de textos. +oc:tooltip.UpgradePiston=Este aprimoramento tem um movimento agressivo. Permite mexer blocos, como se estivesse usando um pistão. Isto §lnão§7 move entidades. +oc:tooltip.UpgradeSign=Permite ler e escrever em placas de texto. oc:tooltip.UpgradeSolarGenerator=Pode ser usado para gerar energia solar em movimento. Requer uma linha de visão limpa do céu acima do dispositivo. Gera energia em %s%% da velocidade de um Motor Stirling. -oc:tooltip.UpgradeTank=Este aprimoramento provê um armazenamento de tanque ou fluídos para robôs e drones. Sem um destes, ele não será capaz de armazenar fluídos internamente. -oc:tooltip.UpgradeTankController=Este aprimoramento permite que robôs e drones tenham mais controle de como eles interagem com tanques externos, e permite que ele transfira fluídos para os tanques e dos tanques. +oc:tooltip.UpgradeTank=Este aprimoramento provê um armazenamento de tanque ou fluidos para robôs e drones. Sem um destes, ele não será capaz de armazenar fluidos internamente. +oc:tooltip.UpgradeTankController=Este aprimoramento permite que robôs e drones tenham mais controle de como eles interagem com tanques externos, e permite que ele transfira fluidos para os tanques e dos tanques. oc:tooltip.UpgradeTractorBeam=Equipa um dispositivo com uma tecnologia extremamente avançada, codenome "Imã". Permite que dispositivos capturem blocos com o raio de 3 blocos de sua localização. +oc:tooltip.UpgradeTrading=Permite que robôs e drones façam trocas com Aldeões. oc:tooltip.Waypoint=Provê um ponto de referência para os dispositvos com um aprimoramento de navegação. oc:tooltip.WirelessNetworkCard=Permite enviar mensagens de rede além do meio normal. Você pode ajustar a §fforça do sinal§7 para controlar o quão longe as mensagens vão. Altos níveis de força de sinal resulta em alto consumo de energia. -oc:tooltip.WorldSensorCard=Permite ler informações sobre o mundo, como gravidade e/ou se tem uma atmosfera respirável. Use os resultados por sua conta e risco. O fabricando não se responsabiliza por danos corporais ou materias por decisões causadas sobre as saídas dos cartões. Nós temos leis. E dinheiro. Então nem tente. +oc:tooltip.WorldSensorCard=Permite ler informações sobre o mundo, como gravidade e/ou se tem uma atmosfera respirável. Use os resultados por sua conta e risco. O fabricando não se responsabiliza por danos corporais ou materias por decisões causadas sobre as saídas dos cartões. Nós temos advogados. E dinheiro. Então nem tente. oc:tooltip.Wrench=Um híbrido entre uma Chave de fenda e uma Chave de boca, esta ferramenta é fácil de usar, mas díficil de dominar. #Achievements @@ -388,21 +401,21 @@ achievement.oc.adapter.desc=Interagiu com blocos de outros mods e também do Min achievement.oc.assembler=Explêndido achievement.oc.assembler.desc=Hora de dominar o mundo! achievement.oc.cable=Não é um Fio Sujo -achievement.oc.cable.desc=Com a tecnologia patentiada anti-espaguete. +achievement.oc.cable.desc=Com a tecnologia patenteada de anti-espaguete. achievement.oc.capacitor=Baterias inclusas achievement.oc.capacitor.desc=Você não pode parar isso. achievement.oc.card=Aceitamos Cartões -achievement.oc.card.desc=Para seu entendimento. Sem segundas intenções, prometo. +achievement.oc.card.desc=Para sua conveniência. Sem segundas intenções, prometo. achievement.oc.case=Em Caso de Problemas achievement.oc.case.desc=Porque torres quadradas são as melhores. achievement.oc.charger=Tá bom, vamo lá -achievement.oc.charger.desc=Carrreeegaaaan- dour, esqueça do sinal de redstone de novo. +achievement.oc.charger.desc=Carrreeegaaaan- poxa, esqueci do sinal de redstone de novo. achievement.oc.chip=Todas as Pequenas Coisas -achievement.oc.chip.desc=Porque tubos a vácuo são do passado. +achievement.oc.chip.desc=Porque tubos a vácuo são coisa do passado. achievement.oc.cpu=Overclocked achievement.oc.cpu.desc=Hora de fazer uso destes ciclos computacionais. achievement.oc.disassembler=Vamo quebra tudo! -achievement.oc.disassembler.desc=Em caso de suas ideias brilhantes não sejam tão brilhantes assim. +achievement.oc.disassembler.desc=Caso suas ideias brilhantes não sejam tão brilhantes assim. achievement.oc.diskDrive=Roda a Roda. achievement.oc.diskDrive.desc=Capacidade inferior mas um som lindíssimo. achievement.oc.drone=Voando alto. @@ -410,7 +423,7 @@ achievement.oc.drone.desc=Mantenha a calma e jogue-o para fora do planeta. achievement.oc.eeprom=Só pode ter um achievement.oc.eeprom.desc=Por computador, claro. Para manter a ordem da inicialização, entendeu? achievement.oc.floppy=Um ri- disco -achievement.oc.floppy.desc=Velho mais ainda funciona. +achievement.oc.floppy.desc=Velho, mas ainda funciona. achievement.oc.geolyzer=Pra dentro da Terra achievement.oc.geolyzer.desc=Têm qualidades extraordinárias. achievement.oc.graphicsCard=Ultima Geração @@ -428,9 +441,9 @@ achievement.oc.motionSensor.desc=Igual a Steve Swagger. achievement.oc.networkCard=Agora Estamos Falando! achievement.oc.networkCard.desc=Mantenha contato com esses parentes distantes. achievement.oc.openOS=Buti -achievement.oc.openOS.desc=Um SO para bot - espere, Já usei isso antes? Droga. -achievement.oc.powerDistributor=Compartilhar é Amor -achievement.oc.powerDistributor.desc=Quando precisa de ajuda distribua essa energia. +achievement.oc.openOS.desc=Um SO para - espere, já usei essa antes? Droga. +achievement.oc.powerDistributor=Compartilhar é Amar +achievement.oc.powerDistributor.desc=Quando você precisa de ajuda para equilibrar toda essa energia. achievement.oc.rack=Mas que potência achievement.oc.rack.desc=Sim, os racks de servidores são potentes. achievement.oc.raid=LFG @@ -444,13 +457,13 @@ achievement.oc.redstoneIO.desc=Levando os sinais de redstone para onde quiser. achievement.oc.robot=Bip Bip achievement.oc.robot.desc=EXTERMINAR! achievement.oc.screen=Tentou desligar e ligar de novo? -achievement.oc.screen.desc=Não, não. Um pulso de redstone pode alternar o monitor entre ligado e desligado. +achievement.oc.screen.desc=Não, de verdade. Um pulso de redstone pode alternar o monitor entre ligado e desligado. achievement.oc.server=Dedicado achievement.oc.server.desc=Servidores na nuvem, aqui vamos nós. achievement.oc.switch=Topologia Complexa achievement.oc.switch.desc=Evite embalagens baratas devido a possibilidade de pacotes perdidos. -achievement.oc.tablet=Não engula -achievement.oc.tablet.desc=Mantenha longe do alcance das crianças para evitar um exagero no seu cartão de crédito. +achievement.oc.tablet=Não Engula +achievement.oc.tablet.desc=Mantenha longe do alcance das crianças para evitar cobranças exageradas no seu cartão de crédito. achievement.oc.transistor=Onipresente achievement.oc.transistor.desc=Crie um Transistor para começar. achievement.oc.wirelessNetworkCard=Sinais @@ -460,9 +473,9 @@ achievement.oc.wirelessNetworkCard.desc=Hora de ir onde nenhum pacote foi antes. # set in the actual damage source in code. death.attack.oc.nanomachinesOverload.1=%s foi muito ganancioso. death.attack.oc.nanomachinesOverload.2=%s teve um ataque de nervos. -death.attack.oc.nanomachinesOverload.3=As nanomaquinas de %s estão fora de controle. -death.attack.oc.nanomachinesHungry.1=%s foi comido por nanomaquinas. -death.attack.oc.nanomachinesHungry.2=%s não alimentou suas nanomaquinas. +death.attack.oc.nanomachinesOverload.3=As nanomáquinas de %s estão fora de controle. +death.attack.oc.nanomachinesHungry.1=%s foi comido por nanomáquinas. +death.attack.oc.nanomachinesHungry.2=%s não alimentou suas nanomáquinas. death.attack.oc.nanomachinesHungry.3=%s foi digerido. # NEI Integration From 9bb7b6952830a6143d2e8bacc15b6ed099550807 Mon Sep 17 00:00:00 2001 From: payonel Date: Tue, 11 May 2021 09:08:12 -0700 Subject: [PATCH 11/19] allow orphaned coroutines to function. they could be referenced in detached threads. closes #3423 --- .../assets/opencomputers/loot/openos/boot/01_process.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/resources/assets/opencomputers/loot/openos/boot/01_process.lua b/src/main/resources/assets/opencomputers/loot/openos/boot/01_process.lua index 208d41111..4fc9428eb 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/boot/01_process.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/boot/01_process.lua @@ -16,7 +16,8 @@ _G.coroutine = setmetatable( }, { __index = function(_, key) - return assert(process.info(_coroutine.running()), "thread has no proc").data.coroutine_handler[key] + local proc = process.info(_coroutine.running()) + return (proc and proc.data.coroutine_handler or _coroutine)[key] end } ) From a1d1834597cc8ca3dc6787da991e519efcbcd510 Mon Sep 17 00:00:00 2001 From: payonel Date: Tue, 11 May 2021 09:33:36 -0700 Subject: [PATCH 12/19] seems onLoaded from ic2 can call oc before traits are ready. this probably closes #3187 --- .../li/cil/oc/common/tileentity/traits/RedstoneAware.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/RedstoneAware.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/RedstoneAware.scala index 5d58afe55..fdc794773 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/RedstoneAware.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/RedstoneAware.scala @@ -92,7 +92,10 @@ trait RedstoneAware extends RotationAware with IConnectable with IRedstoneEmitte def getOutput: Array[Int] = ForgeDirection.VALID_DIRECTIONS.map{ side: ForgeDirection => _output(toLocal(side).ordinal) } - def getOutput(side: ForgeDirection) = _output(toLocal(side).ordinal()) + def getOutput(side: ForgeDirection) = Option(_output) match { + case Some(output) => output(toLocal(side).ordinal()) + case _ => 0 + } def setOutput(side: ForgeDirection, value: Int): Boolean = { if (value == getOutput(side)) return false From 90be0181bcede454ace2db7acade660db99e6fea Mon Sep 17 00:00:00 2001 From: payonel Date: Tue, 11 May 2021 13:03:41 -0700 Subject: [PATCH 13/19] args drop returns scala iterator, no need to cast again, toArray will work closes #3159 --- src/main/scala/li/cil/oc/server/component/DebugCard.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/scala/li/cil/oc/server/component/DebugCard.scala b/src/main/scala/li/cil/oc/server/component/DebugCard.scala index 4ab26c9e7..8d2f0e301 100644 --- a/src/main/scala/li/cil/oc/server/component/DebugCard.scala +++ b/src/main/scala/li/cil/oc/server/component/DebugCard.scala @@ -259,8 +259,7 @@ class DebugCard(host: EnvironmentHost) extends prefab.ManagedEnvironment with De checkAccess() val destination = args.checkString(0) DebugNetwork.getEndpoint(destination).filter(_ != this).foreach{endpoint => - // Cast to iterable to use Scala's toArray instead of the Arguments' one (which converts byte arrays to Strings). - val packet = Network.newPacket(node.address, destination, 0, args.drop(1).asInstanceOf[java.lang.Iterable[AnyRef]].toArray) + val packet = Network.newPacket(node.address, destination, 0, args.drop(1).toArray) endpoint.receivePacket(packet) } result() From 4a50b50725b53f87d8effbf4a3acb7aa7493c15d Mon Sep 17 00:00:00 2001 From: payonel Date: Wed, 12 May 2021 07:21:54 -0700 Subject: [PATCH 14/19] fix raw set fg and bg methods for row, col, and even the color fields. closes #3401 --- .gitignore | 4 ++++ .../oc/common/component/traits/TextBufferProxy.scala | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 2ce31b1d6..a3a069964 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,7 @@ # VSCode /.vscode /saves +/logs +/config +/options.txt +/usernamecache.json diff --git a/src/main/scala/li/cil/oc/common/component/traits/TextBufferProxy.scala b/src/main/scala/li/cil/oc/common/component/traits/TextBufferProxy.scala index c0c5f9e1d..41a9ea286 100644 --- a/src/main/scala/li/cil/oc/common/component/traits/TextBufferProxy.scala +++ b/src/main/scala/li/cil/oc/common/component/traits/TextBufferProxy.scala @@ -130,9 +130,9 @@ trait TextBufferProxy extends api.internal.TextBuffer { for (y <- row until ((row + color.length) min data.height)) { val line = color(y - row) for (x <- col until ((col + line.length) min data.width)) { - val packedBackground = data.format.deflate(PackedColor.Color(line(x - col))) & 0x00FF - val packedForeground = data.color(row)(col) & 0xFF00 - data.color(row)(col) = (packedForeground | packedBackground).toShort + val packedBackground = data.color(y)(x) & 0x00FF + val packedForeground = (data.format.deflate(PackedColor.Color(line(x - col))) << PackedColor.ForegroundShift) & 0xFF00 + data.color(y)(x) = (packedForeground | packedBackground).toShort } } } @@ -141,9 +141,9 @@ trait TextBufferProxy extends api.internal.TextBuffer { for (y <- row until ((row + color.length) min data.height)) { val line = color(y - row) for (x <- col until ((col + line.length) min data.width)) { - val packedBackground = data.color(row)(col) & 0x00FF - val packedForeground = (data.format.deflate(PackedColor.Color(line(x - col))) << PackedColor.ForegroundShift) & 0xFF00 - data.color(row)(col) = (packedForeground | packedBackground).toShort + val packedBackground = data.format.deflate(PackedColor.Color(line(x - col))) & 0x00FF + val packedForeground = data.color(y)(x) & 0xFF00 + data.color(y)(x) = (packedForeground | packedBackground).toShort } } } From 41a6b8ac965e4e3e30f0c762c7f0576c145134ae Mon Sep 17 00:00:00 2001 From: payonel Date: Wed, 12 May 2021 09:22:40 -0700 Subject: [PATCH 15/19] generator fixes and change in behavior 1. insert now puts a single container back in the inventory. this is not fully ic2 fuel cell compatible, you'll lose fuel cells. :) 2. remove requires container if fuel has container type 3. count returns 2nd value, the item name closes #3391 --- .../server/component/UpgradeGenerator.scala | 76 ++++++++++++++----- 1 file changed, 58 insertions(+), 18 deletions(-) diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala b/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala index 710f8129a..33c34c31f 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala @@ -53,6 +53,8 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends pr if (!TileEntityFurnace.isItemFuel(stack)) { return result(Unit, "selected slot does not contain fuel") } + val container = stack.getItem().getContainerItem(stack) + var consumedCount = 0 inventory match { case Some(existingStack) => if (!existingStack.isItemEqual(stack) || @@ -63,38 +65,79 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends pr if (space <= 0) { return result(Unit, "queue is full") } - val moveCount = math.min(stack.stackSize, math.min(space, count)) - existingStack.stackSize += moveCount - stack.stackSize -= moveCount + consumedCount = math.min(stack.stackSize, math.min(space, count)) + existingStack.stackSize += consumedCount + stack.stackSize -= consumedCount case _ => - inventory = Some(stack.splitStack(math.min(stack.stackSize, count))) + consumedCount = math.min(stack.stackSize, count) + inventory = Some(stack.splitStack(consumedCount)) } - if (stack.stackSize > 0) host.mainInventory.setInventorySlotContents(host.selectedSlot, stack) - else host.mainInventory.setInventorySlotContents(host.selectedSlot, null) + if (consumedCount > 0 && container != null) { + container.stackSize = consumedCount + } + if (stack.stackSize > 0) { + host.mainInventory.setInventorySlotContents(host.selectedSlot, stack) + } + if (stack.stackSize == 0 || container != null) { + host.mainInventory.setInventorySlotContents(host.selectedSlot, container) + } + result(true) } @Callback(doc = """function():number -- Get the size of the item stack in the generator's queue.""") def count(context: Context, args: Arguments): Array[AnyRef] = { inventory match { - case Some(stack) => result(stack.stackSize) + case Some(stack) => result(stack.stackSize, stack.getItem.getItemStackDisplayName(stack)) case _ => result(0) } } + @Callback() + def clear(context: Context, args: Arguments): Array[AnyRef] = { + inventory = None + remainingTicks = 0 + result(true) + } + @Callback(doc = """function([count:number]):boolean -- Tries to remove items from the generator's queue.""") def remove(context: Context, args: Arguments): Array[AnyRef] = { val count = args.optInteger(0, Int.MaxValue) + var selectSlotContainer: ItemStack = null inventory match { case Some(stack) => - val removedStack = stack.splitStack(math.min(count, stack.stackSize)) - val success = host.player.inventory.addItemStackToInventory(removedStack) - stack.stackSize += removedStack.stackSize - if (success && stack.stackSize <= 0) { - inventory = None + val moveCount = Option(stack.getItem().getContainerItem(stack)) match { + case Some(fuelContainer) => + // if the fuel requires a container, we can only refill containers + Option(host.mainInventory.getStackInSlot(host.selectedSlot)) match { + case Some(selectedStack) if selectedStack.getItem() == fuelContainer.getItem() => + selectSlotContainer = selectedStack.copy() // keep a copy in case we have to put it back + 1 // refill one container + case _ => 0 // container required + } + case _ => count } - result(success) - case _ => result(false) + if (moveCount == 0) { + result(false, "fuel requires container in the selected slot") + } else { + val removedStack = stack.splitStack(math.min(moveCount, stack.stackSize)) + if (selectSlotContainer != null) { + host.mainInventory.decrStackSize(host.selectedSlot, 1) + } + val success = host.player.inventory.addItemStackToInventory(removedStack) + stack.stackSize += removedStack.stackSize + if (success) { + if (stack.stackSize <= 0) { + inventory = None + } + result(true) + } else { + // if we decremented the container, we need to put it back + host.mainInventory.setInventorySlotContents(host.selectedSlot, selectSlotContainer) + result(false, "no inventory space available for fuel") + } + } + case _ => result(false, "queue is empty") } } @@ -108,13 +151,10 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends pr val stack = inventory.get remainingTicks = TileEntityFurnace.getItemBurnTime(stack) if (remainingTicks > 0) { - // If not we probably have a container item now (e.g. bucket after lava bucket). updateClient() stack.stackSize -= 1 if (stack.stackSize <= 0) { - if (stack.getItem.hasContainerItem(stack)) - inventory = Option(stack.getItem.getContainerItem(stack)) - else + // do not put container in inventory (we left the container when fuel was inserted) inventory = None } } From ff3c2f51a97070806a26fe7369129322990c2af4 Mon Sep 17 00:00:00 2001 From: payonel Date: Wed, 12 May 2021 19:10:38 -0700 Subject: [PATCH 16/19] implement getInventoryStackLimit for Disassembler to limit transfers from the transposer (and other possible api calls) closes #3247 --- src/main/scala/li/cil/oc/common/tileentity/Disassembler.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/scala/li/cil/oc/common/tileentity/Disassembler.scala b/src/main/scala/li/cil/oc/common/tileentity/Disassembler.scala index 25c03a21f..c6802fa97 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Disassembler.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Disassembler.scala @@ -37,6 +37,8 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra var totalRequiredEnergy = 0.0 + override def getInventoryStackLimit: Int = 1 + var buffer = 0.0 var disassembleNextInstantly = false From 278e7bdbefbf99be3116e9b95d6cc613e37e93f5 Mon Sep 17 00:00:00 2001 From: payonel Date: Thu, 13 May 2021 05:44:19 -0700 Subject: [PATCH 17/19] add address key check in item Delegator to limit max stack size to 1 closes #3226 --- .../li/cil/oc/common/item/Delegator.scala | 9 ++++--- .../li/cil/oc/common/item/HardDiskDrive.scala | 8 +++---- .../cil/oc/common/item/data/DriveData.scala | 2 +- .../oc/integration/opencomputers/Item.scala | 24 +++++++++++++++++++ .../li/cil/oc/server/fs/FileSystem.scala | 4 ++-- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/main/scala/li/cil/oc/common/item/Delegator.scala b/src/main/scala/li/cil/oc/common/item/Delegator.scala index d827c04af..b0862aaf4 100644 --- a/src/main/scala/li/cil/oc/common/item/Delegator.scala +++ b/src/main/scala/li/cil/oc/common/item/Delegator.scala @@ -2,7 +2,6 @@ package li.cil.oc.common.item import java.util import java.util.Random - import cpw.mods.fml.relauncher.Side import cpw.mods.fml.relauncher.SideOnly import li.cil.oc.CreativeTab @@ -13,6 +12,7 @@ import li.cil.oc.api.driver.item.Chargeable import li.cil.oc.api.event.RobotRenderEvent.MountPoint import li.cil.oc.api.internal.Robot import li.cil.oc.client.renderer.item.UpgradeRenderer +import li.cil.oc.integration.opencomputers.{Item => OpenComputersItem} import li.cil.oc.util.BlockPosition import net.minecraft.client.renderer.texture.IIconRegister import net.minecraft.creativetab.CreativeTabs @@ -48,9 +48,12 @@ class Delegator extends Item with driver.item.UpgradeRenderer with Chargeable { // SubItem // ----------------------------------------------------------------------- // - override def getItemStackLimit(stack: ItemStack) = + override def getItemStackLimit(stack: ItemStack): Int = Delegator.subItem(stack) match { - case Some(subItem) => subItem.maxStackSize + case Some(subItem) => OpenComputersItem.address(stack) match { + case Some(address) => 1 + case _ => subItem.maxStackSize + } case _ => maxStackSize } diff --git a/src/main/scala/li/cil/oc/common/item/HardDiskDrive.scala b/src/main/scala/li/cil/oc/common/item/HardDiskDrive.scala index da7b2a227..57ee665a9 100644 --- a/src/main/scala/li/cil/oc/common/item/HardDiskDrive.scala +++ b/src/main/scala/li/cil/oc/common/item/HardDiskDrive.scala @@ -4,11 +4,11 @@ import li.cil.oc.Settings import net.minecraft.item.ItemStack class HardDiskDrive(val parent: Delegator, val tier: Int) extends traits.Delegate with traits.ItemTier with traits.FileSystemLike { - override val unlocalizedName = super.unlocalizedName + tier - val kiloBytes = Settings.get.hddSizes(tier) - val platterCount = Settings.get.hddPlatterCounts(tier) + override val unlocalizedName: String = super.unlocalizedName + tier + val kiloBytes: Int = Settings.get.hddSizes(tier) + val platterCount: Int = Settings.get.hddPlatterCounts(tier) - override def displayName(stack: ItemStack) = { + override def displayName(stack: ItemStack): Option[String] = { val localizedName = parent.internalGetItemStackDisplayName(stack) Some(if (kiloBytes >= 1024) { localizedName + s" (${kiloBytes / 1024}MB)" diff --git a/src/main/scala/li/cil/oc/common/item/data/DriveData.scala b/src/main/scala/li/cil/oc/common/item/data/DriveData.scala index 2a0cc6e53..1190612b8 100644 --- a/src/main/scala/li/cil/oc/common/item/data/DriveData.scala +++ b/src/main/scala/li/cil/oc/common/item/data/DriveData.scala @@ -41,7 +41,7 @@ object DriveData { val data = new DriveData(stack) if (!data.isLocked) { data.lockInfo = key match { - case name: String if name != null && !name.isEmpty => name + case name: String if name != null && name.nonEmpty => name case _ => "notch" // meaning: "unknown" } data.save(stack) diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/Item.scala b/src/main/scala/li/cil/oc/integration/opencomputers/Item.scala index 6962cc7e2..5d52946d1 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/Item.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/Item.scala @@ -1,5 +1,6 @@ package li.cil.oc.integration.opencomputers +import com.google.common.base.Strings import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.api.driver @@ -10,6 +11,8 @@ import li.cil.oc.server.driver.Registry import net.minecraft.item.ItemStack import net.minecraft.nbt.NBTTagCompound +import scala.annotation.tailrec + trait Item extends driver.Item { def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]): Boolean = worksWith(stack) && !Registry.blacklist.exists { @@ -52,4 +55,25 @@ object Item { } nbt.getCompoundTag(Settings.namespace + "data") } + + @tailrec + private def getTag(tagCompound: NBTTagCompound, keys: Array[String]): Option[NBTTagCompound] = { + if (keys.length == 0) Option(tagCompound) + else if (!tagCompound.hasKey(keys(0))) None + else getTag(tagCompound.getCompoundTag(keys(0)), keys.drop(1)) + } + + private def getTag(stack: ItemStack, keys: Array[String]): Option[NBTTagCompound] = { + if (stack == null || stack.stackSize == 0) None + else if (!stack.hasTagCompound) None + else getTag(stack.getTagCompound, keys) + } + + def address(stack: ItemStack): Option[String] = { + val addressKey = "address" + getTag(stack, Array(Settings.namespace + "data", "node")) match { + case Some(tag) if tag.hasKey(addressKey) => Option(tag.getString(addressKey)) + case _ => None + } + } } diff --git a/src/main/scala/li/cil/oc/server/fs/FileSystem.scala b/src/main/scala/li/cil/oc/server/fs/FileSystem.scala index db0ed8a63..5aa6cfa08 100755 --- a/src/main/scala/li/cil/oc/server/fs/FileSystem.scala +++ b/src/main/scala/li/cil/oc/server/fs/FileSystem.scala @@ -101,7 +101,7 @@ object FileSystem extends api.detail.FileSystemAPI { } } - override def fromSaveDirectory(root: String, capacity: Long, buffered: Boolean) = { + override def fromSaveDirectory(root: String, capacity: Long, buffered: Boolean): Capacity = { val path = new io.File(DimensionManager.getCurrentSaveRootDirectory, Settings.savePath + root) if (!path.isDirectory) { path.delete() @@ -200,7 +200,7 @@ object FileSystem extends api.detail.FileSystemAPI { extends VirtualFileSystem with Buffered with Capacity { - protected override def segments(path: String) = { + protected override def segments(path: String): Array[String] = { val parts = super.segments(path) if (isCaseInsensitive) toCaseInsensitive(parts) else parts } From acd384b7b7531b574490f8527611499513adf282 Mon Sep 17 00:00:00 2001 From: payonel Date: Fri, 14 May 2021 17:41:19 -0700 Subject: [PATCH 18/19] refactor generator upgrade for robustness --- .../server/component/UpgradeGenerator.scala | 156 +++++++++++------- 1 file changed, 92 insertions(+), 64 deletions(-) diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala b/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala index 33c34c31f..fe901763d 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala @@ -49,40 +49,57 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends pr def insert(context: Context, args: Arguments): Array[AnyRef] = { val count = args.optInteger(0, 64) val stack = host.mainInventory.getStackInSlot(host.selectedSlot) - if (stack == null) return result(Unit, "selected slot is empty") + if (stack == null || stack.stackSize == 0) return result(Unit, "selected slot is empty") if (!TileEntityFurnace.isItemFuel(stack)) { return result(Unit, "selected slot does not contain fuel") } - val container = stack.getItem().getContainerItem(stack) - var consumedCount = 0 - inventory match { - case Some(existingStack) => - if (!existingStack.isItemEqual(stack) || - !ItemStack.areItemStackTagsEqual(existingStack, stack)) { + val container: ItemStack = stack.getItem.getContainerItem(stack) + val inQueue: ItemStack = inventory match { + case Some(q) if q != null && q.stackSize > 0 => + if (!q.isItemEqual(stack) || !ItemStack.areItemStackTagsEqual(q, stack)) { return result(Unit, "different fuel type already queued") } - val space = existingStack.getMaxStackSize - existingStack.stackSize - if (space <= 0) { - return result(Unit, "queue is full") - } - consumedCount = math.min(stack.stackSize, math.min(space, count)) - existingStack.stackSize += consumedCount - stack.stackSize -= consumedCount - case _ => - consumedCount = math.min(stack.stackSize, count) - inventory = Some(stack.splitStack(consumedCount)) + q + case _ => null } - if (consumedCount > 0 && container != null) { - container.stackSize = consumedCount + val space = Option(inQueue) match { + case Some(q) if q != null && q.stackSize > 0 => q.getMaxStackSize - q.stackSize + case _ => stack.getMaxStackSize } - if (stack.stackSize > 0) { + if (space == 0) { + return result(Unit, "queue is full") + } + val previousSelectedFuel: ItemStack = stack.copy + val insertLimit: Int = math.min(stack.stackSize, math.min(space, count)) + val fuelToInsert: ItemStack = stack.splitStack(insertLimit) + + // remove the fuel from the inventory + if (stack.stackSize == 0) { + host.mainInventory.setInventorySlotContents(host.selectedSlot, null) + } else { host.mainInventory.setInventorySlotContents(host.selectedSlot, stack) } - if (stack.stackSize == 0 || container != null) { - host.mainInventory.setInventorySlotContents(host.selectedSlot, container) + + // add empty containers to inventory + if (container != null) { + container.stackSize = fuelToInsert.stackSize + if (!host.player.inventory.addItemStackToInventory(container)) { + // no containers could be placed in inventory, give back the fuel + host.mainInventory.setInventorySlotContents(host.selectedSlot, previousSelectedFuel) + return result(false, "no space in inventory for fuel containers") + } else if (container.stackSize > 0) { + // not all the containers could be inserted in the inventory + host.player.entityDropItem(container.copy, -0.25f) + } } - - result(true) + + if (inQueue != null) { + fuelToInsert.stackSize += inQueue.stackSize + } + + inventory = Option(fuelToInsert) + + result(true, insertLimit) } @Callback(doc = """function():number -- Get the size of the item stack in the generator's queue.""") @@ -93,51 +110,59 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends pr } } - @Callback() - def clear(context: Context, args: Arguments): Array[AnyRef] = { - inventory = None - remainingTicks = 0 - result(true) - } - @Callback(doc = """function([count:number]):boolean -- Tries to remove items from the generator's queue.""") def remove(context: Context, args: Arguments): Array[AnyRef] = { val count = args.optInteger(0, Int.MaxValue) - var selectSlotContainer: ItemStack = null - inventory match { - case Some(stack) => - val moveCount = Option(stack.getItem().getContainerItem(stack)) match { - case Some(fuelContainer) => - // if the fuel requires a container, we can only refill containers - Option(host.mainInventory.getStackInSlot(host.selectedSlot)) match { - case Some(selectedStack) if selectedStack.getItem() == fuelContainer.getItem() => - selectSlotContainer = selectedStack.copy() // keep a copy in case we have to put it back - 1 // refill one container - case _ => 0 // container required - } - case _ => count - } - if (moveCount == 0) { - result(false, "fuel requires container in the selected slot") + if (count <= 0) { + return result(true) // it is allowed to remove zero + } + val inQueue: ItemStack = inventory match { + case Some(q) if q != null && q.stackSize > 0 => q + case _ => null + } + if (inQueue == null) { + return result(false, "queue is empty") + } + val previousSelectedItem: ItemStack = host.mainInventory.getStackInSlot(host.selectedSlot) match { + case s: ItemStack if s != null => s.copy + case _ => null + } + val selectedEmptyContainer: Option[ItemStack] = inQueue.getItem.getContainerItem(inQueue) match { + case requiredContainer if requiredContainer != null && requiredContainer.stackSize > 0 => previousSelectedItem match { + case slotItem: ItemStack if slotItem != null && slotItem.stackSize > 0 && slotItem.getItem == requiredContainer.getItem => Option(slotItem.copy) + case _ => return result(false, "removing this fuel requires the appropriate container in the selected slot") + } + case _ => None // nothing to do, nothing required + } + + val removeLimit: Int = math.min(inQueue.stackSize, selectedEmptyContainer match { + case Some(emptyContainer) => emptyContainer.stackSize + case _ => count + }) + + // backup in case of failure + val previousQueue = inQueue.copy + val forUser = inQueue.splitStack(removeLimit) + selectedEmptyContainer match { + case Some(emptyContainer) => + emptyContainer.splitStack(removeLimit) + if (emptyContainer.stackSize == 0) { + host.mainInventory.setInventorySlotContents(host.selectedSlot, null) } else { - val removedStack = stack.splitStack(math.min(moveCount, stack.stackSize)) - if (selectSlotContainer != null) { - host.mainInventory.decrStackSize(host.selectedSlot, 1) - } - val success = host.player.inventory.addItemStackToInventory(removedStack) - stack.stackSize += removedStack.stackSize - if (success) { - if (stack.stackSize <= 0) { - inventory = None - } - result(true) - } else { - // if we decremented the container, we need to put it back - host.mainInventory.setInventorySlotContents(host.selectedSlot, selectSlotContainer) - result(false, "no inventory space available for fuel") - } + host.mainInventory.decrStackSize(host.selectedSlot, removeLimit) } - case _ => result(false, "queue is empty") + case _ => // do nothing + } + // addItemStackToInventory splits the input stack by reference + if (!host.player.inventory.addItemStackToInventory(forUser)) { + // returns false if NO items were inserted + host.mainInventory.setInventorySlotContents(host.selectedSlot, previousSelectedItem) + inventory = Option(previousQueue) + result (false, "no inventory space available for fuel") + } else { + previousQueue.stackSize = inQueue.stackSize + forUser.stackSize + inventory = if (previousQueue.stackSize == 0) None else Option(previousQueue) + result(true, removeLimit - forUser.stackSize) } } @@ -211,3 +236,6 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends pr } } } + +class GeneratorActionException extends Exception { +} From e38c3fd308a7fc48cac2156ec34440d4dad9124a Mon Sep 17 00:00:00 2001 From: payonel Date: Fri, 14 May 2021 19:01:11 -0700 Subject: [PATCH 19/19] check tag info for bucket compare on remove --- .../li/cil/oc/server/component/UpgradeGenerator.scala | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala b/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala index fe901763d..86b43728f 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala @@ -129,7 +129,11 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends pr } val selectedEmptyContainer: Option[ItemStack] = inQueue.getItem.getContainerItem(inQueue) match { case requiredContainer if requiredContainer != null && requiredContainer.stackSize > 0 => previousSelectedItem match { - case slotItem: ItemStack if slotItem != null && slotItem.stackSize > 0 && slotItem.getItem == requiredContainer.getItem => Option(slotItem.copy) + case slotItem: ItemStack if + slotItem != null && + slotItem.stackSize > 0 && + slotItem.getItem == requiredContainer.getItem && + ItemStack.areItemStackTagsEqual(slotItem, requiredContainer) => Option(slotItem.copy) case _ => return result(false, "removing this fuel requires the appropriate container in the selected slot") } case _ => None // nothing to do, nothing required @@ -193,7 +197,7 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends pr } } - private def updateClient() = host match { + private def updateClient(): Unit = host match { case robot: internal.Robot => robot.synchronizeSlot(robot.componentSlot(node.address)) case _ => } @@ -236,6 +240,3 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends pr } } } - -class GeneratorActionException extends Exception { -}