diff --git a/.travis.yml b/.travis.yml index df81f4ef6..22223c3d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ sudo: false language: scala scala: 2.11.1 jdk: oraclejdk8 +dist: trusty notifications: email: false diff --git a/build.gradle b/build.gradle index 257789d86..e810eee5b 100644 --- a/build.gradle +++ b/build.gradle @@ -9,20 +9,21 @@ buildscript { name = "sonatype" url = "https://oss.sonatype.org/content/repositories/snapshots/" } + maven { + url = "https://jitpack.io" + } } dependencies { - classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT' + classpath 'com.github.CDAGaming:ForgeGradle:1c670759c5' + classpath 'com.github.CDAGaming:CurseGradle:184e4322fd' } } -plugins { - id "com.matthewprenger.cursegradle" version "1.0.9" -} - apply plugin: 'scala' apply plugin: 'forge' apply plugin: 'idea' apply plugin: 'maven-publish' +apply plugin: 'com.matthewprenger.cursegradle' file "build.properties" withReader { def prop = new Properties() @@ -77,53 +78,61 @@ repositories { name = "mightypirates" url = "https://maven.cil.li/" } + // These are necessary because some parts of the maven repo is weirdly structured, this needs to be fixed. + ivy { + name 'weird maven repos' + artifactPattern "https://maven.cil.li/[module]/[revision]/[module]-[revision].[ext]" + } + ivy { + name 'weird maven repos 2' + artifactPattern "https://maven.cil.li/[module]/[revision]/[module]-[revision]-[classifier].[ext]" + } } configurations { - provided embedded - compile.extendsFrom embedded + implementation.extendsFrom embedded } dependencies { - provided "appeng:RotaryCraft:${config.rotc.version}:api" - provided ("appeng:appliedenergistics2:${config.ae2.version}:dev") { + compileOnly "appeng:RotaryCraft:${config.rotc.version}:api" + compileOnly ("appeng:appliedenergistics2:${config.ae2.version}:dev") { exclude module: 'buildcraft' } - provided "codechicken:CodeChickenLib:${config.minecraft.version}-${config.ccl.version}:dev" - provided "codechicken:EnderStorage:${config.minecraft.version}-${config.es.version}:dev" - provided "codechicken:ForgeMultipart:${config.minecraft.version}-${config.fmp.version}:dev" - provided "codechicken:NotEnoughItems:${config.minecraft.version}-${config.nei.version}:dev" - provided "codechicken:WR-CBE:${config.minecraft.version}-${config.wrcbe.version}:dev" - provided "com.bluepowermod:BluePower:${config.bluepower.version}:deobf" - provided "com.gregoriust.gregtech:gregtech_${config.minecraft.version}:${config.gt.version}:dev" - provided "igwmod:IGW-Mod-1.7.10:${config.igwmod.version}:userdev" - provided "li.cil.tis3d:TIS-3D:${config.tis3d.version}:dev" - provided "mcp.mobius.waila:Waila:${config.waila.version}_${config.minecraft.version}:dev" - provided "net.industrial-craft:industrialcraft-2:${config.ic2.version}:dev" - provided "net.sengir.forestry:forestry_${config.minecraft.version}:${config.forestry.version}:dev" - provided "dev.modwarriors.notenoughkeys:NotEnoughKeys:${config.minecraft.version}-${config.nek.version}:deobf-dev" - provided "qmunity:QmunityLib:${config.qmunitylib.version}:deobf" - provided "tmech:TMechworks:${config.minecraft.version}-${config.tmech.version}:deobf" - provided ("mrtjp:ProjectRed:${config.projred.version}:dev") { + compileOnly "codechicken:CodeChickenLib:${config.minecraft.version}-${config.ccl.version}:dev" + compileOnly "codechicken:EnderStorage:${config.minecraft.version}-${config.es.version}:dev" + compileOnly "codechicken:ForgeMultipart:${config.minecraft.version}-${config.fmp.version}:dev" + compileOnly "codechicken:NotEnoughItems:${config.minecraft.version}-${config.nei.version}:dev" + compileOnly "codechicken:WR-CBE:${config.minecraft.version}-${config.wrcbe.version}:dev" + compileOnly "com.bluepowermod:BluePower:${config.bluepower.version}:deobf" + compileOnly "com.gregoriust.gregtech:gregtech_${config.minecraft.version}:${config.gt.version}:dev" + compileOnly "igwmod:IGW-Mod-1.7.10:${config.igwmod.version}:userdev" + compileOnly "li.cil.tis3d:TIS-3D:${config.tis3d.version}:dev" + compileOnly "mcp.mobius.waila:Waila:${config.waila.version}_${config.minecraft.version}:dev" + compileOnly "net.industrial-craft:industrialcraft-2:${config.ic2.version}:dev" + compileOnly "net.sengir.forestry:forestry_${config.minecraft.version}:${config.forestry.version}:dev" + compileOnly "dev.modwarriors.notenoughkeys:NotEnoughKeys:${config.minecraft.version}-${config.nek.version}:deobf-dev" + compileOnly "qmunity:QmunityLib:${config.qmunitylib.version}:deobf" + compileOnly "tmech:TMechworks:${config.minecraft.version}-${config.tmech.version}:deobf" + compileOnly ("mrtjp:ProjectRed:${config.projred.version}:dev") { exclude module: 'CoFHCore' } - // provided "coloredlightscore:ColoredLightsCore:${config.coloredlights.version}:api" + // compileOnly "coloredlightscore:ColoredLightsCore:${config.coloredlights.version}:api" - provided name: 'buildcraft', version: config.bc.version, classifier: "dev", ext: 'jar' - provided name: 'GalacticraftCoreAll', version: config.gc.version, ext: 'jar' - provided name: 'MekanismAll', version: config.mekanism.version, ext: 'jar' - provided name: 'redlogic', version: config.redlogic.version, ext: 'jar' + compileOnly name: 'buildcraft', version: config.bc.version, classifier: "dev", ext: 'jar' + compileOnly name: 'GalacticraftCoreAll', version: config.gc.version, ext: 'jar' + compileOnly name: 'MekanismAll', version: config.mekanism.version, ext: 'jar' + compileOnly name: 'redlogic', version: config.redlogic.version, ext: 'jar' - provided name: 'CoFHLib', version: config.cofhlib.version, ext: 'jar' - provided name: 'CoFHCore', version: config.cofhcore.version, ext: 'jar' - provided name: 'MineFactoryReloaded', version: config.mfr.version, ext: 'jar' - provided name: 'ComputerCraft', version: config.cc.version, ext: 'jar' - provided name: 'EnderIO', version: config.eio.version, ext: 'jar' - provided name: 'Railcraft', version: config.rc.version, ext: 'jar' - provided name: 'BloodMagic', version: config.bloodmagic.version, ext: 'jar' - provided name: 'ExtraCells', version: config.ec.version, ext: 'jar' - provided name: 'ThaumicEnergistics', version: config.thaumicenergistics.version, ext: 'jar' + compileOnly name: 'CoFHLib', version: config.cofhlib.version, ext: 'jar' + compileOnly name: 'CoFHCore', version: config.cofhcore.version, ext: 'jar' + compileOnly name: 'MineFactoryReloaded', version: config.mfr.version, ext: 'jar' + compileOnly name: 'ComputerCraft', version: config.cc.version, ext: 'jar' + compileOnly name: 'EnderIO', version: config.eio.version, ext: 'jar' + compileOnly name: 'Railcraft', version: config.rc.version, ext: 'jar' + compileOnly name: 'BloodMagic', version: config.bloodmagic.version, ext: 'jar' + compileOnly name: 'ExtraCells', version: config.ec.version, ext: 'jar' + compileOnly name: 'ThaumicEnergistics', version: config.thaumicenergistics.version, ext: 'jar' compile 'com.google.code.findbugs:jsr305:1.3.9' // Annotations used by google libs. @@ -134,13 +143,6 @@ dependencies { testCompile "org.scalatest:scalatest_2.11:2.2.6" } -// Add the "provided" dependencies to the compile (but NOT runtime) classpath. -sourceSets.main.compileClasspath += [configurations.provided] - -idea.module.scopes.PROVIDED.plus += [configurations.provided] -// TODO Causes errors on Gradle 2 for me (No such property: allDependencies for class: java.io.File). -//eclipse.classpath.plusConfigurations += [configurations.provided] - minecraft { version = "${config.minecraft.version}-${config.forge.version}" @@ -255,6 +257,7 @@ curseforge { changelog = file("changelog.md") addGameVersion config.minecraft.version addGameVersion "Java 8" + mainArtifact jar } } diff --git a/build.properties b/build.properties index e9d4b2e25..cd7736ec6 100644 --- a/build.properties +++ b/build.properties @@ -1,7 +1,7 @@ minecraft.version=1.7.10 forge.version=10.13.4.1614-1.7.10 -oc.version=1.7.4 +oc.version=1.7.5 ae2.version=rv2-beta-26 bc.version=7.0.9 diff --git a/changelog.md b/changelog.md index 6a43e0c37..70975ba7f 100644 --- a/changelog.md +++ b/changelog.md @@ -1,26 +1,69 @@ ## New Features/Support -* **Misc: when powering on, drones may fly a bit higher** - - will fly a above their starting block to get above nonfull blocks (such as chests) -* Misc: more robot names -* Misc: robot/drone swing respects harvestability of block vs tool -* Fixed: zero sized files (bufferChanges failing to do its job) -* Fixed: client crash when using remote terminal out of range -* Fixed: inventory controllers now honor specified target slot -* Fixed: T1 wireless cards now ignore properly ignore wired messages -* Fixed: waila integration by checking for nulls with relay block -* Fixed: practical logisitics integration by not passing null for EnumFacing -* Fixed: locking items in hotbar when gui is open -* Fixed: some container names localized +**This will be the last version for Minecraft 1.11.2. Minecraft 1.7.10, 1.10.2, and 1.12.2 will keep receiving updates.** + +* **Added: Barcode reader upgrade!** (AmandaCameron) + - An Analyzer can now be installed in a Tablet as an upgrade. + - Provides the `barcode_reader` component. + - When clicking on a block with a tablet containing this upgrade, the `tablet_use` event will contain information the Analyzer would normally reveal. + - This allows getting components' addresses into OC directly by clicking on blocks. +* Added: Config option to set max signal queue size (default 256, the same as before). + - Signals pushed to the computer when the queue is full are dropped. +* Added: Allow different HTTP request methods in `internet.request` (the method to use is now the fourth optional argument). +* Added: You can now install Angel Upgrades in drones (Minecraft 1.12 only). +* Added: Chargers can now charge items in nearby players' inventories. +* Added: Experience Upgrade now shows its level in its tooltip (Minecraft 1.12 only). +* Added: Extended item information to Thaumcraft Essentia Jars on Minecraft 1.12 (seebs) +* Added: Support for SimpleLogic bundled cables on Minecraft 1.12. (asiekierka) +* Added: Re-added Wireless Redstone (ChickenBones Edition) support on Minecraft 1.12. +* Misc: Hide bounding box wireframe on screens while not sneaking +* Misc: More robot names. +* Misc: Updated the chinese translation of the manual. (3TUSK, ZeroAurora, JackyWangMislantiaJnirvana) +* Changed: Cleaned up some wording in the config file. +* Changed: `gpu.bind` is now faster. +* Changed: `computer.pushSignal` now accepts tables of simple key-value pairs, but not nested tables. +* Changed: APU tiers now correspond to their CPU tiers. +* Changed: Putting unmanaged hard drives into a Raid now forces them into managed mode along with wiping them. +* Fixed: Robots being unable to use buckets. +* Fixed: Fluid dupe bug that I will _not_ explain to you. +* Fixed: Tier 2 wireless network card not receiving wired messages. +* Fixed: Return value of `robot.swing` when the block breaks too fast. +* Fixed: Server racks not sending messages to mountables quickly enough. +* Fixed: Relays not displaying traffic accurately. +* Fixed: Relay message relaying issues. +* Fixed: `itemDamageRate` config option set to 0 not working. (svitoos) +* Fixed: Crash with `hologram.copy`. +* Fixed: Geolyzer's `isSunVisible`. +* Fixed: Crash with remote terminals. +* Fixed: A Robot without inventory deleting the items it drops. +* Fixed: `too long without yielding` sometimes not triggering when it should. +* Fixed: Crash when blowing up a computer while code is running. +* Fixed: Another fluid dupe bug that I will definitely not explain to you either. Stop asking. +* Fixed: Available architectures not always being what they should be. +* Fixed: Crashes in AE2 integration. +* Fixed: The AE2 ME Interface part not having network control. +* Fixed: AE2 ME cells not having all intended information on inspection. (wkalinin) +* Fixed: Crash with AE2 when power usage is disabled. +* Fixed: AE2 interface not being recognized as components when channels are disabled. +* Fixed: Some AE2 integration not working on 1.7.10. (wkalinin) +* Fixed: Another crash with AE2 when power usage is disabled. +* Fixed: Specific AE2 integration being very slow. +* Fixed: Crash with IC2 Classic. ## OpenOS fixes/improvements -* Fixed: fixed event timing issues when pulling smaller timeouts than a current timer -* Added: tty handles '\v' code to move cursor down one line -* Misc: some openos cleanup -* Misc: more memory savings -* Misc: slightly faster boot up times +* Fixed: Error related to installing OPPM. +* Fixed: OpenOS timers being starved during blocking pulls. +* Fixed: `reset` alias to reset the screen resolution to its maximum. +* Fixed: Certain TCP connections in Network loot disk +* Fixed: Various vt100 fixes +* Fixed: Now errors properly on using `print` with bad `__string` metamethods ## List of contributors -payonel, Wilma456 -Anar Abdullayev, TheCodex6824 +payonel, +AmandaCameron, wkalinin, +LizzyTrickster, svitoos, +kchanakira, seebs, +asiekierka, +3TUSK, ZeroAurora, +JackyWangMislantiaJnirvana diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f5ba3fdf9..6afbcbb43 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-2.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip diff --git a/src/main/resources/assets/opencomputers/lang/de_DE.lang b/src/main/resources/assets/opencomputers/lang/de_DE.lang index 30f991953..f41d7120c 100644 --- a/src/main/resources/assets/opencomputers/lang/de_DE.lang +++ b/src/main/resources/assets/opencomputers/lang/de_DE.lang @@ -8,6 +8,7 @@ tile.oc.adapter.name=Adapter tile.oc.assembler.name=Elektronik-Werkbank tile.oc.cable.name=Kabel tile.oc.capacitor.name=Kondensator +tile.oc.carpetedCapacitor.name=Teppichkondensator tile.oc.case1.name=Computergehäuse (Stufe 1) tile.oc.case2.name=Computergehäuse (Stufe 2) tile.oc.case3.name=Computergehäuse (Stufe 3) @@ -57,6 +58,7 @@ item.oc.CircuitBoard.name=Leiterplatte item.oc.ComponentBus0.name=Komponentenschnittstelle (Stufe 1) item.oc.ComponentBus1.name=Komponentenschnittstelle (Stufe 2) item.oc.ComponentBus2.name=Komponentenschnittstelle (Stufe 3) +item.oc.ComponentBus3.name=Komponentenschnittstelle (Kreativ) item.oc.ControlUnit.name=Steuerwerk (CU) item.oc.CPU0.name=Hauptprozessor (CPU) (Stufe 1) item.oc.CPU1.name=Hauptprozessor (CPU) (Stufe 2) @@ -201,6 +203,8 @@ oc:gui.Chat.WarningRecipes=Es gab Fehler beim Laden eines oder mehrerer Rezepte. oc:gui.Chat.WarningSimpleComponent=Eine Erweiterung (deine?) welche das §aSimpleComponent§f-Interface verwendet, hat etwas §efalsch gemacht§f. Komponentenlogik konnte nicht eingefügt werden. Bitte wirf einen Blick in deine Log-Datei für weitere Informationen. oc:gui.Drive.Managed=Managed oc:gui.Drive.Unmanaged=Unmanaged +oc:gui.Drive.ReadOnlyLock=Sperre +oc:gui.Drive.ReadOnlyLockWarning=§lNur Lesen§r Sperre. Kann nur entfernt werden, wenn das Laufwerk gelöscht wird. oc:gui.Drive.Warning=§lWarnung§r: Umschalten der Modi führt zum Datenverlust. oc:gui.Error.ComponentOverflow=Zu viele Komponenten sind mit dem Computer verbunden. oc:gui.Error.InternalError=Interner Fehler, bitte sieh in der Logdatei nach. Das ist wahrscheinlich ein Bug. @@ -263,6 +267,7 @@ oc:tooltip.APU=Eine CPU mit integrierter GPU (bzw. IGP), falls du unbedingt den oc:tooltip.Assembler=Erlaubt die Fertigung von Robotern und weiteren Geräten aus diversen anderen Computerteilen. oc:tooltip.Cable=Ein billiger Weg, verschiedene Blöcke miteinander zu verbinden. oc:tooltip.Capacitor=Speichert Energie für spätere Verwendung. Kann extrem schnell befüllt und entleert werden. +oc:tooltip.CarpetedCapacitor=Speichert Energie für den späteren Gebrauch. Kann sehr schnell befüllt und entleert werden. Lädt auf, wenn Schafe oder Ozelots darauf laufen. oc:tooltip.CardBase=Wie der Name schon sagt, werden alle Erweiterungskarten hieraus hergestellt. oc:tooltip.Case=Das Computergehäuse ist der essentielle Grundbaustein für einen Computer. §fErweiterungskarten§7, §fRAM§7 und §fFestplatten§7 können in einem Gehäuse installiert werden.[nl] Slots: §f%s§7 oc:tooltip.Chamelium=Rohmaterial für 3D-Drucke. Nicht zum Verzehr geeignet: kann zu Erblindung und zeitweiligem Verlust von Präsenz führen. @@ -286,6 +291,7 @@ oc:tooltip.DiskDrive.CC=ComputerCraft-Disketten werden §aauch unterstützt§7. oc:tooltip.DiskDrive=Erlaubt es, Disketten zu lesen und zu beschreiben. Kann in Robotern installiert werden, um später Disketten einlegen zu können. oc:tooltip.DiskDriveMountable=Funktioniert genauso wie ein normales Diskettenlaufwerk, wird aber in einem Serverschrank installiert. oc:tooltip.DiskUsage=Festplattennutzung: %s/%s Byte +oc:tooltip.DiskLocked=Gesperrt von %s oc:tooltip.DiskModeManaged=Modus: Managed oc:tooltip.DiskModeUnmanaged=Modus: Unmanaged oc:tooltip.Drone=Drohnen sind schlichte, flinke Aufklärungseinheiten mit limitierter Inventargröße. diff --git a/src/main/resources/assets/opencomputers/lang/en_US.lang b/src/main/resources/assets/opencomputers/lang/en_US.lang index daf682cf5..c96fa6c86 100644 --- a/src/main/resources/assets/opencomputers/lang/en_US.lang +++ b/src/main/resources/assets/opencomputers/lang/en_US.lang @@ -47,8 +47,8 @@ item.oc.AbstractBusCard.name=Abstract Bus Card item.oc.Acid.name=Grog item.oc.ALU.name=Arithmetic Logic Unit (ALU) item.oc.Analyzer.name=Analyzer -item.oc.APU0.name=Accelerated Processing Unit (APU) (Tier 1) -item.oc.APU1.name=Accelerated Processing Unit (APU) (Tier 2) +item.oc.APU0.name=Accelerated Processing Unit (APU) (Tier 2) +item.oc.APU1.name=Accelerated Processing Unit (APU) (Tier 3) item.oc.APU2.name=Accelerated Processing Unit (APU) (Creative) item.oc.ArrowKeys.name=Arrow Keys item.oc.ButtonGroup.name=Button Group diff --git a/src/main/resources/assets/opencomputers/lang/ru_RU.lang b/src/main/resources/assets/opencomputers/lang/ru_RU.lang index ff5cdf945..fe48cb59b 100644 --- a/src/main/resources/assets/opencomputers/lang/ru_RU.lang +++ b/src/main/resources/assets/opencomputers/lang/ru_RU.lang @@ -8,6 +8,7 @@ tile.oc.adapter.name=Адаптер tile.oc.assembler.name=Сборщик tile.oc.cable.name=Кабель tile.oc.capacitor.name=Конденсатор энергии +tile.oc.carpetedCapacitor.name=Конденсатор с ковровым покрытием tile.oc.case1.name=Системный блок (1-ый уровень) tile.oc.case2.name=Системный блок (2-ой уровень) tile.oc.case3.name=Системный блок (3-ий уровень) @@ -57,6 +58,7 @@ item.oc.CircuitBoard.name=Нетравленая печатная плата item.oc.ComponentBus0.name=Компонентная шина (1-ый уровень) item.oc.ComponentBus1.name=Компонентная шина (2-ой уровень) item.oc.ComponentBus2.name=Компонентная шина (3-ий уровень) +item.oc.ComponentBus3.name=Компонентная шина (Творческая) item.oc.ControlUnit.name=Устройство управления (УУ) item.oc.CPU0.name=Центральный процессор (ЦП) (1-ый уровень) item.oc.CPU1.name=Центральный процессор (ЦП) (2-ой уровень) @@ -201,6 +203,8 @@ oc:gui.Chat.WarningRecipes=Произошла ошибка при загрузк oc:gui.Chat.WarningSimpleComponent=Некоторый мод §eневерно§f использует интрефейс §aSimpleComponent§f. Логика компонента не смогла быть внедрена. Проверьте логи, чобы узнать подробнее. oc:gui.Drive.Managed=Файловый режим oc:gui.Drive.Unmanaged=Блочный режим +oc:gui.Drive.ReadOnlyLock=Блокировка +oc:gui.Drive.ReadOnlyLockWarning=Блокировка §lтолько для чтения§r. Не может быть снята, если только носитель не был стёрт. oc:gui.Drive.Warning=§lВнимание§r: переключение режимов очищает диск! oc:gui.Error.ComponentOverflow=Слишком много компонентов подключено к компьютеру. oc:gui.Error.InternalError=Возникла внутренняя ошибка, пожалуйста, посмотрите лог-файл. Возможно, это баг. @@ -263,6 +267,7 @@ oc:tooltip.APU=Это процессор со встроенной видеок oc:tooltip.Assembler=Позволяет собирать роботов и другие устройства из ряда различных частей компьютера. oc:tooltip.Cable=Простой и дешёвый способ соединить компоненты между собой. oc:tooltip.Capacitor=Накапливает энергию для дальнейшего использования. Может быть очень быстро заполнен и опустошён. +oc:tooltip.CarpetedCapacitor=Накапливает энергию для последующего использования. Может быть заполнен и опорожнен очень быстро. Заряжается, когда по нём гуляют овцы или оцелоты oc:tooltip.CardBase=Как видно из названия, это основа для всех карт расширения. oc:tooltip.Case=Системный блок - основа компьютера, содержащий §fкарты расширения§7, §fОЗУ§7 и §fжёсткие диски§7.[nl] Слотов: §f%s§7 oc:tooltip.Chamelium=Базовый материал для 3D печати. Не глотать: может привести к слепоте и временным отсутствием присутствия. @@ -286,6 +291,7 @@ oc:tooltip.DiskDrive.CC=§aПоддерживаются§7 дискеты из C oc:tooltip.DiskDrive=Позволяет читать и записывать дискеты. Может быть установлен в роботов, что позволит затем вставлять дискеты. oc:tooltip.DiskDriveMountable=Работает так же, как и обычный дисковод, но может быть вставлен только в серверную стойку. oc:tooltip.DiskUsage=Занято %s/%s байт +oc:tooltip.DiskLocked=Блокирован: %s oc:tooltip.DiskModeManaged=Режим: файловый oc:tooltip.DiskModeUnmanaged=Режим: блочный oc:tooltip.Drone=Дроны это легкие и быстрые устройства, но с ограниченным инвентарем. diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/core/boot.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/core/boot.lua index 4e51bf576..4c7c138ab 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/core/boot.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/core/boot.lua @@ -1,7 +1,7 @@ -- called from /init.lua local raw_loadfile = ... -_G._OSVERSION = "OpenOS 1.7.4" +_G._OSVERSION = "OpenOS 1.7.5" -- luacheck: globals component computer unicode _OSVERSION local component = component diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/core/full_text.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/core/full_text.lua index 2f9c33e64..72e55683b 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/core/full_text.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/core/full_text.lua @@ -181,7 +181,7 @@ function text.internal.reader(txt, mode) }, {__index=text.internal.stream_base((mode or ""):match("b"))}) process.closeOnExit(reader) - return require("buffer").new("r", reader) + return require("buffer").new((mode or "r"):match("[rb]+"), reader) end function text.internal.writer(ostream, mode, append_txt) @@ -223,7 +223,7 @@ function text.internal.writer(ostream, mode, append_txt) }, {__index=text.internal.stream_base((mode or ""):match("b"))}) process.closeOnExit(writer) - return require("buffer").new("w", writer) + return require("buffer").new((mode or "w"):match("[awb]+"), writer) end function text.detab(value, tabWidth) diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/io.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/io.lua index 1a6f25ce7..b6ff97116 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/io.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/io.lua @@ -47,17 +47,12 @@ end function io.stream(fd,file,mode) checkArg(1,fd,'number') + checkArg(2, file, "table", "string", "nil") assert(fd>=0,'fd must be >= 0. 0 is input, 1 is stdout, 2 is stderr') local dio = require("process").info().data.io if file then if type(file) == "string" then - local result, reason = io.open(file, mode) - if not result then - error(reason, 2) - end - file = result - elseif not io.type(file) then - error("bad argument #1 (string or file expected, got " .. type(file) .. ")", 2) + file = assert(io.open(file, mode)) end dio[fd] = file end diff --git a/src/main/resources/assets/opencomputers/lua/machine.lua b/src/main/resources/assets/opencomputers/lua/machine.lua index d2751bfb0..1177f5f71 100644 --- a/src/main/resources/assets/opencomputers/lua/machine.lua +++ b/src/main/resources/assets/opencomputers/lua/machine.lua @@ -41,6 +41,7 @@ if hookInterval < 1000 then hookInterval = 1000 end local deadline = math.huge local hitDeadline = false +local tooLongWithoutYielding = setmetatable({}, { __tostring = function() return "too long without yielding" end}) local function checkDeadline() if computer.realTime() > deadline then debug.sethook(coroutine.running(), checkDeadline, "", 1) @@ -48,9 +49,16 @@ local function checkDeadline() deadline = deadline + 0.5 end hitDeadline = true - error("too long without yielding", 0) + error(tooLongWithoutYielding) end end +local function pcallTimeoutCheck(...) + local ok, timeout = ... + if rawequal(timeout, tooLongWithoutYielding) then + return ok, tostring(tooLongWithoutYielding) + end + return ... +end ------------------------------------------------------------------------------- @@ -739,9 +747,7 @@ sandbox = { next = next, pairs = pairs, pcall = function(...) - local result = table.pack(pcall(...)) - checkDeadline() - return table.unpack(result, 1, result.n) + return pcallTimeoutCheck(pcall(...)) end, print = nil, -- in boot/*_base.lua rawequal = rawequal, @@ -785,18 +791,23 @@ sandbox = { tonumber = tonumber, tostring = tostring, type = type, - _VERSION = _VERSION:match("5.3") and "Lua 5.3" or "Lua 5.2", + _VERSION = _VERSION:match("Luaj") and "Luaj" or _VERSION:match("5.3") and "Lua 5.3" or "Lua 5.2", xpcall = function(f, msgh, ...) local handled = false + checkArg(2, msgh, "function") local result = table.pack(xpcall(f, function(...) - if handled then + if (...) == tooLongWithoutYielding then + return tooLongWithoutYielding + elseif handled then return ... else handled = true return msgh(...) end end, ...)) - checkDeadline() + if result[2] == tooLongWithoutYielding then + result = table.pack(result[1], select(2, pcallTimeoutCheck(pcall(msgh, tostring(tooLongWithoutYielding))))) + end return table.unpack(result, 1, result.n) end, @@ -1503,4 +1514,4 @@ end -- JNLua converts the coroutine to a string immediately, so we can't get the -- traceback later. Because of that we have to do the error handling here. -return pcall(main) +return pcallTimeoutCheck(pcall(main)) diff --git a/src/main/resources/assets/opencomputers/robot.names b/src/main/resources/assets/opencomputers/robot.names index 8ba9c910f..33fdcdf7e 100644 --- a/src/main/resources/assets/opencomputers/robot.names +++ b/src/main/resources/assets/opencomputers/robot.names @@ -88,6 +88,7 @@ Michiyo # Contributor Mycroft Holmes # The Moon Is a Harsh Mistress Pac-Man # Pac-Man Optimus # Transformers. Seperated "Optimus Prime" into two names, as both are quite fitting robot names. +Ordis # Warframe P-Body # Portal Pintsize # Questionable Content PixelToast # Contributor diff --git a/src/main/scala/li/cil/oc/common/EventHandler.scala b/src/main/scala/li/cil/oc/common/EventHandler.scala index 35e526e60..093f22f87 100644 --- a/src/main/scala/li/cil/oc/common/EventHandler.scala +++ b/src/main/scala/li/cil/oc/common/EventHandler.scala @@ -193,7 +193,7 @@ object EventHandler { if (SideTracker.isServer) e.player match { case _: FakePlayer => // Nope case player: EntityPlayerMP => - if (!LuaStateFactory.isAvailable) { + if (!LuaStateFactory.isAvailable && !LuaStateFactory.luajRequested) { player.addChatMessage(Localization.Chat.WarningLuaFallback) } if (Recipes.hadErrors) { diff --git a/src/main/scala/li/cil/oc/common/Proxy.scala b/src/main/scala/li/cil/oc/common/Proxy.scala index 3e92416b2..ce7c6d1ac 100644 --- a/src/main/scala/li/cil/oc/common/Proxy.scala +++ b/src/main/scala/li/cil/oc/common/Proxy.scala @@ -79,7 +79,7 @@ class Proxy { if (LuaStateFactory.include53) { api.Machine.add(classOf[NativeLua53Architecture]) } - if (api.Machine.architectures.size == 0) { + if (LuaStateFactory.includeLuaJ) { api.Machine.add(classOf[LuaJLuaArchitecture]) } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Charger.scala b/src/main/scala/li/cil/oc/common/tileentity/Charger.scala index 48d6c4651..58e7ba876 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Charger.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Charger.scala @@ -36,6 +36,7 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R create() val connectors = mutable.Set.empty[Chargeable] + val equipment = mutable.Set.empty[ItemStack] var chargeSpeed = 0.0 @@ -79,6 +80,14 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R override def canUpdate = true + private def chargeStack(stack: ItemStack, charge: Double): Unit = { + if (stack != null && charge > 0) { + val offered = charge + node.changeBuffer(-charge) + val surplus = ItemCharge.charge(stack, offered) + node.changeBuffer(surplus) + } + } + override def updateEntity() { super.updateEntity() @@ -104,11 +113,16 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R val charge = Settings.get.chargeRateTablet * chargeSpeed * Settings.get.tickFrequency canCharge ||= charge > 0 && node.globalBuffer >= charge * 0.5 if (canCharge) { - (0 until getSizeInventory).map(getStackInSlot).foreach(stack => if (stack != null) { - val offered = charge + node.changeBuffer(-charge) - val surplus = ItemCharge.charge(stack, offered) - node.changeBuffer(surplus) - }) + (0 until getSizeInventory).map(getStackInSlot).foreach(chargeStack(_, charge)) + } + } + + // Charging of equipment + { + val charge = Settings.get.chargeRateTablet * chargeSpeed * Settings.get.tickFrequency + canCharge ||= charge > 0 && node.globalBuffer >= charge * 0.5 + if (canCharge) { + equipment.foreach(chargeStack(_, charge)) } } @@ -219,17 +233,35 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R } val players = world.getEntitiesWithinAABB(classOf[EntityPlayer], bounds).collect { - case player: EntityPlayer if api.Nanomachines.hasController(player) => new PlayerChargeable(player) + case player: EntityPlayer => player + } + + val chargeablePlayers = players.collect { + case player if api.Nanomachines.hasController(player) => new PlayerChargeable(player) } // Only update list when we have to, keeps pointless block updates to a minimum. - val newConnectors = robots ++ drones ++ players + val newConnectors = robots ++ drones ++ chargeablePlayers if (connectors.size != newConnectors.length || (connectors.nonEmpty && (connectors -- newConnectors).nonEmpty)) { connectors.clear() connectors ++= newConnectors world.notifyBlocksOfNeighborChange(x, y, z, block) } + + // scan players for chargeable equipment + equipment.clear() + players.foreach { + player => player.inventory.mainInventory.foreach { + stack: ItemStack => + if (Option(Driver.driverFor(stack, getClass)) match { + case Some(driver) if driver.slot(stack) == Slot.Tablet => true + case _ => ItemCharge.canCharge(stack) + }) { + equipment += stack + } + } + } } trait Chargeable { diff --git a/src/main/scala/li/cil/oc/common/tileentity/Rack.scala b/src/main/scala/li/cil/oc/common/tileentity/Rack.scala index 48bd57d21..7658d23a3 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Rack.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Rack.scala @@ -331,7 +331,8 @@ class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalance super.onRedstoneInputChanged(args) components.collect { case Some(mountable: RackMountable) if mountable.node != null => - mountable.node.sendToNeighbors("redstone.changed", args) + val toLocalArgs = RedstoneChangedEventArgs(toLocal(args.side), args.oldValue, args.newValue, args.color) + mountable.node.sendToNeighbors("redstone.changed", toLocalArgs) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Raid.scala b/src/main/scala/li/cil/oc/common/tileentity/Raid.scala index 590a56cea..8486637fa 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Raid.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Raid.scala @@ -10,6 +10,7 @@ import li.cil.oc.api.Driver import li.cil.oc.api.fs.Label import li.cil.oc.api.network.Analyzable import li.cil.oc.api.network.Visibility +import li.cil.oc.common.item.data.DriveData import li.cil.oc.common.Slot import li.cil.oc.server.component.FileSystem import li.cil.oc.server.{PacketSender => ServerPacketSender} @@ -79,6 +80,14 @@ class Raid extends traits.Environment with traits.Inventory with traits.Rotatabl def tryCreateRaid(id: String) { if (items.count(_.isDefined) == items.length && filesystem.fold(true)(fs => fs.node == null || fs.node.address != id)) { filesystem.foreach(fs => if (fs.node != null) fs.node.remove()) + items.foreach(fs => fs match { + case Some(fsStack) => + val drive = new DriveData(fsStack) + drive.lockInfo = "" + drive.isUnmanaged = false + drive.save(fsStack) + case _ => // should not happen but is safe to ignore + }) val fs = api.FileSystem.asManagedEnvironment( api.FileSystem.fromSaveDirectory(id, wipeDisksAndComputeSpace, Settings.get.bufferChanges), label, this, Settings.resourceDomain + ":hdd_access", 6). diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala index e98ee49dc..fb19e5584 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala @@ -216,7 +216,8 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B override protected def onRedstoneInputChanged(args: RedstoneChangedEventArgs) { super.onRedstoneInputChanged(args) - machine.node.sendToNeighbors("redstone.changed", args) + val toLocalArgs = RedstoneChangedEventArgs(toLocal(args.side), args.oldValue, args.newValue, args.color) + machine.node.sendToNeighbors("redstone.changed", toLocalArgs) } // ----------------------------------------------------------------------- // diff --git a/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala b/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala index 98922e55a..9fe7cb6e6 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala @@ -101,7 +101,7 @@ trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActi case (key: String, value: AnyRef) => (key, value) } result(allCraftables - .collect{ case aeCraftItem if matches(convert(aeCraftItem), filter) => new NetworkControl.Craftable(tile, aeCraftItem) } + .collect{ case aeCraftItem if filter.isEmpty || matches(convert(aeCraftItem), filter) => new NetworkControl.Craftable(tile, aeCraftItem) } .toArray) } diff --git a/src/main/scala/li/cil/oc/server/PacketSender.scala b/src/main/scala/li/cil/oc/server/PacketSender.scala index e86ca626a..1d9279ffe 100644 --- a/src/main/scala/li/cil/oc/server/PacketSender.scala +++ b/src/main/scala/li/cil/oc/server/PacketSender.scala @@ -260,8 +260,10 @@ object PacketSender { val x = (xz >> 8).toByte val z = xz.toByte pb.writeShort(xz) - pb.writeInt(t.volume(x + z * t.width)) - pb.writeInt(t.volume(x + z * t.width + t.width * t.width)) + val rangeStart: Int = x + z * t.width + val rangeFinal: Int = x + z * t.width + t.width * t.width + pb.writeInt(t.volume(rangeStart max 0 min t.volume.length - 1)) + pb.writeInt(t.volume(rangeFinal max 0 min t.volume.length - 1)) } pb.sendToPlayersNearTileEntity(t) diff --git a/src/main/scala/li/cil/oc/server/agent/Player.scala b/src/main/scala/li/cil/oc/server/agent/Player.scala index 100760bc0..796d50597 100644 --- a/src/main/scala/li/cil/oc/server/agent/Player.scala +++ b/src/main/scala/li/cil/oc/server/agent/Player.scala @@ -187,11 +187,11 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc private def collectDroppedItems(itemsBefore: Iterable[EntityItem]) { val itemsAfter = adjacentItems val itemsDropped = itemsAfter -- itemsBefore - for (drop <- itemsDropped) { - - drop.delayBeforeCanPickup = 0 - drop.onCollideWithPlayer(this) - drop.setDead() + if (itemsDropped.nonEmpty) { + for (drop <- itemsDropped) { + drop.delayBeforeCanPickup = 0 + drop.onCollideWithPlayer(this) + } } } diff --git a/src/main/scala/li/cil/oc/server/component/Agent.scala b/src/main/scala/li/cil/oc/server/component/Agent.scala index 88be38d19..658fb27bd 100644 --- a/src/main/scala/li/cil/oc/server/component/Agent.scala +++ b/src/main/scala/li/cil/oc/server/component/Agent.scala @@ -288,11 +288,20 @@ trait Agent extends traits.WorldControl with traits.InventoryControl with traits entity.captureDrops = true } + protected def endConsumeDrops(player: Player, entity: Entity) { entity.captureDrops = false - for (drop <- entity.capturedDrops) { - val stack = drop.getEntityItem - InventoryUtils.addToPlayerInventory(stack, player) + // this inventory size check is a HACK to preserve old behavior that a agent can suck items out + // of the capturedDrops. Ideally, we'd only pick up items off the ground. We could clear the + // capturedDrops when Player.attackTargetEntityWithCurrentItem() is called + // But this felt slightly less hacky, slightly + if (player.inventory.getSizeInventory > 0) { + for (drop <- entity.capturedDrops) { + if (!drop.isDead) { + val stack = drop.getEntityItem + InventoryUtils.addToPlayerInventory(stack, player, spawnInWorld = false) + } + } } entity.capturedDrops.clear() } 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 e5e58b45b..fb1a1e97b 100644 --- a/src/main/scala/li/cil/oc/server/component/DebugCard.scala +++ b/src/main/scala/li/cil/oc/server/component/DebugCard.scala @@ -382,7 +382,7 @@ object DebugCard { def setGameType(context: Context, args: Arguments): Array[AnyRef] = withPlayer(player => { val gametype = args.checkString(0) - player.setGameType(GameType.values.find(_.name == gametype).getOrElse(GameType.SURVIVAL)) + player.setGameType(GameType.values.find(_.getName == gametype).getOrElse(GameType.SURVIVAL)) null }) diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeNavigation.scala b/src/main/scala/li/cil/oc/server/component/UpgradeNavigation.scala index 41b62a985..6c982acfb 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeNavigation.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeNavigation.scala @@ -83,7 +83,8 @@ class UpgradeNavigation(val host: EnvironmentHost with Rotatable) extends prefab Map( "position" -> Array(delta.xCoord, delta.yCoord, delta.zCoord), "redstone" -> waypoint.maxInput, - "label" -> waypoint.label + "label" -> waypoint.label, + "address" -> waypoint.node.address() ) }).toArray) } diff --git a/src/main/scala/li/cil/oc/server/component/WirelessNetworkCard.scala b/src/main/scala/li/cil/oc/server/component/WirelessNetworkCard.scala index 587dd1f7e..d2ba1747a 100644 --- a/src/main/scala/li/cil/oc/server/component/WirelessNetworkCard.scala +++ b/src/main/scala/li/cil/oc/server/component/WirelessNetworkCard.scala @@ -158,10 +158,14 @@ object WirelessNetworkCard { override def getDeviceInfo: util.Map[String, String] = deviceInfo override protected def isPacketAccepted(packet: Packet, distance: Double): Boolean = { - (shouldSendWiredTraffic || distance == 0) && super.isPacketAccepted(packet, distance) + if (distance <= maxWirelessRange && (distance > 0 || shouldSendWiredTraffic)) { + super.isPacketAccepted(packet, distance) + } else { + false + } } } - + class Tier2(host: EnvironmentHost) extends Tier1(host) { override protected def wirelessCostPerRange: Double = Settings.get.wirelessCostPerRange(Tier.Two) diff --git a/src/main/scala/li/cil/oc/server/machine/luac/LuaStateFactory.scala b/src/main/scala/li/cil/oc/server/machine/luac/LuaStateFactory.scala index 6789e7461..9cf0302a6 100644 --- a/src/main/scala/li/cil/oc/server/machine/luac/LuaStateFactory.scala +++ b/src/main/scala/li/cil/oc/server/machine/luac/LuaStateFactory.scala @@ -22,24 +22,22 @@ import org.apache.commons.lang3.SystemUtils import scala.util.Random object LuaStateFactory { - def isAvailable = { + def isAvailable: Boolean = { // Force initialization of both. val lua52 = Lua52.isAvailable val lua53 = Lua53.isAvailable lua52 || lua53 } - def include52 = { - Lua52.isAvailable && !Settings.get.forceLuaJ - } + def luajRequested: Boolean = Settings.get.forceLuaJ || Settings.get.registerLuaJArchitecture - def include53 = { - Lua53.isAvailable && Settings.get.enableLua53 - } + def includeLuaJ: Boolean = !isAvailable || luajRequested - def default53 = { - include53 && Settings.get.defaultLua53 - } + def include52: Boolean = Lua52.isAvailable && !Settings.get.forceLuaJ + + def include53: Boolean = Lua53.isAvailable && Settings.get.enableLua53 && !Settings.get.forceLuaJ + + def default53: Boolean = include53 && Settings.get.defaultLua53 def setDefaultArch(stack: ItemStack): ItemStack = { if (default53) { diff --git a/src/main/scala/li/cil/oc/util/FluidUtils.scala b/src/main/scala/li/cil/oc/util/FluidUtils.scala index 91cc8a755..38de45045 100644 --- a/src/main/scala/li/cil/oc/util/FluidUtils.scala +++ b/src/main/scala/li/cil/oc/util/FluidUtils.scala @@ -156,7 +156,7 @@ object FluidUtils { override def canFill(from: ForgeDirection, fluid: Fluid): Boolean = fluid.canBePlacedInWorld override def fill(from: ForgeDirection, resource: FluidStack, doFill: Boolean): Int = { - if (resource != null && resource.getFluid.canBePlacedInWorld && resource.getFluid.getBlock != null) { + if (resource != null && resource.getFluid.canBePlacedInWorld && resource.getFluid.getBlock != null && resource.amount >= 1000) { if (doFill) { val world = position.world.get if (!world.isAirBlock(position) && !world.isAnyLiquid(position.bounds)) diff --git a/src/main/scala/li/cil/oc/util/InventoryUtils.scala b/src/main/scala/li/cil/oc/util/InventoryUtils.scala index 6089f221e..fd1c2d9b3 100644 --- a/src/main/scala/li/cil/oc/util/InventoryUtils.scala +++ b/src/main/scala/li/cil/oc/util/InventoryUtils.scala @@ -369,7 +369,7 @@ object InventoryUtils { /** * Try inserting an item stack into a player inventory. If that fails, drop it into the world. */ - def addToPlayerInventory(stack: ItemStack, player: EntityPlayer): Unit = { + def addToPlayerInventory(stack: ItemStack, player: EntityPlayer, spawnInWorld: Boolean = true): Unit = { if (stack != null) { if (player.inventory.addItemStackToInventory(stack)) { player.inventory.markDirty() @@ -377,7 +377,7 @@ object InventoryUtils { player.openContainer.detectAndSendChanges() } } - if (stack.stackSize > 0) { + if (stack.stackSize > 0 && spawnInWorld) { player.dropPlayerItemWithRandomChoice(stack, false) } }