Compare commits
1 Commits
v1.12.2-1.
...
feature/ne
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6ac1c0e944 |
5
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -6,10 +6,11 @@ about: Report some misbehaviour in the mod
|
|||||||
|
|
||||||
<!--
|
<!--
|
||||||
## Before reporting
|
## Before reporting
|
||||||
- Search for the bug on the issue tracker. Make sure to look at closed issues too!
|
- Search for the bug both here and [on the ComputerCraft issues page](https://github.com/dan200/ComputerCraft/issues?utf8=%E2%9C%93&q=is%3Aissue+)
|
||||||
|
- If possible, try to reproduce on vanilla ComputerCraft. If it still occurs, [report on the ComputerCraft repo](https://github.com/dan200/ComputerCraft/issues/new) instead.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
## Useful information to include:
|
## Useful information to include:
|
||||||
- Minecraft version
|
- Minecraft version
|
||||||
- CC: Tweaked version
|
- CC: Tweaked version
|
||||||
- Detailed reproduction steps: sometimes I can spot a bug pretty easily, but often it's much more obscure. The more information I have to help reproduce it, the quicker it'll get fixed.
|
- Detailed reproduction steps!** Sometimes I can spot a bug pretty easily, but often it's much more obscure. Anything you can give which will help reproduce it means it'll get fixed quicker.
|
||||||
|
7
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -6,9 +6,10 @@ about: Suggest an idea or improvement
|
|||||||
|
|
||||||
<!--
|
<!--
|
||||||
## Before reporting
|
## Before reporting
|
||||||
- Search for the suggestion here. It's possible someone's suggested it before!
|
- Search for the suggestion both here and [on the ComputerCraft issues page](https://github.com/dan200/ComputerCraft/issues?utf8=%E2%9C%93&q=is%3Aissue+). It's possible someone's suggested it before!
|
||||||
|
- Unless something is specific to CC:Tweaked, try to [suggest them on the ComputerCraft repo](https://github.com/dan200/ComputerCraft/issues/new). There's a lot more people watching it, so it allows the wider community to contribute.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
## Useful information to include:
|
## Useful information to include:
|
||||||
- Explanation of how the feature/change should work.
|
- Explanation of how the feature/change chould work.
|
||||||
- Some rationale/use case for a feature. I'd like to keep CC:T as minimal as possible, so I like have a solid justification for each feature.
|
- Some rationale/use case for a feature. I'd like to keep CC:T as minimal
|
||||||
|
9
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<!--
|
||||||
|
Unless this feature is specific to CC:Tweaked, try to [target the original ComputerCraft repo](https://github.com/dan200/ComputerCraft/) instead. There's a lot more people watching it, so it allows the wider community to contribute.
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Useful information to include:
|
||||||
|
- Brief explanation of the changes you've made.
|
||||||
|
- Rationale of why this change has been made/reasoning behind it.
|
||||||
|
|
||||||
|
The more information you can provide, the easier it is to review something now _and_ to see why a change was made, when the code needs updating in the future.
|
19
LICENSE-luaj
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2007 LuaJ. All rights reserved.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
50
README.md
@@ -1,35 +1,35 @@
|
|||||||
# 
|
# 
|
||||||
[](https://travis-ci.org/SquidDev-CC/CC-Tweaked)
|
[](https://travis-ci.org/SquidDev-CC/CC-Tweaked)
|
||||||
|
|
||||||
CC: Tweaked is a fork of [ComputerCraft](https://github.com/dan200/ComputerCraft), adding programmable computers,
|
CC: Tweaked is a fork of ComputerCraft which aims to provide earlier access to the more experimental and in-development
|
||||||
turtles and more to Minecraft.
|
features of the mod. For a more stable experience, I recommend checking out the
|
||||||
|
[original mod](https://github.com/dan200/ComputerCraft).
|
||||||
|
|
||||||
## What?
|
## What?
|
||||||
ComputerCraft has always held a fond place in my heart: it's the mod which really got me into Minecraft, and it's the
|
CC: Tweaked (or CC:T for short) does not aim to create a competing fork of ComputerCraft, nor am I planning to take it
|
||||||
mod which has kept me playing it for many years. However, development of the original mod has slowed, as the original
|
in in a vastly different direction to the original mod. In fact, CC:T aims to be a nurturing ground for various
|
||||||
developers have had less time to work on the mod, and moved onto other projects and commitments.
|
features, with a pull request against the original mod being the end goal.
|
||||||
|
|
||||||
CC:Tweaked (or CC:T for short) is an attempt to continue ComputerCraft's legacy. It's not intended to be a competitor
|
CC:T also includes many pull requests from the community which have not yet been merged, offering a large number
|
||||||
to CC, nor do I want to take it in a vastly different direction to the original mod. Instead, CC:T focuses on making the
|
of additional bug fixes and features over the original mod.
|
||||||
ComputerCraft experience as _solid_ as possible, ironing out any wrinkles that may have developed over time.
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
CC: Tweaked contains all the features of the latest version of ComputerCraft, as well as numerous fixes, performance
|
CC: Tweaked contains all the features of the latest alpha, as well as numerous fixes, performance improvements and
|
||||||
improvements and several nifty additions. I'd recommend checking out [the releases page](https://github.com/SquidDev-CC/CC-Tweaked/releases)
|
several additional features. I'd recommend checking out [the releases page](https://github.com/SquidDev-CC/CC-Tweaked/releases)
|
||||||
to see the full set of changes, but here's a couple of the more interesting additions:
|
to see the full changes, but here's a couple of the more interesting changes:
|
||||||
|
|
||||||
- Improvements to the `http` library, including websockets, support for other HTTP methods (`PUT`, `DELETE`, etc...)
|
- Replace LuaJ with Cobalt.
|
||||||
and configurable limits on HTTP usage.
|
- Allow running multiple computers at the same time.
|
||||||
- Full-block wired modems, allowing one to wrap non-solid peripherals (such as turtles, or chests if Plethora is
|
- Websocket support in the HTTP library.
|
||||||
installed).
|
- Wired modems and cables act more like multiparts.
|
||||||
- Pocket computers can be held like maps, allowing you to view the screen without entering a GUI.
|
- Add map-like rendering for pocket computers and printed pages/books.
|
||||||
- Printed pages and books can be placed in item frames and held like maps.
|
- Adds the `/computercraft` command, offering various diagnostic tools for server owners. This allows operators to
|
||||||
- Several profiling and administration tools for server owners, via the `/computercraft` command. This allows operators
|
track which computers are hogging resources, turn on and shutdown multiple computers at once and interact with
|
||||||
to track which computers are hogging resources, turn on and shutdown multiple computers at once and interact with
|
|
||||||
computers remotely.
|
computers remotely.
|
||||||
- Closer emulation of standard Lua, adding the `debug` and `io` libraries. This also enables seeking within binary
|
- Add full-block wired modems, allowing one to wrap non-solid peripherals (such as turtles, or chests if Plethora is
|
||||||
files, meaning you don't need to read large files into memory.
|
installed).
|
||||||
- Allow running multiple computers on multiple threads, reducing latency on worlds with many computers.
|
- Extended binary file handles. They support file seeking, and reading new lines, allowing full (and accurate)
|
||||||
|
emulation of the standard Lua `io` library.
|
||||||
|
|
||||||
## Relation to CCTweaks?
|
## Relation to CCTweaks?
|
||||||
This mod has nothing to do with CCTweaks, though there is no denying the name is a throwback to it. That being said,
|
This mod has nothing to do with CCTweaks, though there is no denying the name is a throwback to it. That being said,
|
||||||
@@ -37,8 +37,10 @@ several features have been included, such as full block modems, the Cobalt runti
|
|||||||
computers.
|
computers.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
Any contribution is welcome, be that using the mod, reporting bugs or contributing code. In order to start helping
|
Any contribution is welcome, be that using the mod, reporting bugs or contributing code. If you do wish to contribute
|
||||||
develop CC:T, you'll need to follow these steps:
|
code, do consider submitting it to the ComputerCraft repository first.
|
||||||
|
|
||||||
|
That being said, in order to start helping develop CC:T, you'll need to follow these steps:
|
||||||
|
|
||||||
- **Clone the repository:** `git clone https://github.com/SquidDev-CC/CC-Tweaked.git && cd CC-Tweaked`
|
- **Clone the repository:** `git clone https://github.com/SquidDev-CC/CC-Tweaked.git && cd CC-Tweaked`
|
||||||
- **Setup Forge:** `./gradlew setupDecompWorkspace`
|
- **Setup Forge:** `./gradlew setupDecompWorkspace`
|
||||||
|
120
build.gradle
@@ -9,9 +9,7 @@ buildscript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.google.code.gson:gson:2.8.1'
|
|
||||||
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
|
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
|
||||||
classpath 'net.sf.proguard:proguard-gradle:6.1.0beta1'
|
|
||||||
classpath 'org.ajoberstar.grgit:grgit-gradle:3.0.0'
|
classpath 'org.ajoberstar.grgit:grgit-gradle:3.0.0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,17 +23,14 @@ apply plugin: 'org.ajoberstar.grgit'
|
|||||||
apply plugin: 'maven-publish'
|
apply plugin: 'maven-publish'
|
||||||
apply plugin: 'maven'
|
apply plugin: 'maven'
|
||||||
|
|
||||||
def mc_version = "1.12.2"
|
version = "1.80pr1.14"
|
||||||
def main_version = "1.81.1"
|
|
||||||
version = "${mc_version}-${main_version}"
|
|
||||||
|
|
||||||
group = "org.squiddev"
|
group = "org.squiddev"
|
||||||
archivesBaseName = "cc-tweaked"
|
archivesBaseName = "cc-tweaked"
|
||||||
|
|
||||||
minecraft {
|
minecraft {
|
||||||
version = "${mc_version}-14.23.4.2749"
|
version = "1.12.2-14.23.4.2749"
|
||||||
runDir = "run"
|
runDir = "run"
|
||||||
replace '${version}', main_version
|
replace '${version}', project.version
|
||||||
|
|
||||||
// the mappings can be changed at any time, and must be in the following format.
|
// the mappings can be changed at any time, and must be in the following format.
|
||||||
// snapshot_YYYYMMDD snapshot are built nightly.
|
// snapshot_YYYYMMDD snapshot are built nightly.
|
||||||
@@ -89,68 +84,20 @@ jar {
|
|||||||
attributes('FMLAT': 'computercraft_at.cfg')
|
attributes('FMLAT': 'computercraft_at.cfg')
|
||||||
}
|
}
|
||||||
|
|
||||||
from (sourceSets.main.allSource) {
|
into("docs", { from (javadoc.destinationDir) })
|
||||||
|
|
||||||
|
into("api", { from (sourceSets.main.allSource) {
|
||||||
include "dan200/computercraft/api/**/*.java"
|
include "dan200/computercraft/api/**/*.java"
|
||||||
}
|
}})
|
||||||
|
|
||||||
from configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }
|
from configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets
|
|
||||||
import java.nio.file.*
|
|
||||||
import java.util.zip.*
|
|
||||||
|
|
||||||
import com.google.gson.GsonBuilder
|
|
||||||
import com.google.gson.JsonElement
|
|
||||||
import org.ajoberstar.grgit.Grgit
|
import org.ajoberstar.grgit.Grgit
|
||||||
import proguard.gradle.ProGuardTask
|
|
||||||
|
|
||||||
task proguard(type: ProGuardTask, dependsOn: jar) {
|
|
||||||
description "Removes unused shadowed classes from the jar"
|
|
||||||
group "compact"
|
|
||||||
|
|
||||||
injars jar.archivePath
|
|
||||||
outjars "${jar.archivePath.absolutePath.replace(".jar", "")}-min.jar"
|
|
||||||
|
|
||||||
// Add the main runtime jar and all non-shadowed dependencies
|
|
||||||
libraryjars "${System.getProperty('java.home')}/lib/rt.jar"
|
|
||||||
doFirst {
|
|
||||||
sourceSets.main.compileClasspath
|
|
||||||
.filter { !it.name.contains("Cobalt") }
|
|
||||||
.each { libraryjars it }
|
|
||||||
}
|
|
||||||
|
|
||||||
// We want to avoid as much obfuscation as possible. We're only doing this to shrink code size.
|
|
||||||
dontobfuscate; dontoptimize; keepattributes; keepparameternames
|
|
||||||
|
|
||||||
// Proguard will remove directories by default, but that breaks JarMount.
|
|
||||||
keepdirectories 'assets/computercraft/lua**'
|
|
||||||
|
|
||||||
// Preserve ComputerCraft classes - we only want to strip shadowed files.
|
|
||||||
keep 'class dan200.computercraft.** { *; }'
|
|
||||||
|
|
||||||
// Preserve the constructors in Cobalt library class, as we init them via reflection
|
|
||||||
keepclassmembers 'class org.squiddev.cobalt.lib.** { <init>(...); }'
|
|
||||||
}
|
|
||||||
|
|
||||||
task proguardMove(dependsOn: proguard) {
|
|
||||||
description "Replace the original jar with the minified version"
|
|
||||||
group "compact"
|
|
||||||
|
|
||||||
doLast {
|
|
||||||
Files.move(
|
|
||||||
file("${jar.archivePath.absolutePath.replace(".jar", "")}-min.jar").toPath(),
|
|
||||||
file(jar.archivePath).toPath(),
|
|
||||||
StandardCopyOption.REPLACE_EXISTING
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reobfJar.dependsOn proguardMove
|
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
inputs.property "version", main_version
|
inputs.property "version", project.version
|
||||||
inputs.property "mcversion", mc_version
|
inputs.property "mcversion", project.minecraft.version
|
||||||
|
|
||||||
def hash = 'none'
|
def hash = 'none'
|
||||||
Set<String> contributors = []
|
Set<String> contributors = []
|
||||||
@@ -171,9 +118,9 @@ processResources {
|
|||||||
include 'mcmod.info'
|
include 'mcmod.info'
|
||||||
include 'assets/computercraft/lua/rom/help/credits.txt'
|
include 'assets/computercraft/lua/rom/help/credits.txt'
|
||||||
|
|
||||||
expand 'version': main_version,
|
expand 'version':project.version,
|
||||||
'mcversion': mc_version,
|
'mcversion':project.minecraft.version,
|
||||||
'gitcontributors': contributors.sort(false, String.CASE_INSENSITIVE_ORDER).join('\n')
|
'gitcontributors':contributors.sort(false, String.CASE_INSENSITIVE_ORDER).join('\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
from(sourceSets.main.resources.srcDirs) {
|
from(sourceSets.main.resources.srcDirs) {
|
||||||
@@ -182,53 +129,12 @@ processResources {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task compressJson(dependsOn: extractAnnotationsJar) {
|
|
||||||
group "compact"
|
|
||||||
description "Minifies all JSON files, stripping whitespace"
|
|
||||||
|
|
||||||
def jarPath = file(jar.archivePath)
|
|
||||||
|
|
||||||
def tempPath = File.createTempFile("input", ".jar", temporaryDir)
|
|
||||||
tempPath.deleteOnExit()
|
|
||||||
|
|
||||||
def gson = new GsonBuilder().create()
|
|
||||||
|
|
||||||
doLast {
|
|
||||||
// Copy over all files in the current jar to the new one, running json files from GSON. As pretty printing
|
|
||||||
// is turned off, they should be minified.
|
|
||||||
new ZipFile(jarPath).withCloseable { inJar ->
|
|
||||||
new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(tempPath))).withCloseable { outJar ->
|
|
||||||
inJar.entries().each { entry ->
|
|
||||||
if(entry.directory) {
|
|
||||||
outJar.putNextEntry(entry)
|
|
||||||
} else if(!entry.name.endsWith(".json")) {
|
|
||||||
outJar.putNextEntry(entry)
|
|
||||||
inJar.getInputStream(entry).withCloseable { outJar << it }
|
|
||||||
} else {
|
|
||||||
ZipEntry newEntry = new ZipEntry(entry.name)
|
|
||||||
newEntry.setTime(entry.time)
|
|
||||||
outJar.putNextEntry(newEntry)
|
|
||||||
|
|
||||||
def element = inJar.getInputStream(entry).withCloseable { gson.fromJson(it.newReader("UTF8"), JsonElement.class) }
|
|
||||||
outJar.write(gson.toJson(element).getBytes(StandardCharsets.UTF_8))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// And replace the original jar again
|
|
||||||
Files.move(tempPath.toPath(), jarPath.toPath(), StandardCopyOption.REPLACE_EXISTING)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assemble.dependsOn compressJson
|
|
||||||
|
|
||||||
curseforge {
|
curseforge {
|
||||||
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
|
apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : ''
|
||||||
project {
|
project {
|
||||||
id = '282001'
|
id = '282001'
|
||||||
releaseType = 'release'
|
releaseType = 'beta'
|
||||||
changelog = "Release notes can be found on the GitHub repository (https://github.com/SquidDev-CC/CC-Tweaked/releases/tag/v${project.version})."
|
changelog = "Release notes can be found on the GitHub repository (https://github.com/SquidDev-CC/CC-Tweaked/releases/tag/v${project.version})."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -13,14 +13,12 @@ import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
|||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.FontRenderer;
|
import net.minecraft.client.gui.FontRenderer;
|
||||||
import net.minecraft.client.gui.GuiNewChat;
|
import net.minecraft.client.gui.GuiNewChat;
|
||||||
import net.minecraft.client.gui.GuiUtilRenderComponents;
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
import net.minecraft.util.text.TextFormatting;
|
import net.minecraft.util.text.TextFormatting;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ClientTableFormatter implements TableFormatter
|
public class ClientTableFormatter implements TableFormatter
|
||||||
{
|
{
|
||||||
@@ -64,13 +62,7 @@ public class ClientTableFormatter implements TableFormatter
|
|||||||
@Override
|
@Override
|
||||||
public void writeLine( int id, ITextComponent component )
|
public void writeLine( int id, ITextComponent component )
|
||||||
{
|
{
|
||||||
Minecraft mc = Minecraft.getMinecraft();
|
Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessageWithOptionalDeletion( component, id );
|
||||||
GuiNewChat chat = mc.ingameGUI.getChatGUI();
|
|
||||||
|
|
||||||
// Trim the text if it goes over the allowed length
|
|
||||||
int maxWidth = MathHelper.floor( chat.getChatWidth() / chat.getChatScale() );
|
|
||||||
List<ITextComponent> list = GuiUtilRenderComponents.splitText( component, maxWidth, mc.fontRenderer, false, false );
|
|
||||||
if( !list.isEmpty() ) chat.printChatMessageWithOptionalDeletion( list.get( 0 ), id );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -0,0 +1,188 @@
|
|||||||
|
package dan200.computercraft.client.render;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import dan200.computercraft.api.network.wired.IWiredElement;
|
||||||
|
import dan200.computercraft.shared.wired.WiredNetwork;
|
||||||
|
import dan200.computercraft.shared.wired.WiredNode;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.FontRenderer;
|
||||||
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
|
import net.minecraft.client.renderer.Tessellator;
|
||||||
|
import net.minecraft.client.renderer.entity.RenderManager;
|
||||||
|
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||||
|
import net.minecraft.init.Items;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.client.event.RenderWorldLastEvent;
|
||||||
|
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a helper to render a network when testing.
|
||||||
|
*/
|
||||||
|
public final class RenderOverlayNetwork
|
||||||
|
{
|
||||||
|
private int ticksInGame;
|
||||||
|
private IWiredElement element;
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public void onWorldRenderLast( RenderWorldLastEvent event )
|
||||||
|
{
|
||||||
|
++ticksInGame;
|
||||||
|
|
||||||
|
RayTraceResult result = Minecraft.getMinecraft().objectMouseOver;
|
||||||
|
if( result != null && result.typeOfHit == RayTraceResult.Type.BLOCK )
|
||||||
|
{
|
||||||
|
World clientWorld = Minecraft.getMinecraft().world;
|
||||||
|
World world = FMLCommonHandler.instance().getMinecraftServerInstance().getWorld( clientWorld.provider.getDimension() );
|
||||||
|
|
||||||
|
IWiredElement newElement = ComputerCraft.getWiredElementAt( world, result.getBlockPos(), result.sideHit );
|
||||||
|
if( newElement != null ) element = newElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( element == null ) return;
|
||||||
|
|
||||||
|
Minecraft minecraft = Minecraft.getMinecraft();
|
||||||
|
ItemStack stack = minecraft.player.getHeldItemMainhand();
|
||||||
|
ItemStack otherStack = minecraft.player.getHeldItemOffhand();
|
||||||
|
|
||||||
|
if( stack.getItem() != Items.STICK && otherStack.getItem() != Items.STICK ) return;
|
||||||
|
|
||||||
|
GlStateManager.pushMatrix();
|
||||||
|
RenderManager renderManager = minecraft.getRenderManager();
|
||||||
|
GlStateManager.translate( -renderManager.viewerPosX, -renderManager.viewerPosY, -renderManager.viewerPosZ );
|
||||||
|
|
||||||
|
GlStateManager.disableDepth();
|
||||||
|
GlStateManager.disableTexture2D();
|
||||||
|
GlStateManager.enableBlend();
|
||||||
|
GlStateManager.blendFunc( GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA );
|
||||||
|
|
||||||
|
Set<Pair<IWiredElement>> connections = Sets.newHashSet();
|
||||||
|
WiredNetwork network = (WiredNetwork) element.getNode().getNetwork();
|
||||||
|
|
||||||
|
for( WiredNode node : network.getNodes() )
|
||||||
|
{
|
||||||
|
for( WiredNode other : node.getNeighbours() )
|
||||||
|
{
|
||||||
|
connections.add( new Pair<>( node.getElement(), other.getElement() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderNetworkConnections( connections, new Color( Color.HSBtoRGB( ticksInGame % 200 / 200F, 0.6F, 1F ) ), 1f );
|
||||||
|
|
||||||
|
GlStateManager.enableDepth();
|
||||||
|
GlStateManager.enableTexture2D();
|
||||||
|
GlStateManager.disableBlend();
|
||||||
|
GlStateManager.popMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderNetworkConnections( Collection<Pair<IWiredElement>> data, Color color, float thickness )
|
||||||
|
{
|
||||||
|
renderConnections( data, color, 1.0f, thickness );
|
||||||
|
renderConnections( data, color, 64.0f / 255.0f, thickness * 3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderConnections( Collection<Pair<IWiredElement>> connections, Color color, float alpha, float thickness )
|
||||||
|
{
|
||||||
|
Tessellator tessellator = Tessellator.getInstance();
|
||||||
|
BufferBuilder renderer = tessellator.getBuffer();
|
||||||
|
|
||||||
|
GlStateManager.pushMatrix();
|
||||||
|
GlStateManager.scale( 1, 1, 1 );
|
||||||
|
|
||||||
|
GlStateManager.color( color.getRed() / 255.0f, color.getGreen() / 255.0f, color.getBlue() / 255.0f, alpha );
|
||||||
|
GL11.glLineWidth( thickness );
|
||||||
|
|
||||||
|
renderer.begin( GL11.GL_LINES, DefaultVertexFormats.POSITION );
|
||||||
|
for( Pair<IWiredElement> connection : connections )
|
||||||
|
{
|
||||||
|
Vec3d a = connection.x.getPosition(), b = connection.y.getPosition();
|
||||||
|
|
||||||
|
renderer.pos( a.x, a.y, a.z ).endVertex();
|
||||||
|
renderer.pos( b.x, b.y, b.z ).endVertex();
|
||||||
|
}
|
||||||
|
|
||||||
|
tessellator.draw();
|
||||||
|
|
||||||
|
GlStateManager.popMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderLabel( double x, double y, double z, String label )
|
||||||
|
{
|
||||||
|
RenderManager renderManager = Minecraft.getMinecraft().getRenderManager();
|
||||||
|
FontRenderer fontrenderer = renderManager.getFontRenderer();
|
||||||
|
if( fontrenderer == null ) return;
|
||||||
|
|
||||||
|
GlStateManager.pushMatrix();
|
||||||
|
GlStateManager.disableLighting();
|
||||||
|
|
||||||
|
float scale = 0.02666667f;
|
||||||
|
GlStateManager.translate( x, y, z );
|
||||||
|
GlStateManager.rotate( -renderManager.playerViewY, 0, 1, 0 );
|
||||||
|
GlStateManager.rotate( renderManager.playerViewX, 1, 0, 0 );
|
||||||
|
GlStateManager.scale( -scale, -scale, scale );
|
||||||
|
|
||||||
|
// Render label background
|
||||||
|
Tessellator tessellator = Tessellator.getInstance();
|
||||||
|
BufferBuilder renderer = tessellator.getBuffer();
|
||||||
|
|
||||||
|
int width = fontrenderer.getStringWidth( label );
|
||||||
|
int xOffset = width / 2;
|
||||||
|
|
||||||
|
GlStateManager.disableTexture2D();
|
||||||
|
GlStateManager.color( 0, 0, 0, 65 / 225.0f );
|
||||||
|
|
||||||
|
renderer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION );
|
||||||
|
renderer.pos( -xOffset - 1, -1, 0 ).endVertex();
|
||||||
|
renderer.pos( -xOffset - 1, 8, 0 ).endVertex();
|
||||||
|
renderer.pos( xOffset + 1, 8, 0 ).endVertex();
|
||||||
|
renderer.pos( xOffset + 1, -1, 0 ).endVertex();
|
||||||
|
|
||||||
|
tessellator.draw();
|
||||||
|
GlStateManager.enableTexture2D();
|
||||||
|
|
||||||
|
// Render label
|
||||||
|
fontrenderer.drawString( label, -width / 2, 0, 0xFFFFFFFF );
|
||||||
|
|
||||||
|
GlStateManager.enableLighting();
|
||||||
|
GlStateManager.popMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Pair<T>
|
||||||
|
{
|
||||||
|
public final T x;
|
||||||
|
public final T y;
|
||||||
|
|
||||||
|
public Pair( T right, T y )
|
||||||
|
{
|
||||||
|
this.x = right;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals( Object o )
|
||||||
|
{
|
||||||
|
if( this == o ) return true;
|
||||||
|
if( o == null || getClass() != o.getClass() ) return false;
|
||||||
|
|
||||||
|
Pair<?> p = (Pair<?>) o;
|
||||||
|
return (x.equals( p.x ) && y.equals( p.y ))
|
||||||
|
|| (x.equals( p.y ) && y.equals( p.x ));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return x.hashCode() ^ y.hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -40,7 +40,7 @@ import java.util.List;
|
|||||||
public class TileEntityTurtleRenderer extends TileEntitySpecialRenderer<TileTurtle>
|
public class TileEntityTurtleRenderer extends TileEntitySpecialRenderer<TileTurtle>
|
||||||
{
|
{
|
||||||
private static final ModelResourceLocation NORMAL_TURTLE_MODEL = new ModelResourceLocation( "computercraft:turtle", "inventory" );
|
private static final ModelResourceLocation NORMAL_TURTLE_MODEL = new ModelResourceLocation( "computercraft:turtle", "inventory" );
|
||||||
private static final ModelResourceLocation ADVANCED_TURTLE_MODEL = new ModelResourceLocation( "computercraft:turtle_advanced", "inventory" );
|
private static final ModelResourceLocation ADVANCED_TURTLE_MODEL = new ModelResourceLocation( "computercraft:advanced_turtle", "inventory" );
|
||||||
private static final ModelResourceLocation COLOUR_TURTLE_MODEL = new ModelResourceLocation( "computercraft:turtle_white", "inventory" );
|
private static final ModelResourceLocation COLOUR_TURTLE_MODEL = new ModelResourceLocation( "computercraft:turtle_white", "inventory" );
|
||||||
private static final ModelResourceLocation ELF_OVERLAY_MODEL = new ModelResourceLocation( "computercraft:turtle_elf_overlay", "inventory" );
|
private static final ModelResourceLocation ELF_OVERLAY_MODEL = new ModelResourceLocation( "computercraft:turtle_elf_overlay", "inventory" );
|
||||||
|
|
||||||
|
@@ -14,32 +14,20 @@ import dan200.computercraft.core.filesystem.FileSystem;
|
|||||||
import dan200.computercraft.core.terminal.Terminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
import dan200.computercraft.core.tracking.TrackingField;
|
import dan200.computercraft.core.tracking.TrackingField;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
public interface IAPIEnvironment extends IComputerOwned
|
public interface IAPIEnvironment extends IComputerOwned
|
||||||
{
|
{
|
||||||
String[] SIDE_NAMES = new String[] {
|
|
||||||
"bottom", "top", "back", "front", "right", "left",
|
|
||||||
};
|
|
||||||
|
|
||||||
int SIDE_COUNT = 6;
|
|
||||||
|
|
||||||
interface IPeripheralChangeListener
|
interface IPeripheralChangeListener
|
||||||
{
|
{
|
||||||
void onPeripheralChanged( int side, @Nullable IPeripheral newPeripheral );
|
void onPeripheralChanged( int side, IPeripheral newPeripheral );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
@Override
|
||||||
Computer getComputer();
|
Computer getComputer();
|
||||||
|
|
||||||
int getComputerID();
|
int getComputerID();
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
IComputerEnvironment getComputerEnvironment();
|
IComputerEnvironment getComputerEnvironment();
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
Terminal getTerminal();
|
Terminal getTerminal();
|
||||||
|
|
||||||
FileSystem getFileSystem();
|
FileSystem getFileSystem();
|
||||||
@@ -62,18 +50,17 @@ public interface IAPIEnvironment extends IComputerOwned
|
|||||||
|
|
||||||
int getBundledInput( int side );
|
int getBundledInput( int side );
|
||||||
|
|
||||||
void setPeripheralChangeListener( @Nullable IPeripheralChangeListener listener );
|
void setPeripheralChangeListener( IPeripheralChangeListener listener );
|
||||||
|
|
||||||
@Nullable
|
|
||||||
IPeripheral getPeripheral( int side );
|
IPeripheral getPeripheral( int side );
|
||||||
|
|
||||||
String getLabel();
|
String getLabel();
|
||||||
|
|
||||||
void setLabel( @Nullable String label );
|
void setLabel( String label );
|
||||||
|
|
||||||
void addTrackingChange( @Nonnull TrackingField field, long change );
|
void addTrackingChange( TrackingField field, long change );
|
||||||
|
|
||||||
default void addTrackingChange( @Nonnull TrackingField field )
|
default void addTrackingChange( TrackingField field )
|
||||||
{
|
{
|
||||||
addTrackingChange( field, 1 );
|
addTrackingChange( field, 1 );
|
||||||
}
|
}
|
||||||
|
@@ -278,13 +278,13 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
|||||||
}, null );
|
}, null );
|
||||||
|
|
||||||
// Queue a detachment event
|
// Queue a detachment event
|
||||||
m_environment.queueEvent( "peripheral_detach", new Object[] { IAPIEnvironment.SIDE_NAMES[side] } );
|
m_environment.queueEvent( "peripheral_detach", new Object[] { Computer.s_sideNames[side] } );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign the new peripheral
|
// Assign the new peripheral
|
||||||
if( newPeripheral != null )
|
if( newPeripheral != null )
|
||||||
{
|
{
|
||||||
m_peripherals[side] = new PeripheralWrapper( newPeripheral, IAPIEnvironment.SIDE_NAMES[side] );
|
m_peripherals[side] = new PeripheralWrapper( newPeripheral, Computer.s_sideNames[side] );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -317,7 +317,7 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
|||||||
}, null );
|
}, null );
|
||||||
|
|
||||||
// Queue an attachment event
|
// Queue an attachment event
|
||||||
m_environment.queueEvent( "peripheral", new Object[] { IAPIEnvironment.SIDE_NAMES[side] } );
|
m_environment.queueEvent( "peripheral", new Object[] { Computer.s_sideNames[side] } );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -483,9 +483,9 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
|||||||
private int parseSide( Object[] args ) throws LuaException
|
private int parseSide( Object[] args ) throws LuaException
|
||||||
{
|
{
|
||||||
String side = getString( args, 0 );
|
String side = getString( args, 0 );
|
||||||
for( int n = 0; n < IAPIEnvironment.SIDE_NAMES.length; n++ )
|
for( int n = 0; n < Computer.s_sideNames.length; n++ )
|
||||||
{
|
{
|
||||||
if( side.equals( IAPIEnvironment.SIDE_NAMES[n] ) )
|
if( side.equals( Computer.s_sideNames[n] ) )
|
||||||
{
|
{
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,7 @@ package dan200.computercraft.core.apis;
|
|||||||
import dan200.computercraft.api.lua.ILuaAPI;
|
import dan200.computercraft.api.lua.ILuaAPI;
|
||||||
import dan200.computercraft.api.lua.ILuaContext;
|
import dan200.computercraft.api.lua.ILuaContext;
|
||||||
import dan200.computercraft.api.lua.LuaException;
|
import dan200.computercraft.api.lua.LuaException;
|
||||||
|
import dan200.computercraft.core.computer.Computer;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -64,9 +65,9 @@ public class RedstoneAPI implements ILuaAPI
|
|||||||
{
|
{
|
||||||
// getSides
|
// getSides
|
||||||
Map<Object, Object> table = new HashMap<>();
|
Map<Object, Object> table = new HashMap<>();
|
||||||
for( int i = 0; i < IAPIEnvironment.SIDE_NAMES.length; i++ )
|
for( int i = 0; i < Computer.s_sideNames.length; i++ )
|
||||||
{
|
{
|
||||||
table.put( i + 1, IAPIEnvironment.SIDE_NAMES[i] );
|
table.put( i + 1, Computer.s_sideNames[i] );
|
||||||
}
|
}
|
||||||
return new Object[] { table };
|
return new Object[] { table };
|
||||||
}
|
}
|
||||||
@@ -155,9 +156,9 @@ public class RedstoneAPI implements ILuaAPI
|
|||||||
private int parseSide( Object[] args ) throws LuaException
|
private int parseSide( Object[] args ) throws LuaException
|
||||||
{
|
{
|
||||||
String side = getString( args, 0 );
|
String side = getString( args, 0 );
|
||||||
for( int n = 0; n < IAPIEnvironment.SIDE_NAMES.length; n++ )
|
for( int n = 0; n < Computer.s_sideNames.length; n++ )
|
||||||
{
|
{
|
||||||
if( side.equals( IAPIEnvironment.SIDE_NAMES[n] ) )
|
if( side.equals( Computer.s_sideNames[n] ) )
|
||||||
{
|
{
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@@ -11,7 +11,6 @@ import dan200.computercraft.api.lua.ILuaContext;
|
|||||||
import dan200.computercraft.api.lua.LuaException;
|
import dan200.computercraft.api.lua.LuaException;
|
||||||
import dan200.computercraft.core.computer.IComputerEnvironment;
|
import dan200.computercraft.core.computer.IComputerEnvironment;
|
||||||
import dan200.computercraft.core.terminal.Terminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
import dan200.computercraft.shared.util.Colour;
|
|
||||||
import dan200.computercraft.shared.util.Palette;
|
import dan200.computercraft.shared.util.Palette;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
@@ -66,8 +65,6 @@ public class TermAPI implements ILuaAPI
|
|||||||
"setPaletteColor",
|
"setPaletteColor",
|
||||||
"getPaletteColour",
|
"getPaletteColour",
|
||||||
"getPaletteColor",
|
"getPaletteColor",
|
||||||
"nativePaletteColour",
|
|
||||||
"nativePaletteColor",
|
|
||||||
"getCursorBlink",
|
"getCursorBlink",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -292,19 +289,6 @@ public class TermAPI implements ILuaAPI
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
case 23:
|
case 23:
|
||||||
case 24:
|
|
||||||
{
|
|
||||||
// nativePaletteColour/nativePaletteColor
|
|
||||||
int colour = 15 - parseColour( args );
|
|
||||||
Colour c = Colour.fromInt( colour );
|
|
||||||
|
|
||||||
float[] rgb = c.getRGB();
|
|
||||||
|
|
||||||
Object[] rgbObj = new Object[rgb.length];
|
|
||||||
for( int i = 0; i < rgbObj.length; ++i ) rgbObj[i] = rgb[i];
|
|
||||||
return rgbObj;
|
|
||||||
}
|
|
||||||
case 25:
|
|
||||||
// getCursorBlink
|
// getCursorBlink
|
||||||
return new Object[] { m_terminal.getCursorBlink() };
|
return new Object[] { m_terminal.getCursorBlink() };
|
||||||
default:
|
default:
|
||||||
|
@@ -169,42 +169,27 @@ public class BinaryReadableHandle extends HandleGeneric
|
|||||||
{
|
{
|
||||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||||
|
|
||||||
boolean readAnything = false, readRc = false;
|
boolean readAnything = false;
|
||||||
while( true )
|
while( true )
|
||||||
{
|
{
|
||||||
single.clear();
|
single.clear();
|
||||||
int read = m_reader.read( single );
|
int r = m_reader.read( single );
|
||||||
if( read <= 0 )
|
if( r == -1 ) break;
|
||||||
{
|
|
||||||
// Nothing else to read, and we saw no \n. Return the array. If we saw a \r, then add it
|
|
||||||
// back.
|
|
||||||
if( readRc ) stream.write( '\r' );
|
|
||||||
return readAnything ? new Object[] { stream.toByteArray() } : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
readAnything = true;
|
readAnything = true;
|
||||||
|
byte b = single.get( 0 );
|
||||||
byte chr = single.get( 0 );
|
if( b == '\n' )
|
||||||
if( chr == '\n' )
|
|
||||||
{
|
{
|
||||||
if( withTrailing )
|
if( withTrailing ) stream.write( b );
|
||||||
{
|
break;
|
||||||
if( readRc ) stream.write( '\r' );
|
|
||||||
stream.write( chr );
|
|
||||||
}
|
|
||||||
return new Object[] { stream.toByteArray() };
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// We want to skip \r\n, but obviously need to include cases where \r is not followed by \n.
|
stream.write( b );
|
||||||
// Note, this behaviour is non-standard compliant (strictly speaking we should have no
|
|
||||||
// special logic for \r), but we preserve compatibility with EncodedReadableHandle and
|
|
||||||
// previous behaviour of the io library.
|
|
||||||
if( readRc ) stream.write( '\r' );
|
|
||||||
readRc = chr == '\r';
|
|
||||||
if( !readRc ) stream.write( chr );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return readAnything ? new Object[] { stream.toByteArray() } : null;
|
||||||
}
|
}
|
||||||
catch( IOException e )
|
catch( IOException e )
|
||||||
{
|
{
|
||||||
|
@@ -83,11 +83,6 @@ public class WebsocketHandler extends SimpleChannelInboundHandler<Object>
|
|||||||
CloseWebSocketFrame closeFrame = (CloseWebSocketFrame) frame;
|
CloseWebSocketFrame closeFrame = (CloseWebSocketFrame) frame;
|
||||||
websocket.close( closeFrame.statusCode(), closeFrame.reasonText() );
|
websocket.close( closeFrame.statusCode(), closeFrame.reasonText() );
|
||||||
}
|
}
|
||||||
else if( frame instanceof PingWebSocketFrame )
|
|
||||||
{
|
|
||||||
frame.content().retain();
|
|
||||||
ctx.channel().writeAndFlush( new PongWebSocketFrame( frame.content() ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -113,13 +108,6 @@ public class WebsocketHandler extends SimpleChannelInboundHandler<Object>
|
|||||||
message = "Could not connect";
|
message = "Could not connect";
|
||||||
}
|
}
|
||||||
|
|
||||||
if( handshaker.isHandshakeComplete() )
|
websocket.failure( message );
|
||||||
{
|
|
||||||
websocket.close( -1, message );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
websocket.failure( message );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
package dan200.computercraft.core.computer;
|
|
||||||
|
|
||||||
import dan200.computercraft.api.lua.ILuaAPI;
|
|
||||||
import dan200.computercraft.api.lua.ILuaContext;
|
|
||||||
import dan200.computercraft.api.lua.LuaException;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A wrapper for {@link ILuaAPI}s which cleans up after a {@link ComputerSystem} when the computer is shutdown.
|
|
||||||
*/
|
|
||||||
public class ApiWrapper implements ILuaAPI
|
|
||||||
{
|
|
||||||
private final ILuaAPI delegate;
|
|
||||||
private final ComputerSystem system;
|
|
||||||
|
|
||||||
ApiWrapper( ILuaAPI delegate, ComputerSystem system )
|
|
||||||
{
|
|
||||||
this.delegate = delegate;
|
|
||||||
this.system = system;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getNames()
|
|
||||||
{
|
|
||||||
return delegate.getNames();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void startup()
|
|
||||||
{
|
|
||||||
delegate.startup();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update()
|
|
||||||
{
|
|
||||||
delegate.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void shutdown()
|
|
||||||
{
|
|
||||||
delegate.shutdown();
|
|
||||||
system.unmountAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public String[] getMethodNames()
|
|
||||||
{
|
|
||||||
return delegate.getMethodNames();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException
|
|
||||||
{
|
|
||||||
return delegate.callMethod( context, method, arguments );
|
|
||||||
}
|
|
||||||
}
|
|
@@ -8,10 +8,11 @@ package dan200.computercraft.core.computer;
|
|||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import dan200.computercraft.api.filesystem.IFileSystem;
|
||||||
import dan200.computercraft.api.filesystem.IMount;
|
import dan200.computercraft.api.filesystem.IMount;
|
||||||
import dan200.computercraft.api.filesystem.IWritableMount;
|
import dan200.computercraft.api.filesystem.IWritableMount;
|
||||||
import dan200.computercraft.api.lua.ILuaAPI;
|
import dan200.computercraft.api.lua.ILuaAPI;
|
||||||
import dan200.computercraft.api.lua.ILuaAPIFactory;
|
import dan200.computercraft.api.lua.*;
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
import dan200.computercraft.core.apis.*;
|
import dan200.computercraft.core.apis.*;
|
||||||
import dan200.computercraft.core.filesystem.FileSystem;
|
import dan200.computercraft.core.filesystem.FileSystem;
|
||||||
@@ -19,7 +20,11 @@ import dan200.computercraft.core.filesystem.FileSystemException;
|
|||||||
import dan200.computercraft.core.lua.CobaltLuaMachine;
|
import dan200.computercraft.core.lua.CobaltLuaMachine;
|
||||||
import dan200.computercraft.core.lua.ILuaMachine;
|
import dan200.computercraft.core.lua.ILuaMachine;
|
||||||
import dan200.computercraft.core.terminal.Terminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
|
import dan200.computercraft.core.tracking.Tracking;
|
||||||
|
import dan200.computercraft.core.tracking.TrackingField;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -27,6 +32,10 @@ import java.util.List;
|
|||||||
|
|
||||||
public class Computer
|
public class Computer
|
||||||
{
|
{
|
||||||
|
public static final String[] s_sideNames = new String[] {
|
||||||
|
"bottom", "top", "back", "front", "right", "left",
|
||||||
|
};
|
||||||
|
|
||||||
private enum State
|
private enum State
|
||||||
{
|
{
|
||||||
Off,
|
Off,
|
||||||
@@ -35,81 +44,319 @@ public class Computer
|
|||||||
Stopping,
|
Stopping,
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IMount s_romMount = null;
|
private static class APIEnvironment implements IAPIEnvironment
|
||||||
|
|
||||||
private int m_id;
|
|
||||||
private String m_label = null;
|
|
||||||
private final IComputerEnvironment m_environment;
|
|
||||||
|
|
||||||
private int m_ticksSinceStart = -1;
|
|
||||||
private boolean m_startRequested = false;
|
|
||||||
private State m_state = State.Off;
|
|
||||||
private boolean m_blinking = false;
|
|
||||||
|
|
||||||
private ILuaMachine m_machine = null;
|
|
||||||
private final List<ILuaAPI> m_apis = new ArrayList<>();
|
|
||||||
private final Environment m_internalEnvironment = new Environment( this );
|
|
||||||
|
|
||||||
private final Terminal m_terminal;
|
|
||||||
private FileSystem m_fileSystem = null;
|
|
||||||
private IWritableMount m_rootMount = null;
|
|
||||||
|
|
||||||
private boolean m_externalOutputChanged;
|
|
||||||
|
|
||||||
public Computer( IComputerEnvironment environment, Terminal terminal, int id )
|
|
||||||
{
|
{
|
||||||
m_id = id;
|
private Computer m_computer;
|
||||||
m_environment = environment;
|
private IAPIEnvironment.IPeripheralChangeListener m_peripheralListener;
|
||||||
m_terminal = terminal;
|
|
||||||
|
|
||||||
// Ensure the computer thread is running as required.
|
public APIEnvironment( Computer computer )
|
||||||
ComputerThread.start();
|
|
||||||
|
|
||||||
// Add all default APIs to the loaded list.
|
|
||||||
m_apis.add( new TermAPI( m_internalEnvironment ) );
|
|
||||||
m_apis.add( new RedstoneAPI( m_internalEnvironment ) );
|
|
||||||
m_apis.add( new FSAPI( m_internalEnvironment ) );
|
|
||||||
m_apis.add( new PeripheralAPI( m_internalEnvironment ) );
|
|
||||||
m_apis.add( new OSAPI( m_internalEnvironment ) );
|
|
||||||
if( ComputerCraft.http_enable ) m_apis.add( new HTTPAPI( m_internalEnvironment ) );
|
|
||||||
|
|
||||||
// Load in the API registered APIs.
|
|
||||||
for( ILuaAPIFactory factory : ApiFactories.getAll() )
|
|
||||||
{
|
{
|
||||||
ComputerSystem system = new ComputerSystem( m_internalEnvironment );
|
m_computer = computer;
|
||||||
ILuaAPI api = factory.create( system );
|
m_peripheralListener = null;
|
||||||
if( api != null ) m_apis.add( new ApiWrapper( api, system ) );
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Computer getComputer()
|
||||||
|
{
|
||||||
|
return m_computer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getComputerID()
|
||||||
|
{
|
||||||
|
return m_computer.assignID();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IComputerEnvironment getComputerEnvironment()
|
||||||
|
{
|
||||||
|
return m_computer.m_environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Terminal getTerminal()
|
||||||
|
{
|
||||||
|
return m_computer.m_terminal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileSystem getFileSystem()
|
||||||
|
{
|
||||||
|
return m_computer.m_fileSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown()
|
||||||
|
{
|
||||||
|
m_computer.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reboot()
|
||||||
|
{
|
||||||
|
m_computer.reboot();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queueEvent( String event, Object[] args )
|
||||||
|
{
|
||||||
|
m_computer.queueEvent( event, args );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOutput( int side, int output )
|
||||||
|
{
|
||||||
|
m_computer.setRedstoneOutput( side, output );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOutput( int side )
|
||||||
|
{
|
||||||
|
return m_computer.getInternalRedstoneOutput( side );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInput( int side )
|
||||||
|
{
|
||||||
|
return m_computer.getRedstoneInput( side );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBundledOutput( int side, int output )
|
||||||
|
{
|
||||||
|
m_computer.setBundledRedstoneOutput( side, output );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBundledOutput( int side )
|
||||||
|
{
|
||||||
|
return m_computer.getInternalBundledRedstoneOutput( side );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBundledInput( int side )
|
||||||
|
{
|
||||||
|
return m_computer.getBundledRedstoneInput( side );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPeripheral getPeripheral( int side )
|
||||||
|
{
|
||||||
|
synchronized( m_computer.m_peripherals )
|
||||||
|
{
|
||||||
|
return m_computer.m_peripherals[side];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPeripheralChangeListener( IPeripheralChangeListener listener )
|
||||||
|
{
|
||||||
|
synchronized( m_computer.m_peripherals )
|
||||||
|
{
|
||||||
|
m_peripheralListener = listener;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLabel()
|
||||||
|
{
|
||||||
|
return m_computer.getLabel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLabel( String label )
|
||||||
|
{
|
||||||
|
m_computer.setLabel( label );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTrackingChange( TrackingField field, long change )
|
||||||
|
{
|
||||||
|
Tracking.addValue( m_computer, field, change );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPeripheralChanged( int side, IPeripheral peripheral )
|
||||||
|
{
|
||||||
|
synchronized( m_computer.m_peripherals )
|
||||||
|
{
|
||||||
|
if( m_peripheralListener != null )
|
||||||
|
{
|
||||||
|
m_peripheralListener.onPeripheralChanged( side, peripheral );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IComputerEnvironment getComputerEnvironment()
|
private static class ComputerSystem extends ComputerAccess implements IComputerSystem
|
||||||
{
|
{
|
||||||
return m_environment;
|
private final IAPIEnvironment m_environment;
|
||||||
|
|
||||||
|
private ComputerSystem( IAPIEnvironment m_environment )
|
||||||
|
{
|
||||||
|
super( m_environment );
|
||||||
|
this.m_environment = m_environment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String getAttachmentName()
|
||||||
|
{
|
||||||
|
return "computer";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public IFileSystem getFileSystem()
|
||||||
|
{
|
||||||
|
FileSystem fs = m_environment.getFileSystem();
|
||||||
|
return fs == null ? null : fs.getMountWrapper();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getLabel()
|
||||||
|
{
|
||||||
|
return m_environment.getLabel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystem getFileSystem()
|
private static class APIWrapper implements ILuaAPI
|
||||||
{
|
{
|
||||||
return m_fileSystem;
|
private final ILuaAPI delegate;
|
||||||
|
private final ComputerSystem system;
|
||||||
|
|
||||||
|
private APIWrapper( ILuaAPI delegate, ComputerSystem system )
|
||||||
|
{
|
||||||
|
this.delegate = delegate;
|
||||||
|
this.system = system;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getNames()
|
||||||
|
{
|
||||||
|
return delegate.getNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startup()
|
||||||
|
{
|
||||||
|
delegate.startup();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update()
|
||||||
|
{
|
||||||
|
delegate.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown()
|
||||||
|
{
|
||||||
|
delegate.shutdown();
|
||||||
|
system.unmountAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public String[] getMethodNames()
|
||||||
|
{
|
||||||
|
return delegate.getMethodNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException
|
||||||
|
{
|
||||||
|
return delegate.callMethod( context, method, arguments );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Terminal getTerminal()
|
private static IMount s_romMount = null;
|
||||||
{
|
|
||||||
return m_terminal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Environment getEnvironment()
|
private int m_id;
|
||||||
|
private String m_label;
|
||||||
|
private final IComputerEnvironment m_environment;
|
||||||
|
|
||||||
|
private int m_ticksSinceStart;
|
||||||
|
private boolean m_startRequested;
|
||||||
|
private State m_state;
|
||||||
|
private boolean m_blinking;
|
||||||
|
|
||||||
|
private ILuaMachine m_machine;
|
||||||
|
private final List<ILuaAPI> m_apis;
|
||||||
|
private final APIEnvironment m_apiEnvironment;
|
||||||
|
|
||||||
|
private final Terminal m_terminal;
|
||||||
|
private FileSystem m_fileSystem;
|
||||||
|
private IWritableMount m_rootMount;
|
||||||
|
|
||||||
|
private final int[] m_internalOutput;
|
||||||
|
private final int[] m_internalBundledOutput;
|
||||||
|
private boolean m_internalOutputChanged;
|
||||||
|
|
||||||
|
private final int[] m_externalOutput;
|
||||||
|
private final int[] m_externalBundledOutput;
|
||||||
|
private boolean m_externalOutputChanged;
|
||||||
|
|
||||||
|
private final int[] m_input;
|
||||||
|
private final int[] m_bundledInput;
|
||||||
|
private boolean m_inputChanged;
|
||||||
|
|
||||||
|
private final IPeripheral[] m_peripherals;
|
||||||
|
|
||||||
|
public Computer( IComputerEnvironment environment, Terminal terminal, int id )
|
||||||
{
|
{
|
||||||
return m_internalEnvironment;
|
ComputerThread.start();
|
||||||
|
|
||||||
|
m_id = id;
|
||||||
|
m_label = null;
|
||||||
|
m_environment = environment;
|
||||||
|
|
||||||
|
m_ticksSinceStart = -1;
|
||||||
|
m_startRequested = false;
|
||||||
|
m_state = State.Off;
|
||||||
|
m_blinking = false;
|
||||||
|
|
||||||
|
m_terminal = terminal;
|
||||||
|
m_fileSystem = null;
|
||||||
|
|
||||||
|
m_machine = null;
|
||||||
|
m_apis = new ArrayList<>();
|
||||||
|
m_apiEnvironment = new APIEnvironment( this );
|
||||||
|
|
||||||
|
m_internalOutput = new int[6];
|
||||||
|
m_internalBundledOutput = new int[6];
|
||||||
|
m_internalOutputChanged = true;
|
||||||
|
|
||||||
|
m_externalOutput = new int[6];
|
||||||
|
m_externalBundledOutput = new int[6];
|
||||||
|
m_externalOutputChanged = true;
|
||||||
|
|
||||||
|
m_input = new int[6];
|
||||||
|
m_bundledInput = new int[6];
|
||||||
|
m_inputChanged = false;
|
||||||
|
|
||||||
|
m_peripherals = new IPeripheral[6];
|
||||||
|
for( int i = 0; i < 6; i++ )
|
||||||
|
{
|
||||||
|
m_peripherals[i] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_rootMount = null;
|
||||||
|
createAPIs();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IAPIEnvironment getAPIEnvironment()
|
public IAPIEnvironment getAPIEnvironment()
|
||||||
{
|
{
|
||||||
return m_internalEnvironment;
|
return m_apiEnvironment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void turnOn()
|
public void turnOn()
|
||||||
{
|
{
|
||||||
if( m_state == State.Off ) m_startRequested = true;
|
if( m_state == State.Off )
|
||||||
|
{
|
||||||
|
m_startRequested = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void shutdown()
|
public void shutdown()
|
||||||
@@ -150,7 +397,10 @@ public class Computer
|
|||||||
|
|
||||||
public void unload()
|
public void unload()
|
||||||
{
|
{
|
||||||
stopComputer( false );
|
synchronized( this )
|
||||||
|
{
|
||||||
|
stopComputer( false );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getID()
|
public int getID()
|
||||||
@@ -186,7 +436,7 @@ public class Computer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void advance()
|
public void advance( double _dt )
|
||||||
{
|
{
|
||||||
synchronized( this )
|
synchronized( this )
|
||||||
{
|
{
|
||||||
@@ -203,27 +453,67 @@ public class Computer
|
|||||||
|
|
||||||
if( m_state == State.Running )
|
if( m_state == State.Running )
|
||||||
{
|
{
|
||||||
// Update the environment's internal state.
|
// Fire the redstone event if our redstone input has changed
|
||||||
m_internalEnvironment.update();
|
synchronized( m_input )
|
||||||
|
{
|
||||||
|
if( m_inputChanged )
|
||||||
|
{
|
||||||
|
queueEvent( "redstone", null );
|
||||||
|
m_inputChanged = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Advance our APIs
|
// Advance our APIs
|
||||||
for( ILuaAPI api : m_apis ) api.update();
|
synchronized( m_apis )
|
||||||
|
{
|
||||||
|
for( ILuaAPI api : m_apis )
|
||||||
|
{
|
||||||
|
api.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare to propagate the environment's output to the world.
|
// Set outputchanged if the internal redstone has changed
|
||||||
if( m_internalEnvironment.updateOutput() ) m_externalOutputChanged = true;
|
synchronized( m_internalOutput )
|
||||||
|
|
||||||
// Set output changed if the terminal has changed from blinking to not
|
|
||||||
boolean blinking =
|
|
||||||
m_terminal.getCursorBlink() &&
|
|
||||||
m_terminal.getCursorX() >= 0 && m_terminal.getCursorX() < m_terminal.getWidth() &&
|
|
||||||
m_terminal.getCursorY() >= 0 && m_terminal.getCursorY() < m_terminal.getHeight();
|
|
||||||
|
|
||||||
if( blinking != m_blinking )
|
|
||||||
{
|
{
|
||||||
m_blinking = blinking;
|
if( m_internalOutputChanged )
|
||||||
m_externalOutputChanged = true;
|
{
|
||||||
|
boolean changed = false;
|
||||||
|
for( int i = 0; i < 6; i++ )
|
||||||
|
{
|
||||||
|
if( m_externalOutput[i] != m_internalOutput[i] )
|
||||||
|
{
|
||||||
|
m_externalOutput[i] = m_internalOutput[i];
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if( m_externalBundledOutput[i] != m_internalBundledOutput[i] )
|
||||||
|
{
|
||||||
|
m_externalBundledOutput[i] = m_internalBundledOutput[i];
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_internalOutputChanged = false;
|
||||||
|
if( changed )
|
||||||
|
{
|
||||||
|
m_externalOutputChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set outputchanged if the terminal has changed from blinking to not
|
||||||
|
synchronized( m_terminal )
|
||||||
|
{
|
||||||
|
boolean blinking =
|
||||||
|
m_terminal.getCursorBlink() &&
|
||||||
|
m_terminal.getCursorX() >= 0 && m_terminal.getCursorX() < m_terminal.getWidth() &&
|
||||||
|
m_terminal.getCursorY() >= 0 && m_terminal.getCursorY() < m_terminal.getHeight();
|
||||||
|
|
||||||
|
if( blinking != m_blinking )
|
||||||
|
{
|
||||||
|
m_blinking = blinking;
|
||||||
|
m_externalOutputChanged = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +529,10 @@ public class Computer
|
|||||||
|
|
||||||
public boolean isBlinking()
|
public boolean isBlinking()
|
||||||
{
|
{
|
||||||
return isOn() && m_blinking;
|
synchronized( m_terminal )
|
||||||
|
{
|
||||||
|
return isOn() && m_blinking;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IWritableMount getRootMount()
|
public IWritableMount getRootMount()
|
||||||
@@ -260,7 +553,10 @@ public class Computer
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_fileSystem = new FileSystem( "hdd", getRootMount() );
|
m_fileSystem = new FileSystem( "hdd", getRootMount() );
|
||||||
if( s_romMount == null ) s_romMount = m_environment.createResourceMount( "computercraft", "lua/rom" );
|
if( s_romMount == null )
|
||||||
|
{
|
||||||
|
s_romMount = m_environment.createResourceMount( "computercraft", "lua/rom" );
|
||||||
|
}
|
||||||
if( s_romMount != null )
|
if( s_romMount != null )
|
||||||
{
|
{
|
||||||
m_fileSystem.mount( "rom", "rom", s_romMount );
|
m_fileSystem.mount( "rom", "rom", s_romMount );
|
||||||
@@ -275,6 +571,104 @@ public class Computer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Redstone
|
||||||
|
|
||||||
|
public int getRedstoneOutput( int side )
|
||||||
|
{
|
||||||
|
synchronized( m_internalOutput )
|
||||||
|
{
|
||||||
|
return isOn() ? m_externalOutput[side] : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getInternalRedstoneOutput( int side )
|
||||||
|
{
|
||||||
|
synchronized( m_internalOutput )
|
||||||
|
{
|
||||||
|
return isOn() ? m_internalOutput[side] : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setRedstoneOutput( int side, int level )
|
||||||
|
{
|
||||||
|
synchronized( m_internalOutput )
|
||||||
|
{
|
||||||
|
if( m_internalOutput[side] != level )
|
||||||
|
{
|
||||||
|
m_internalOutput[side] = level;
|
||||||
|
m_internalOutputChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRedstoneInput( int side, int level )
|
||||||
|
{
|
||||||
|
synchronized( m_input )
|
||||||
|
{
|
||||||
|
if( m_input[side] != level )
|
||||||
|
{
|
||||||
|
m_input[side] = level;
|
||||||
|
m_inputChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getRedstoneInput( int side )
|
||||||
|
{
|
||||||
|
synchronized( m_input )
|
||||||
|
{
|
||||||
|
return m_input[side];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBundledRedstoneOutput( int side )
|
||||||
|
{
|
||||||
|
synchronized( m_internalOutput )
|
||||||
|
{
|
||||||
|
return isOn() ? m_externalBundledOutput[side] : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getInternalBundledRedstoneOutput( int side )
|
||||||
|
{
|
||||||
|
synchronized( m_internalOutput )
|
||||||
|
{
|
||||||
|
return isOn() ? m_internalBundledOutput[side] : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setBundledRedstoneOutput( int side, int combination )
|
||||||
|
{
|
||||||
|
synchronized( m_internalOutput )
|
||||||
|
{
|
||||||
|
if( m_internalBundledOutput[side] != combination )
|
||||||
|
{
|
||||||
|
m_internalBundledOutput[side] = combination;
|
||||||
|
m_internalOutputChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBundledRedstoneInput( int side, int combination )
|
||||||
|
{
|
||||||
|
synchronized( m_input )
|
||||||
|
{
|
||||||
|
if( m_bundledInput[side] != combination )
|
||||||
|
{
|
||||||
|
m_bundledInput[side] = combination;
|
||||||
|
m_inputChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getBundledRedstoneInput( int side )
|
||||||
|
{
|
||||||
|
synchronized( m_input )
|
||||||
|
{
|
||||||
|
return m_bundledInput[side];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Peripherals
|
// Peripherals
|
||||||
|
|
||||||
public void addAPI( ILuaAPI api )
|
public void addAPI( ILuaAPI api )
|
||||||
@@ -282,8 +676,57 @@ public class Computer
|
|||||||
m_apis.add( api );
|
m_apis.add( api );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings( "deprecation" )
|
||||||
|
public void addAPI( dan200.computercraft.core.apis.ILuaAPI api )
|
||||||
|
{
|
||||||
|
addAPI( (ILuaAPI) api );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPeripheral( int side, IPeripheral peripheral )
|
||||||
|
{
|
||||||
|
synchronized( m_peripherals )
|
||||||
|
{
|
||||||
|
IPeripheral existing = m_peripherals[side];
|
||||||
|
if( (existing == null && peripheral != null) ||
|
||||||
|
(existing != null && peripheral == null) ||
|
||||||
|
(existing != null && !existing.equals( peripheral )) )
|
||||||
|
{
|
||||||
|
m_peripherals[side] = peripheral;
|
||||||
|
m_apiEnvironment.onPeripheralChanged( side, peripheral );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPeripheral getPeripheral( int side )
|
||||||
|
{
|
||||||
|
synchronized( m_peripherals )
|
||||||
|
{
|
||||||
|
return m_peripherals[side];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Lua
|
// Lua
|
||||||
|
|
||||||
|
private void createAPIs()
|
||||||
|
{
|
||||||
|
m_apis.add( new TermAPI( m_apiEnvironment ) );
|
||||||
|
m_apis.add( new RedstoneAPI( m_apiEnvironment ) );
|
||||||
|
m_apis.add( new FSAPI( m_apiEnvironment ) );
|
||||||
|
m_apis.add( new PeripheralAPI( m_apiEnvironment ) );
|
||||||
|
m_apis.add( new OSAPI( m_apiEnvironment ) );
|
||||||
|
if( ComputerCraft.http_enable )
|
||||||
|
{
|
||||||
|
m_apis.add( new HTTPAPI( m_apiEnvironment ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( ILuaAPIFactory factory : ApiFactories.getAll() )
|
||||||
|
{
|
||||||
|
ComputerSystem system = new ComputerSystem( m_apiEnvironment );
|
||||||
|
ILuaAPI api = factory.create( system );
|
||||||
|
if( api != null ) m_apis.add( api );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void initLua()
|
private void initLua()
|
||||||
{
|
{
|
||||||
// Create the lua machine
|
// Create the lua machine
|
||||||
@@ -381,7 +824,10 @@ public class Computer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Init terminal
|
// Init terminal
|
||||||
m_terminal.reset();
|
synchronized( m_terminal )
|
||||||
|
{
|
||||||
|
m_terminal.reset();
|
||||||
|
}
|
||||||
|
|
||||||
// Init filesystem
|
// Init filesystem
|
||||||
if( !initFileSystem() )
|
if( !initFileSystem() )
|
||||||
@@ -474,7 +920,10 @@ public class Computer
|
|||||||
|
|
||||||
if( m_machine != null )
|
if( m_machine != null )
|
||||||
{
|
{
|
||||||
m_terminal.reset();
|
synchronized( m_terminal )
|
||||||
|
{
|
||||||
|
m_terminal.reset();
|
||||||
|
}
|
||||||
|
|
||||||
synchronized( m_machine )
|
synchronized( m_machine )
|
||||||
{
|
{
|
||||||
@@ -484,7 +933,15 @@ public class Computer
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reset redstone output
|
// Reset redstone output
|
||||||
m_internalEnvironment.resetOutput();
|
synchronized( m_internalOutput )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < 6; i++ )
|
||||||
|
{
|
||||||
|
m_internalOutput[i] = 0;
|
||||||
|
m_internalBundledOutput[i] = 0;
|
||||||
|
}
|
||||||
|
m_internalOutputChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
m_state = State.Off;
|
m_state = State.Off;
|
||||||
m_externalOutputChanged = true;
|
m_externalOutputChanged = true;
|
||||||
@@ -545,31 +1002,4 @@ public class Computer
|
|||||||
|
|
||||||
ComputerThread.queueTask( task, computer );
|
ComputerThread.queueTask( task, computer );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public IPeripheral getPeripheral( int side )
|
|
||||||
{
|
|
||||||
return m_internalEnvironment.getPeripheral( side );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void setPeripheral( int side, IPeripheral peripheral )
|
|
||||||
{
|
|
||||||
m_internalEnvironment.setPeripheral( side, peripheral );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void addAPI( dan200.computercraft.core.apis.ILuaAPI api )
|
|
||||||
{
|
|
||||||
addAPI( (ILuaAPI) api );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
@SuppressWarnings( "unused" )
|
|
||||||
public void advance( double dt )
|
|
||||||
{
|
|
||||||
advance();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final String[] s_sideNames = IAPIEnvironment.SIDE_NAMES;
|
|
||||||
}
|
}
|
||||||
|
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
package dan200.computercraft.core.computer;
|
|
||||||
|
|
||||||
import dan200.computercraft.api.filesystem.IFileSystem;
|
|
||||||
import dan200.computercraft.api.lua.IComputerSystem;
|
|
||||||
import dan200.computercraft.api.lua.ILuaAPIFactory;
|
|
||||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
|
||||||
import dan200.computercraft.core.apis.ComputerAccess;
|
|
||||||
import dan200.computercraft.core.apis.IAPIEnvironment;
|
|
||||||
import dan200.computercraft.core.filesystem.FileSystem;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of {@link IComputerAccess}/{@link IComputerSystem} for external APIs.
|
|
||||||
*
|
|
||||||
* @see dan200.computercraft.api.ComputerCraftAPI#registerAPIFactory(ILuaAPIFactory)
|
|
||||||
* @see ILuaAPIFactory
|
|
||||||
* @see ApiWrapper
|
|
||||||
*/
|
|
||||||
public class ComputerSystem extends ComputerAccess implements IComputerSystem
|
|
||||||
{
|
|
||||||
private final IAPIEnvironment m_environment;
|
|
||||||
|
|
||||||
ComputerSystem( IAPIEnvironment m_environment )
|
|
||||||
{
|
|
||||||
super( m_environment );
|
|
||||||
this.m_environment = m_environment;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public String getAttachmentName()
|
|
||||||
{
|
|
||||||
return "computer";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public IFileSystem getFileSystem()
|
|
||||||
{
|
|
||||||
FileSystem fs = m_environment.getFileSystem();
|
|
||||||
return fs == null ? null : fs.getMountWrapper();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public String getLabel()
|
|
||||||
{
|
|
||||||
return m_environment.getLabel();
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,306 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
package dan200.computercraft.core.computer;
|
|
||||||
|
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
|
||||||
import dan200.computercraft.core.apis.IAPIEnvironment;
|
|
||||||
import dan200.computercraft.core.filesystem.FileSystem;
|
|
||||||
import dan200.computercraft.core.terminal.Terminal;
|
|
||||||
import dan200.computercraft.core.tracking.Tracking;
|
|
||||||
import dan200.computercraft.core.tracking.TrackingField;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents the "environment" that a {@link Computer} exists in.
|
|
||||||
*
|
|
||||||
* This handles storing and updating of peripherals and redstone.
|
|
||||||
*
|
|
||||||
* <h2>Redstone</h2>
|
|
||||||
* We holds three kinds of arrays for redstone, in normal and bundled versions:
|
|
||||||
* <ul>
|
|
||||||
* <li>{@link #internalOutput} is the redstone output which the computer has currently set. This is read on both
|
|
||||||
* threads, and written on the computer thread.</li>
|
|
||||||
* <li>{@link #externalOutput} is the redstone output currently propagated to the world. This is only read and written
|
|
||||||
* on the main thread.</li>
|
|
||||||
* <li>{@link #input} is the redstone input from external sources. This is read on both threads, and written on the main
|
|
||||||
* thread.</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* <h2>Peripheral</h2>
|
|
||||||
* We also keep track of peripherals. These are read on both threads, and only written on the main thread.
|
|
||||||
*/
|
|
||||||
public final class Environment implements IAPIEnvironment
|
|
||||||
{
|
|
||||||
private final Computer computer;
|
|
||||||
|
|
||||||
private boolean internalOutputChanged = false;
|
|
||||||
private final int[] internalOutput = new int[SIDE_COUNT];
|
|
||||||
private final int[] internalBundledOutput = new int[SIDE_COUNT];
|
|
||||||
|
|
||||||
private final int[] externalOutput = new int[SIDE_COUNT];
|
|
||||||
private final int[] externalBundledOutput = new int[SIDE_COUNT];
|
|
||||||
|
|
||||||
private boolean inputChanged = false;
|
|
||||||
private final int[] input = new int[SIDE_COUNT];
|
|
||||||
private final int[] bundledInput = new int[SIDE_COUNT];
|
|
||||||
|
|
||||||
private final IPeripheral[] peripherals = new IPeripheral[SIDE_COUNT];
|
|
||||||
private IPeripheralChangeListener peripheralListener = null;
|
|
||||||
|
|
||||||
Environment( Computer computer )
|
|
||||||
{
|
|
||||||
this.computer = computer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public Computer getComputer()
|
|
||||||
{
|
|
||||||
return computer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getComputerID()
|
|
||||||
{
|
|
||||||
return computer.assignID();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public IComputerEnvironment getComputerEnvironment()
|
|
||||||
{
|
|
||||||
return computer.getComputerEnvironment();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
|
||||||
public Terminal getTerminal()
|
|
||||||
{
|
|
||||||
return computer.getTerminal();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FileSystem getFileSystem()
|
|
||||||
{
|
|
||||||
return computer.getFileSystem();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void shutdown()
|
|
||||||
{
|
|
||||||
computer.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reboot()
|
|
||||||
{
|
|
||||||
computer.reboot();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void queueEvent( String event, Object[] args )
|
|
||||||
{
|
|
||||||
computer.queueEvent( event, args );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInput( int side )
|
|
||||||
{
|
|
||||||
return input[side];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBundledInput( int side )
|
|
||||||
{
|
|
||||||
return bundledInput[side];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setOutput( int side, int output )
|
|
||||||
{
|
|
||||||
synchronized( internalOutput )
|
|
||||||
{
|
|
||||||
if( internalOutput[side] != output )
|
|
||||||
{
|
|
||||||
internalOutput[side] = output;
|
|
||||||
internalOutputChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getOutput( int side )
|
|
||||||
{
|
|
||||||
synchronized( internalOutput )
|
|
||||||
{
|
|
||||||
return computer.isOn() ? internalOutput[side] : 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBundledOutput( int side, int output )
|
|
||||||
{
|
|
||||||
synchronized( internalOutput )
|
|
||||||
{
|
|
||||||
if( internalBundledOutput[side] != output )
|
|
||||||
{
|
|
||||||
internalBundledOutput[side] = output;
|
|
||||||
internalOutputChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getBundledOutput( int side )
|
|
||||||
{
|
|
||||||
synchronized( internalOutput )
|
|
||||||
{
|
|
||||||
return computer.isOn() ? internalBundledOutput[side] : 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getExternalRedstoneOutput( int side )
|
|
||||||
{
|
|
||||||
return computer.isOn() ? externalOutput[side] : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getExternalBundledRedstoneOutput( int side )
|
|
||||||
{
|
|
||||||
return computer.isOn() ? externalBundledOutput[side] : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRedstoneInput( int side, int level )
|
|
||||||
{
|
|
||||||
if( input[side] != level )
|
|
||||||
{
|
|
||||||
input[side] = level;
|
|
||||||
inputChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBundledRedstoneInput( int side, int combination )
|
|
||||||
{
|
|
||||||
if( bundledInput[side] != combination )
|
|
||||||
{
|
|
||||||
bundledInput[side] = combination;
|
|
||||||
inputChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called on the main thread to update the internal state of the computer.
|
|
||||||
*
|
|
||||||
* This just queues a {@code redstone} event if the input has changed.
|
|
||||||
*/
|
|
||||||
void update()
|
|
||||||
{
|
|
||||||
if( inputChanged )
|
|
||||||
{
|
|
||||||
inputChanged = false;
|
|
||||||
queueEvent( "redstone", null );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called on the main thread to propagate the internal outputs to the external ones.
|
|
||||||
*
|
|
||||||
* @return If the outputs have changed.
|
|
||||||
*/
|
|
||||||
boolean updateOutput()
|
|
||||||
{
|
|
||||||
// Set outputchanged if the internal redstone has changed
|
|
||||||
synchronized( internalOutput )
|
|
||||||
{
|
|
||||||
if( !internalOutputChanged ) return false;
|
|
||||||
|
|
||||||
boolean changed = false;
|
|
||||||
|
|
||||||
for( int i = 0; i < SIDE_COUNT; i++ )
|
|
||||||
{
|
|
||||||
if( externalOutput[i] != internalOutput[i] )
|
|
||||||
{
|
|
||||||
externalOutput[i] = internalOutput[i];
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( externalBundledOutput[i] != internalBundledOutput[i] )
|
|
||||||
{
|
|
||||||
externalBundledOutput[i] = internalBundledOutput[i];
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internalOutputChanged = false;
|
|
||||||
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void resetOutput()
|
|
||||||
{
|
|
||||||
// Reset redstone output
|
|
||||||
synchronized( internalOutput )
|
|
||||||
{
|
|
||||||
Arrays.fill( internalOutput, 0 );
|
|
||||||
Arrays.fill( internalBundledOutput, 0 );
|
|
||||||
internalOutputChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IPeripheral getPeripheral( int side )
|
|
||||||
{
|
|
||||||
synchronized( peripherals )
|
|
||||||
{
|
|
||||||
return peripherals[side];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPeripheral( int side, IPeripheral peripheral )
|
|
||||||
{
|
|
||||||
synchronized( peripherals )
|
|
||||||
{
|
|
||||||
IPeripheral existing = peripherals[side];
|
|
||||||
if( (existing == null && peripheral != null) ||
|
|
||||||
(existing != null && peripheral == null) ||
|
|
||||||
(existing != null && !existing.equals( peripheral )) )
|
|
||||||
{
|
|
||||||
peripherals[side] = peripheral;
|
|
||||||
if( peripheralListener != null ) peripheralListener.onPeripheralChanged( side, peripheral );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPeripheralChangeListener( IPeripheralChangeListener listener )
|
|
||||||
{
|
|
||||||
synchronized( peripherals )
|
|
||||||
{
|
|
||||||
peripheralListener = listener;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLabel()
|
|
||||||
{
|
|
||||||
return computer.getLabel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLabel( String label )
|
|
||||||
{
|
|
||||||
computer.setLabel( label );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addTrackingChange( @Nonnull TrackingField field, long change )
|
|
||||||
{
|
|
||||||
Tracking.addValue( computer, field, change );
|
|
||||||
}
|
|
||||||
}
|
|
@@ -9,7 +9,6 @@ package dan200.computercraft.shared.command;
|
|||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
import dan200.computercraft.core.apis.IAPIEnvironment;
|
|
||||||
import dan200.computercraft.core.computer.Computer;
|
import dan200.computercraft.core.computer.Computer;
|
||||||
import dan200.computercraft.core.tracking.ComputerTracker;
|
import dan200.computercraft.core.tracking.ComputerTracker;
|
||||||
import dan200.computercraft.core.tracking.Tracking;
|
import dan200.computercraft.core.tracking.Tracking;
|
||||||
@@ -127,7 +126,7 @@ public final class CommandComputerCraft extends CommandDelegate
|
|||||||
IPeripheral peripheral = computer.getPeripheral( i );
|
IPeripheral peripheral = computer.getPeripheral( i );
|
||||||
if( peripheral != null )
|
if( peripheral != null )
|
||||||
{
|
{
|
||||||
table.row( header( "Peripheral " + IAPIEnvironment.SIDE_NAMES[i] ), text( peripheral.getType() ) );
|
table.row( header( "Peripheral " + Computer.s_sideNames[i] ), text( peripheral.getType() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -101,11 +101,6 @@ public class TableBuilder
|
|||||||
return additional;
|
return additional;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAdditional( int additional )
|
|
||||||
{
|
|
||||||
this.additional = additional;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trim this table to a given height
|
* Trim this table to a given height
|
||||||
*
|
*
|
||||||
@@ -115,8 +110,8 @@ public class TableBuilder
|
|||||||
{
|
{
|
||||||
if( rows.size() > height )
|
if( rows.size() > height )
|
||||||
{
|
{
|
||||||
additional += rows.size() - height - 1;
|
additional += rows.size() - height;
|
||||||
rows.subList( height - 1, rows.size() ).clear();
|
rows.subList( height, rows.size() ).clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -74,6 +74,8 @@ public interface TableFormatter
|
|||||||
int totalWidth = (columns - 1) * getWidth( SEPARATOR );
|
int totalWidth = (columns - 1) * getWidth( SEPARATOR );
|
||||||
for( int x : maxWidths ) totalWidth += x;
|
for( int x : maxWidths ) totalWidth += x;
|
||||||
|
|
||||||
|
// TODO: Limit the widths of some entries if totalWidth > maxWidth
|
||||||
|
|
||||||
if( headers != null )
|
if( headers != null )
|
||||||
{
|
{
|
||||||
TextComponentString line = new TextComponentString( "" );
|
TextComponentString line = new TextComponentString( "" );
|
||||||
|
@@ -51,11 +51,15 @@ public abstract class BlockGeneric extends Block implements ITileEntityProvider
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@SuppressWarnings( "deprecation" )
|
|
||||||
public final void neighborChanged( IBlockState state, World world, BlockPos pos, Block block, BlockPos neighbour )
|
public final void neighborChanged( IBlockState state, World world, BlockPos pos, Block block, BlockPos neighbour )
|
||||||
{
|
{
|
||||||
TileEntity tile = world.getTileEntity( pos );
|
TileEntity tile = world.getTileEntity( pos );
|
||||||
if( tile instanceof TileGeneric ) ((TileGeneric) tile).onNeighbourChange( neighbour );
|
if( tile instanceof TileGeneric )
|
||||||
|
{
|
||||||
|
TileGeneric generic = (TileGeneric) tile;
|
||||||
|
generic.onNeighbourChange();
|
||||||
|
generic.onNeighbourChange( neighbour );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -63,10 +63,8 @@ public abstract class TileGeneric extends TileEntity
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings( "deprecation" )
|
|
||||||
public void onNeighbourChange( @Nonnull BlockPos neighbour )
|
public void onNeighbourChange( @Nonnull BlockPos neighbour )
|
||||||
{
|
{
|
||||||
onNeighbourChange();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour )
|
public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour )
|
||||||
|
@@ -105,7 +105,7 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
|||||||
public void update()
|
public void update()
|
||||||
{
|
{
|
||||||
super.update();
|
super.update();
|
||||||
m_computer.advance();
|
m_computer.advance( 0.05 );
|
||||||
|
|
||||||
m_changedLastFrame = m_computer.pollAndResetChanged() || m_changed;
|
m_changedLastFrame = m_computer.pollAndResetChanged() || m_changed;
|
||||||
m_changed = false;
|
m_changed = false;
|
||||||
@@ -283,22 +283,22 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
|||||||
|
|
||||||
public int getRedstoneOutput( int side )
|
public int getRedstoneOutput( int side )
|
||||||
{
|
{
|
||||||
return m_computer.getEnvironment().getExternalRedstoneOutput( side );
|
return m_computer.getRedstoneOutput( side );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRedstoneInput( int side, int level )
|
public void setRedstoneInput( int side, int level )
|
||||||
{
|
{
|
||||||
m_computer.getEnvironment().setRedstoneInput( side, level );
|
m_computer.setRedstoneInput( side, level );
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBundledRedstoneOutput( int side )
|
public int getBundledRedstoneOutput( int side )
|
||||||
{
|
{
|
||||||
return m_computer.getEnvironment().getExternalBundledRedstoneOutput( side );
|
return m_computer.getBundledRedstoneOutput( side );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBundledRedstoneInput( int side, int combination )
|
public void setBundledRedstoneInput( int side, int combination )
|
||||||
{
|
{
|
||||||
m_computer.getEnvironment().setBundledRedstoneInput( side, combination );
|
m_computer.setBundledRedstoneInput( side, combination );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAPI( ILuaAPI api )
|
public void addAPI( ILuaAPI api )
|
||||||
@@ -306,7 +306,7 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
|||||||
m_computer.addAPI( api );
|
m_computer.addAPI( api );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@SuppressWarnings( "deprecation" )
|
||||||
public void addAPI( dan200.computercraft.core.apis.ILuaAPI api )
|
public void addAPI( dan200.computercraft.core.apis.ILuaAPI api )
|
||||||
{
|
{
|
||||||
m_computer.addAPI( api );
|
m_computer.addAPI( api );
|
||||||
@@ -314,12 +314,12 @@ public class ServerComputer extends ServerTerminal implements IComputer, IComput
|
|||||||
|
|
||||||
public void setPeripheral( int side, IPeripheral peripheral )
|
public void setPeripheral( int side, IPeripheral peripheral )
|
||||||
{
|
{
|
||||||
m_computer.getEnvironment().setPeripheral( side, peripheral );
|
m_computer.setPeripheral( side, peripheral );
|
||||||
}
|
}
|
||||||
|
|
||||||
public IPeripheral getPeripheral( int side )
|
public IPeripheral getPeripheral( int side )
|
||||||
{
|
{
|
||||||
return m_computer.getEnvironment().getPeripheral( side );
|
return m_computer.getPeripheral( side );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLabel( String label )
|
public void setLabel( String label )
|
||||||
|
@@ -43,10 +43,7 @@ final class BundledCapabilityProvider implements ICapabilityProvider
|
|||||||
if( capability == CAPABILITY_RECEIVER )
|
if( capability == CAPABILITY_RECEIVER )
|
||||||
{
|
{
|
||||||
IBundledReceiver receiver = this.receiver;
|
IBundledReceiver receiver = this.receiver;
|
||||||
if( receiver == null )
|
if( receiver == null ) receiver = this.receiver = tile::onNeighbourChange;
|
||||||
{
|
|
||||||
receiver = this.receiver = () -> tile.onNeighbourChange( tile.getPos().offset( side ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return CAPABILITY_RECEIVER.cast( receiver );
|
return CAPABILITY_RECEIVER.cast( receiver );
|
||||||
}
|
}
|
||||||
|
@@ -48,8 +48,6 @@ public class ChatTableClientMessage implements NetworkMessage
|
|||||||
{
|
{
|
||||||
for( ITextComponent column : row ) buf.writeTextComponent( column );
|
for( ITextComponent column : row ) buf.writeTextComponent( column );
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.writeVarInt( table.getAdditional() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -76,8 +74,6 @@ public class ChatTableClientMessage implements NetworkMessage
|
|||||||
for( int j = 0; j < columns; j++ ) row[j] = NBTUtil.readTextComponent( buf );
|
for( int j = 0; j < columns; j++ ) row[j] = NBTUtil.readTextComponent( buf );
|
||||||
table.row( row );
|
table.row( row );
|
||||||
}
|
}
|
||||||
|
|
||||||
table.setAdditional( buf.readVarInt() );
|
|
||||||
this.table = table;
|
this.table = table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,7 +25,6 @@ public abstract class TileWirelessModemBase extends TileGeneric implements IPeri
|
|||||||
protected TileWirelessModemBase( boolean advanced )
|
protected TileWirelessModemBase( boolean advanced )
|
||||||
{
|
{
|
||||||
this.advanced = advanced;
|
this.advanced = advanced;
|
||||||
this.modem = new Peripheral( this ); // Needs to be initialised after advanced
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Peripheral extends WirelessModemPeripheral
|
private static class Peripheral extends WirelessModemPeripheral
|
||||||
@@ -63,7 +62,7 @@ public abstract class TileWirelessModemBase extends TileGeneric implements IPeri
|
|||||||
private final boolean advanced;
|
private final boolean advanced;
|
||||||
private boolean hasModemDirection = false;
|
private boolean hasModemDirection = false;
|
||||||
private EnumFacing modemDirection = EnumFacing.DOWN;
|
private EnumFacing modemDirection = EnumFacing.DOWN;
|
||||||
private final ModemPeripheral modem;
|
private final ModemPeripheral modem = new Peripheral( this );
|
||||||
private boolean destroyed = false;
|
private boolean destroyed = false;
|
||||||
|
|
||||||
private boolean on = false;
|
private boolean on = false;
|
||||||
|
@@ -13,6 +13,7 @@ import dan200.computercraft.shared.media.items.ItemPrintout;
|
|||||||
import dan200.computercraft.shared.peripheral.PeripheralType;
|
import dan200.computercraft.shared.peripheral.PeripheralType;
|
||||||
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
|
import dan200.computercraft.shared.peripheral.common.TilePeripheralBase;
|
||||||
import dan200.computercraft.shared.util.DefaultSidedInventory;
|
import dan200.computercraft.shared.util.DefaultSidedInventory;
|
||||||
|
import dan200.computercraft.shared.util.InventoryUtil;
|
||||||
import dan200.computercraft.shared.util.WorldUtil;
|
import dan200.computercraft.shared.util.WorldUtil;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
@@ -261,23 +262,6 @@ public class TilePrinter extends TilePeripheralBase implements DefaultSidedInven
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isItemValidForSlot( int slot, @Nonnull ItemStack stack )
|
|
||||||
{
|
|
||||||
if( slot == 0 )
|
|
||||||
{
|
|
||||||
return isInk( stack );
|
|
||||||
}
|
|
||||||
else if( slot >= topSlots[0] && slot <= topSlots[topSlots.length - 1] )
|
|
||||||
{
|
|
||||||
return isPaper( stack );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasCustomName()
|
public boolean hasCustomName()
|
||||||
{
|
{
|
||||||
@@ -409,15 +393,15 @@ public class TilePrinter extends TilePeripheralBase implements DefaultSidedInven
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isInk( @Nonnull ItemStack stack )
|
private boolean isInk( @Nonnull ItemStack stack )
|
||||||
{
|
{
|
||||||
return stack.getItem() == Items.DYE;
|
return (stack.getItem() == Items.DYE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isPaper( @Nonnull ItemStack stack )
|
private boolean isPaper( @Nonnull ItemStack stack )
|
||||||
{
|
{
|
||||||
Item item = stack.getItem();
|
Item item = stack.getItem();
|
||||||
return item == Items.PAPER || (item instanceof ItemPrintout && ItemPrintout.getType( stack ) == ItemPrintout.Type.Single);
|
return (item == Items.PAPER || (item instanceof ItemPrintout && ItemPrintout.getType( stack ) == ItemPrintout.Type.Single));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean canInputPage()
|
private boolean canInputPage()
|
||||||
@@ -509,14 +493,11 @@ public class TilePrinter extends TilePeripheralBase implements DefaultSidedInven
|
|||||||
ItemStack stack = ItemPrintout.createSingleFromTitleAndText( m_pageTitle, lines, colours );
|
ItemStack stack = ItemPrintout.createSingleFromTitleAndText( m_pageTitle, lines, colours );
|
||||||
synchronized( m_inventory )
|
synchronized( m_inventory )
|
||||||
{
|
{
|
||||||
for( int slot : bottomSlots )
|
ItemStack remainder = InventoryUtil.storeItems( stack, m_itemHandlerAll, 7, 6, 7 );
|
||||||
|
if( remainder.isEmpty() )
|
||||||
{
|
{
|
||||||
if( m_inventory.get( slot ).isEmpty() )
|
m_printing = false;
|
||||||
{
|
return true;
|
||||||
m_inventory.set( slot, stack );
|
|
||||||
m_printing = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@@ -80,7 +80,7 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
|||||||
m_inventory = NonNullList.withSize( INVENTORY_SIZE, ItemStack.EMPTY );
|
m_inventory = NonNullList.withSize( INVENTORY_SIZE, ItemStack.EMPTY );
|
||||||
m_previousInventory = NonNullList.withSize( INVENTORY_SIZE, ItemStack.EMPTY );
|
m_previousInventory = NonNullList.withSize( INVENTORY_SIZE, ItemStack.EMPTY );
|
||||||
m_inventoryChanged = false;
|
m_inventoryChanged = false;
|
||||||
m_brain = new TurtleBrain( this );
|
m_brain = createBrain();
|
||||||
m_moveState = MoveState.NOT_MOVED;
|
m_moveState = MoveState.NOT_MOVED;
|
||||||
m_family = family;
|
m_family = family;
|
||||||
}
|
}
|
||||||
@@ -90,12 +90,21 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
|||||||
return m_moveState == MoveState.MOVED;
|
return m_moveState == MoveState.MOVED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected TurtleBrain createBrain()
|
||||||
protected ServerComputer createComputer( int instanceID, int id )
|
{
|
||||||
|
return new TurtleBrain( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final ServerComputer createComputer( int instanceID, int id, int termWidth, int termHeight )
|
||||||
{
|
{
|
||||||
ServerComputer computer = new ServerComputer(
|
ServerComputer computer = new ServerComputer(
|
||||||
getWorld(), id, m_label, instanceID, getFamily(),
|
getWorld(),
|
||||||
ComputerCraft.terminalWidth_turtle, ComputerCraft.terminalHeight_turtle
|
id,
|
||||||
|
m_label,
|
||||||
|
instanceID,
|
||||||
|
getFamily(),
|
||||||
|
termWidth,
|
||||||
|
termHeight
|
||||||
);
|
);
|
||||||
computer.setPosition( getPos() );
|
computer.setPosition( getPos() );
|
||||||
computer.addAPI( new TurtleAPI( computer.getAPIEnvironment(), getAccess() ) );
|
computer.addAPI( new TurtleAPI( computer.getAPIEnvironment(), getAccess() ) );
|
||||||
@@ -103,6 +112,12 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
|||||||
return computer;
|
return computer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ServerComputer createComputer( int instanceID, int id )
|
||||||
|
{
|
||||||
|
return createComputer( instanceID, id, ComputerCraft.terminalWidth_turtle, ComputerCraft.terminalHeight_turtle );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ComputerProxy createProxy()
|
public ComputerProxy createProxy()
|
||||||
{
|
{
|
||||||
|
@@ -54,7 +54,7 @@ public class TurtleBrain implements ITurtleAccess
|
|||||||
private int m_commandsIssued = 0;
|
private int m_commandsIssued = 0;
|
||||||
|
|
||||||
private Map<TurtleSide, ITurtleUpgrade> m_upgrades = new EnumMap<>( TurtleSide.class );
|
private Map<TurtleSide, ITurtleUpgrade> m_upgrades = new EnumMap<>( TurtleSide.class );
|
||||||
private Map<TurtleSide, IPeripheral> peripherals = new EnumMap<>( TurtleSide.class );
|
private Map<TurtleSide, IPeripheral> m_peripherals = new EnumMap<>( TurtleSide.class );
|
||||||
private Map<TurtleSide, NBTTagCompound> m_upgradeNBTData = new EnumMap<>( TurtleSide.class );
|
private Map<TurtleSide, NBTTagCompound> m_upgradeNBTData = new EnumMap<>( TurtleSide.class );
|
||||||
|
|
||||||
private int m_selectedSlot = 0;
|
private int m_selectedSlot = 0;
|
||||||
@@ -824,9 +824,9 @@ public class TurtleBrain implements ITurtleAccess
|
|||||||
@Override
|
@Override
|
||||||
public IPeripheral getPeripheral( @Nonnull TurtleSide side )
|
public IPeripheral getPeripheral( @Nonnull TurtleSide side )
|
||||||
{
|
{
|
||||||
if( peripherals.containsKey( side ) )
|
if( m_peripherals.containsKey( side ) )
|
||||||
{
|
{
|
||||||
return peripherals.get( side );
|
return m_peripherals.get( side );
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -924,9 +924,13 @@ public class TurtleBrain implements ITurtleAccess
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updatePeripherals( ServerComputer serverComputer )
|
public void updatePeripherals( ServerComputer serverComputer )
|
||||||
{
|
{
|
||||||
if( serverComputer == null ) return;
|
if( serverComputer == null )
|
||||||
|
{
|
||||||
|
// Nothing to do
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Update peripherals
|
// Update peripherals
|
||||||
for( TurtleSide side : TurtleSide.values() )
|
for( TurtleSide side : TurtleSide.values() )
|
||||||
@@ -938,20 +942,26 @@ public class TurtleBrain implements ITurtleAccess
|
|||||||
peripheral = upgrade.createPeripheral( this, side );
|
peripheral = upgrade.createPeripheral( this, side );
|
||||||
}
|
}
|
||||||
|
|
||||||
IPeripheral existing = peripherals.get( side );
|
int dir = toDirection( side );
|
||||||
if( existing == peripheral || (existing != null && peripheral != null && existing.equals( peripheral )) )
|
if( peripheral != null )
|
||||||
{
|
{
|
||||||
// If the peripheral is the same, just use that.
|
if( !m_peripherals.containsKey( side ) )
|
||||||
peripheral = existing;
|
{
|
||||||
|
serverComputer.setPeripheral( dir, peripheral );
|
||||||
|
m_peripherals.put( side, peripheral );
|
||||||
|
}
|
||||||
|
else if( !m_peripherals.get( side ).equals( peripheral ) )
|
||||||
|
{
|
||||||
|
serverComputer.setPeripheral( dir, peripheral );
|
||||||
|
m_peripherals.remove( side );
|
||||||
|
m_peripherals.put( side, peripheral );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else if( m_peripherals.containsKey( side ) )
|
||||||
{
|
{
|
||||||
// Otherwise update our map
|
serverComputer.setPeripheral( dir, null );
|
||||||
peripherals.put( side, peripheral );
|
m_peripherals.remove( side );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always update the computer: it may not be the same computer as before!
|
|
||||||
serverComputer.setPeripheral( toDirection( side ), peripheral );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
package dan200.computercraft.shared.util;
|
|
||||||
|
|
||||||
import net.minecraft.inventory.IInventory;
|
|
||||||
import net.minecraft.inventory.Slot;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
|
|
||||||
public class ValidatingSlot extends Slot
|
|
||||||
{
|
|
||||||
public ValidatingSlot( IInventory inventoryIn, int index, int xPosition, int yPosition )
|
|
||||||
{
|
|
||||||
super( inventoryIn, index, xPosition, yPosition );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isItemValid( ItemStack stack )
|
|
||||||
{
|
|
||||||
return true; // inventory.isItemValidForSlot( slotNumber, stack );
|
|
||||||
}
|
|
||||||
}
|
|
@@ -48,39 +48,22 @@ function test( colors, color )
|
|||||||
if type( color ) ~= "number" then
|
if type( color ) ~= "number" then
|
||||||
error( "bad argument #2 (expected number, got " .. type( color ) .. ")", 2 )
|
error( "bad argument #2 (expected number, got " .. type( color ) .. ")", 2 )
|
||||||
end
|
end
|
||||||
return bit32.band(colors, color) == color
|
return ((bit32.band(colors, color)) == color)
|
||||||
end
|
|
||||||
|
|
||||||
function packRGB( r, g, b )
|
|
||||||
if type( r ) ~= "number" then
|
|
||||||
error( "bad argument #1 (expected number, got " .. type( r ) .. ")", 2 )
|
|
||||||
end
|
|
||||||
if type( g ) ~= "number" then
|
|
||||||
error( "bad argument #2 (expected number, got " .. type( g ) .. ")", 2 )
|
|
||||||
end
|
|
||||||
if type( b ) ~= "number" then
|
|
||||||
error( "bad argument #3 (expected number, got " .. type( b ) .. ")", 2 )
|
|
||||||
end
|
|
||||||
return
|
|
||||||
bit32.band( r * 255, 0xFF ) * 2^16 +
|
|
||||||
bit32.band( g * 255, 0xFF ) * 2^8 +
|
|
||||||
bit32.band( b * 255, 0xFF )
|
|
||||||
end
|
|
||||||
|
|
||||||
function unpackRGB( rgb )
|
|
||||||
if type( rgb ) ~= "number" then
|
|
||||||
error( "bad argument #1 (expected number, got " .. type( rgb ) .. ")", 2 )
|
|
||||||
end
|
|
||||||
return
|
|
||||||
bit32.band( bit32.rshift( rgb, 16 ), 0xFF ) / 255,
|
|
||||||
bit32.band( bit32.rshift( rgb, 8 ), 0xFF ) / 255,
|
|
||||||
bit32.band( rgb, 0xFF ) / 255
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function rgb8( r, g, b )
|
function rgb8( r, g, b )
|
||||||
if g == nil and b == nil then
|
if type( r ) ~= "number" then
|
||||||
return unpackRGB( r )
|
error( "bad argument #1 (expected number, got " .. type( r ) .. ")", 2 )
|
||||||
else
|
elseif type(r) == "number" and g == nil and b == nil then
|
||||||
return packRGB( r, g, b )
|
return bit32.band( bit32.rshift( r, 16 ), 0xFF ) / 255, bit32.band( bit32.rshift( r, 8 ), 0xFF ) / 255, bit32.band( r, 0xFF ) / 255
|
||||||
|
elseif type(r) == "number" and type(g) == "number" and type(b) == "number" then
|
||||||
|
return
|
||||||
|
bit32.lshift( bit32.band(r * 255, 0xFF), 16 ) +
|
||||||
|
bit32.lshift( bit32.band(g * 255, 0xFF), 8 ) +
|
||||||
|
bit32.band(b * 255, 0xFF)
|
||||||
|
elseif type( g ) ~= "number" then
|
||||||
|
error( "bad argument #2 (expected number, got " .. type( g ) .. ")", 2 )
|
||||||
|
elseif type( b ) ~= "number" then
|
||||||
|
error( "bad argument #3 (expected number, got " .. type( b ) .. ")", 2 )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@@ -42,16 +42,11 @@ term.native = function()
|
|||||||
return native
|
return native
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Some methods shouldn't go through redirects, so we move them to the main
|
|
||||||
-- term API.
|
|
||||||
for _, method in ipairs { "nativePaletteColor", "nativePaletteColour"} do
|
|
||||||
term[method] = native[method]
|
|
||||||
native[method] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
for k,v in pairs( native ) do
|
for k,v in pairs( native ) do
|
||||||
if type( k ) == "string" and type( v ) == "function" and term[k] == nil then
|
if type( k ) == "string" and type( v ) == "function" then
|
||||||
term[k] = wrap( k )
|
if term[k] == nil then
|
||||||
|
term[k] = wrap( k )
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@@ -298,7 +298,7 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible )
|
|||||||
|
|
||||||
local tCol
|
local tCol
|
||||||
if type(r) == "number" and g == nil and b == nil then
|
if type(r) == "number" and g == nil and b == nil then
|
||||||
tCol = { colours.unpackRGB( r ) }
|
tCol = { colours.rgb8( r ) }
|
||||||
tPalette[ colour ] = tCol
|
tPalette[ colour ] = tCol
|
||||||
else
|
else
|
||||||
if type( r ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( r ) .. ")", 2 ) end
|
if type( r ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( r ) .. ")", 2 ) end
|
||||||
|
@@ -8,8 +8,6 @@ local nCurrentProcess = nil
|
|||||||
local nRunningProcess = nil
|
local nRunningProcess = nil
|
||||||
local bShowMenu = false
|
local bShowMenu = false
|
||||||
local bWindowsResized = false
|
local bWindowsResized = false
|
||||||
local nScrollPos = 1
|
|
||||||
local bScrollRight = false
|
|
||||||
|
|
||||||
local function selectProcess( n )
|
local function selectProcess( n )
|
||||||
if nCurrentProcess ~= n then
|
if nCurrentProcess ~= n then
|
||||||
@@ -88,9 +86,6 @@ local function cullProcess( nProcess )
|
|||||||
selectProcess( 1 )
|
selectProcess( 1 )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if nScrollPos ~= 1 then
|
|
||||||
nScrollPos = nScrollPos - 1
|
|
||||||
end
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
@@ -120,15 +115,7 @@ local function redrawMenu()
|
|||||||
parentTerm.setCursorPos( 1, 1 )
|
parentTerm.setCursorPos( 1, 1 )
|
||||||
parentTerm.setBackgroundColor( menuOtherBgColor )
|
parentTerm.setBackgroundColor( menuOtherBgColor )
|
||||||
parentTerm.clearLine()
|
parentTerm.clearLine()
|
||||||
local nCharCount = 0
|
for n=1,#tProcesses do
|
||||||
local nSize = parentTerm.getSize()
|
|
||||||
if nScrollPos ~= 1 then
|
|
||||||
parentTerm.setTextColor( menuOtherTextColor )
|
|
||||||
parentTerm.setBackgroundColor( menuOtherBgColor )
|
|
||||||
parentTerm.write( "<" )
|
|
||||||
nCharCount = 1
|
|
||||||
end
|
|
||||||
for n=nScrollPos,#tProcesses do
|
|
||||||
if n == nCurrentProcess then
|
if n == nCurrentProcess then
|
||||||
parentTerm.setTextColor( menuMainTextColor )
|
parentTerm.setTextColor( menuMainTextColor )
|
||||||
parentTerm.setBackgroundColor( menuMainBgColor )
|
parentTerm.setBackgroundColor( menuMainBgColor )
|
||||||
@@ -137,16 +124,6 @@ local function redrawMenu()
|
|||||||
parentTerm.setBackgroundColor( menuOtherBgColor )
|
parentTerm.setBackgroundColor( menuOtherBgColor )
|
||||||
end
|
end
|
||||||
parentTerm.write( " " .. tProcesses[n].sTitle .. " " )
|
parentTerm.write( " " .. tProcesses[n].sTitle .. " " )
|
||||||
nCharCount = nCharCount + #tProcesses[n].sTitle + 2
|
|
||||||
end
|
|
||||||
if nCharCount > nSize then
|
|
||||||
parentTerm.setTextColor( menuOtherTextColor )
|
|
||||||
parentTerm.setBackgroundColor( menuOtherBgColor )
|
|
||||||
parentTerm.setCursorPos( nSize, 1 )
|
|
||||||
parentTerm.write( ">" )
|
|
||||||
bScrollRight = true
|
|
||||||
else
|
|
||||||
bScrollRight = false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Put the cursor back where it should be
|
-- Put the cursor back where it should be
|
||||||
@@ -285,26 +262,15 @@ while #tProcesses > 0 do
|
|||||||
local button, x, y = tEventData[2], tEventData[3], tEventData[4]
|
local button, x, y = tEventData[2], tEventData[3], tEventData[4]
|
||||||
if bShowMenu and y == 1 then
|
if bShowMenu and y == 1 then
|
||||||
-- Switch process
|
-- Switch process
|
||||||
if x == 1 and nScrollPos ~= 1 then
|
local tabStart = 1
|
||||||
nScrollPos = nScrollPos - 1
|
for n=1,#tProcesses do
|
||||||
redrawMenu()
|
local tabEnd = tabStart + string.len( tProcesses[n].sTitle ) + 1
|
||||||
elseif bScrollRight and x == term.getSize() then
|
if x >= tabStart and x <= tabEnd then
|
||||||
nScrollPos = nScrollPos + 1
|
selectProcess( n )
|
||||||
redrawMenu()
|
redrawMenu()
|
||||||
else
|
break
|
||||||
local tabStart = 1
|
|
||||||
if nScrollPos ~= 1 then
|
|
||||||
tabStart = 2
|
|
||||||
end
|
|
||||||
for n=nScrollPos,#tProcesses do
|
|
||||||
local tabEnd = tabStart + string.len( tProcesses[n].sTitle ) + 1
|
|
||||||
if x >= tabStart and x <= tabEnd then
|
|
||||||
selectProcess( n )
|
|
||||||
redrawMenu()
|
|
||||||
break
|
|
||||||
end
|
|
||||||
tabStart = tabEnd + 1
|
|
||||||
end
|
end
|
||||||
|
tabStart = tabEnd + 1
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- Passthrough to current process
|
-- Passthrough to current process
|
||||||
@@ -318,15 +284,7 @@ while #tProcesses > 0 do
|
|||||||
elseif sEvent == "mouse_drag" or sEvent == "mouse_up" or sEvent == "mouse_scroll" then
|
elseif sEvent == "mouse_drag" or sEvent == "mouse_up" or sEvent == "mouse_scroll" then
|
||||||
-- Other mouse event
|
-- Other mouse event
|
||||||
local p1, x, y = tEventData[2], tEventData[3], tEventData[4]
|
local p1, x, y = tEventData[2], tEventData[3], tEventData[4]
|
||||||
if bShowMenu and sEvent == "mouse_scroll" and y == 1 then
|
if not (bShowMenu and y == 1) then
|
||||||
if p1 == -1 and nScrollPos ~= 1 then
|
|
||||||
nScrollPos = nScrollPos - 1
|
|
||||||
redrawMenu()
|
|
||||||
elseif bScrollRight and p1 == 1 then
|
|
||||||
nScrollPos = nScrollPos + 1
|
|
||||||
redrawMenu()
|
|
||||||
end
|
|
||||||
elseif not (bShowMenu and y == 1) then
|
|
||||||
-- Passthrough to current process
|
-- Passthrough to current process
|
||||||
resumeProcess( nCurrentProcess, sEvent, p1, x, (bShowMenu and y-1) or y )
|
resumeProcess( nCurrentProcess, sEvent, p1, x, (bShowMenu and y-1) or y )
|
||||||
if cullProcess( nCurrentProcess ) then
|
if cullProcess( nCurrentProcess ) then
|
||||||
|
Before Width: | Height: | Size: 190 B After Width: | Height: | Size: 230 B |
Before Width: | Height: | Size: 181 B After Width: | Height: | Size: 222 B |
Before Width: | Height: | Size: 641 B After Width: | Height: | Size: 643 B |
Before Width: | Height: | Size: 205 B After Width: | Height: | Size: 312 B |
Before Width: | Height: | Size: 296 B After Width: | Height: | Size: 332 B |
Before Width: | Height: | Size: 294 B After Width: | Height: | Size: 333 B |
Before Width: | Height: | Size: 179 B After Width: | Height: | Size: 273 B |
Before Width: | Height: | Size: 237 B After Width: | Height: | Size: 381 B |
Before Width: | Height: | Size: 267 B After Width: | Height: | Size: 273 B |
Before Width: | Height: | Size: 224 B After Width: | Height: | Size: 259 B |
Before Width: | Height: | Size: 248 B After Width: | Height: | Size: 250 B |
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 258 B |
Before Width: | Height: | Size: 235 B After Width: | Height: | Size: 263 B |
Before Width: | Height: | Size: 179 B After Width: | Height: | Size: 222 B |
Before Width: | Height: | Size: 221 B After Width: | Height: | Size: 266 B |
Before Width: | Height: | Size: 224 B After Width: | Height: | Size: 261 B |
Before Width: | Height: | Size: 302 B After Width: | Height: | Size: 337 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 294 B After Width: | Height: | Size: 619 B |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 241 B After Width: | Height: | Size: 254 B |
Before Width: | Height: | Size: 282 B After Width: | Height: | Size: 316 B |
Before Width: | Height: | Size: 239 B After Width: | Height: | Size: 253 B |
Before Width: | Height: | Size: 235 B After Width: | Height: | Size: 259 B |
Before Width: | Height: | Size: 426 B After Width: | Height: | Size: 974 B |
Before Width: | Height: | Size: 436 B After Width: | Height: | Size: 989 B |
Before Width: | Height: | Size: 430 B After Width: | Height: | Size: 992 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 490 B After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 223 B After Width: | Height: | Size: 241 B |
Before Width: | Height: | Size: 200 B After Width: | Height: | Size: 211 B |
Before Width: | Height: | Size: 260 B After Width: | Height: | Size: 299 B |
Before Width: | Height: | Size: 200 B After Width: | Height: | Size: 212 B |
Before Width: | Height: | Size: 516 B After Width: | Height: | Size: 638 B |
@@ -10,10 +10,9 @@ import dan200.computercraft.api.lua.LuaException;
|
|||||||
import dan200.computercraft.core.apis.ObjectWrapper;
|
import dan200.computercraft.core.apis.ObjectWrapper;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
public class BinaryReadableHandleTest
|
public class BinaryReadableHandleTest
|
||||||
{
|
{
|
||||||
@@ -60,24 +59,6 @@ public class BinaryReadableHandleTest
|
|||||||
assertEquals( 1000, wrapper.<byte[]>callOf( "read", 11000 ).length );
|
assertEquals( 1000, wrapper.<byte[]>callOf( "read", 11000 ).length );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReadLine() throws LuaException
|
|
||||||
{
|
|
||||||
ObjectWrapper wrapper = new ObjectWrapper( new BinaryReadableHandle( new ArrayByteChannel( "hello\r\nworld\r!".getBytes( StandardCharsets.UTF_8 ) ) ) );
|
|
||||||
assertArrayEquals( "hello".getBytes( StandardCharsets.UTF_8 ), wrapper.callOf( "readLine" ) );
|
|
||||||
assertArrayEquals( "world\r!".getBytes( StandardCharsets.UTF_8 ), wrapper.callOf( "readLine" ) );
|
|
||||||
assertNull( wrapper.call( "readLine" ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReadLineTrailing() throws LuaException
|
|
||||||
{
|
|
||||||
ObjectWrapper wrapper = new ObjectWrapper( new BinaryReadableHandle( new ArrayByteChannel( "hello\r\nworld\r!".getBytes( StandardCharsets.UTF_8 ) ) ) );
|
|
||||||
assertArrayEquals( "hello\r\n".getBytes( StandardCharsets.UTF_8 ), wrapper.callOf( "readLine", true ) );
|
|
||||||
assertArrayEquals( "world\r!".getBytes( StandardCharsets.UTF_8 ), wrapper.callOf( "readLine", true ) );
|
|
||||||
assertNull( wrapper.call( "readLine", true ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ObjectWrapper fromLength( int length )
|
private static ObjectWrapper fromLength( int length )
|
||||||
{
|
{
|
||||||
byte[] input = new byte[length];
|
byte[] input = new byte[length];
|
||||||
|