mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-15 04:30:29 +00:00
Merge branch 'mc-1.16.x' into mc-1.17.x
This commit is contained in:
commit
af966179ce
@ -17,7 +17,7 @@ plugins {
|
|||||||
id "com.github.hierynomus.license" version "0.16.1"
|
id "com.github.hierynomus.license" version "0.16.1"
|
||||||
id "com.matthewprenger.cursegradle" version "1.4.0"
|
id "com.matthewprenger.cursegradle" version "1.4.0"
|
||||||
id "com.github.breadmoirai.github-release" version "2.2.12"
|
id "com.github.breadmoirai.github-release" version "2.2.12"
|
||||||
id "org.jetbrains.kotlin.jvm" version "1.5.21"
|
id "org.jetbrains.kotlin.jvm" version "1.6.0"
|
||||||
id "com.modrinth.minotaur" version "1.2.1"
|
id "com.modrinth.minotaur" version "1.2.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,13 +162,13 @@ dependencies {
|
|||||||
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.7.0'
|
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.7.0'
|
||||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
|
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
|
||||||
testImplementation 'org.hamcrest:hamcrest:2.2'
|
testImplementation 'org.hamcrest:hamcrest:2.2'
|
||||||
testImplementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.21'
|
testImplementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.0'
|
||||||
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1'
|
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2'
|
||||||
|
|
||||||
testModImplementation sourceSets.main.output
|
testModImplementation sourceSets.main.output
|
||||||
testModExtra 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.21'
|
testModExtra 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.21'
|
||||||
|
|
||||||
cctJavadoc 'cc.tweaked:cct-javadoc:1.4.1'
|
cctJavadoc 'cc.tweaked:cct-javadoc:1.4.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile tasks
|
// Compile tasks
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
module: [kind=event] redstone
|
module: [kind=event] redstone
|
||||||
---
|
---
|
||||||
|
|
||||||
The @{redstone} event is fired whenever any redstone inputs on the computer change.
|
The @{event!redstone} event is fired whenever any redstone inputs on the computer change.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
Prints a message when a redstone input changes:
|
Prints a message when a redstone input changes:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
org.gradle.jvmargs=-Xmx3G
|
org.gradle.jvmargs=-Xmx3G
|
||||||
|
|
||||||
# Mod properties
|
# Mod properties
|
||||||
mod_version=1.98.2
|
mod_version=1.99.0
|
||||||
|
|
||||||
# Minecraft properties (update mods.toml when changing)
|
# Minecraft properties (update mods.toml when changing)
|
||||||
mc_version=1.17.1
|
mc_version=1.17.1
|
||||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
269
gradlew
vendored
269
gradlew
vendored
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright 2015 the original author or authors.
|
# Copyright © 2015-2021 the original authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -17,67 +17,101 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
##
|
#
|
||||||
## Gradle start up script for UN*X
|
# Gradle start up script for POSIX generated by Gradle.
|
||||||
##
|
#
|
||||||
|
# Important for running:
|
||||||
|
#
|
||||||
|
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||||
|
# noncompliant, but you have some other compliant shell such as ksh or
|
||||||
|
# bash, then to run this script, type that shell name before the whole
|
||||||
|
# command line, like:
|
||||||
|
#
|
||||||
|
# ksh Gradle
|
||||||
|
#
|
||||||
|
# Busybox and similar reduced shells will NOT work, because this script
|
||||||
|
# requires all of these POSIX shell features:
|
||||||
|
# * functions;
|
||||||
|
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||||
|
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||||
|
# * compound commands having a testable exit status, especially «case»;
|
||||||
|
# * various built-in commands including «command», «set», and «ulimit».
|
||||||
|
#
|
||||||
|
# Important for patching:
|
||||||
|
#
|
||||||
|
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||||
|
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||||
|
#
|
||||||
|
# The "traditional" practice of packing multiple parameters into a
|
||||||
|
# space-separated string is a well documented source of bugs and security
|
||||||
|
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||||
|
# options in "$@", and eventually passing that to Java.
|
||||||
|
#
|
||||||
|
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||||
|
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||||
|
# see the in-line comments for details.
|
||||||
|
#
|
||||||
|
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||||
|
# Darwin, MinGW, and NonStop.
|
||||||
|
#
|
||||||
|
# (3) This script is generated from the Groovy template
|
||||||
|
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
|
# within the Gradle project.
|
||||||
|
#
|
||||||
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
# Attempt to set APP_HOME
|
# Attempt to set APP_HOME
|
||||||
|
|
||||||
# Resolve links: $0 may be a link
|
# Resolve links: $0 may be a link
|
||||||
PRG="$0"
|
app_path=$0
|
||||||
# Need this for relative symlinks.
|
|
||||||
while [ -h "$PRG" ] ; do
|
# Need this for daisy-chained symlinks.
|
||||||
ls=`ls -ld "$PRG"`
|
while
|
||||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||||
if expr "$link" : '/.*' > /dev/null; then
|
[ -h "$app_path" ]
|
||||||
PRG="$link"
|
do
|
||||||
else
|
ls=$( ls -ld "$app_path" )
|
||||||
PRG=`dirname "$PRG"`"/$link"
|
link=${ls#*' -> '}
|
||||||
fi
|
case $link in #(
|
||||||
|
/*) app_path=$link ;; #(
|
||||||
|
*) app_path=$APP_HOME$link ;;
|
||||||
|
esac
|
||||||
done
|
done
|
||||||
SAVED="`pwd`"
|
|
||||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||||
APP_HOME="`pwd -P`"
|
|
||||||
cd "$SAVED" >/dev/null
|
|
||||||
|
|
||||||
APP_NAME="Gradle"
|
APP_NAME="Gradle"
|
||||||
APP_BASE_NAME=`basename "$0"`
|
APP_BASE_NAME=${0##*/}
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD="maximum"
|
MAX_FD=maximum
|
||||||
|
|
||||||
warn () {
|
warn () {
|
||||||
echo "$*"
|
echo "$*"
|
||||||
}
|
} >&2
|
||||||
|
|
||||||
die () {
|
die () {
|
||||||
echo
|
echo
|
||||||
echo "$*"
|
echo "$*"
|
||||||
echo
|
echo
|
||||||
exit 1
|
exit 1
|
||||||
}
|
} >&2
|
||||||
|
|
||||||
# OS specific support (must be 'true' or 'false').
|
# OS specific support (must be 'true' or 'false').
|
||||||
cygwin=false
|
cygwin=false
|
||||||
msys=false
|
msys=false
|
||||||
darwin=false
|
darwin=false
|
||||||
nonstop=false
|
nonstop=false
|
||||||
case "`uname`" in
|
case "$( uname )" in #(
|
||||||
CYGWIN* )
|
CYGWIN* ) cygwin=true ;; #(
|
||||||
cygwin=true
|
Darwin* ) darwin=true ;; #(
|
||||||
;;
|
MSYS* | MINGW* ) msys=true ;; #(
|
||||||
Darwin* )
|
NONSTOP* ) nonstop=true ;;
|
||||||
darwin=true
|
|
||||||
;;
|
|
||||||
MSYS* | MINGW* )
|
|
||||||
msys=true
|
|
||||||
;;
|
|
||||||
NONSTOP* )
|
|
||||||
nonstop=true
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
|||||||
if [ -n "$JAVA_HOME" ] ; then
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
# IBM's JDK on AIX uses strange locations for the executables
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||||
else
|
else
|
||||||
JAVACMD="$JAVA_HOME/bin/java"
|
JAVACMD=$JAVA_HOME/bin/java
|
||||||
fi
|
fi
|
||||||
if [ ! -x "$JAVACMD" ] ; then
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
|||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD="java"
|
JAVACMD=java
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
@ -106,80 +140,95 @@ location of your Java installation."
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
MAX_FD_LIMIT=`ulimit -H -n`
|
case $MAX_FD in #(
|
||||||
if [ $? -eq 0 ] ; then
|
max*)
|
||||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
MAX_FD="$MAX_FD_LIMIT"
|
warn "Could not query maximum file descriptor limit"
|
||||||
fi
|
esac
|
||||||
ulimit -n $MAX_FD
|
case $MAX_FD in #(
|
||||||
if [ $? -ne 0 ] ; then
|
'' | soft) :;; #(
|
||||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
*)
|
||||||
fi
|
ulimit -n "$MAX_FD" ||
|
||||||
else
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Darwin, add options to specify how the application appears in the dock
|
|
||||||
if $darwin; then
|
|
||||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
|
||||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
|
||||||
|
|
||||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
|
||||||
|
|
||||||
# We build the pattern for arguments to be converted via cygpath
|
|
||||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
|
||||||
SEP=""
|
|
||||||
for dir in $ROOTDIRSRAW ; do
|
|
||||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
|
||||||
SEP="|"
|
|
||||||
done
|
|
||||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
|
||||||
# Add a user-defined pattern to the cygpath arguments
|
|
||||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
|
||||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
|
||||||
fi
|
|
||||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
|
||||||
i=0
|
|
||||||
for arg in "$@" ; do
|
|
||||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
|
||||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
|
||||||
|
|
||||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
|
||||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
|
||||||
else
|
|
||||||
eval `echo args$i`="\"$arg\""
|
|
||||||
fi
|
|
||||||
i=`expr $i + 1`
|
|
||||||
done
|
|
||||||
case $i in
|
|
||||||
0) set -- ;;
|
|
||||||
1) set -- "$args0" ;;
|
|
||||||
2) set -- "$args0" "$args1" ;;
|
|
||||||
3) set -- "$args0" "$args1" "$args2" ;;
|
|
||||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
|
||||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
|
||||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
|
||||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
|
||||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
|
||||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Escape application args
|
# Collect all arguments for the java command, stacking in reverse order:
|
||||||
save () {
|
# * args from the command line
|
||||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
# * the main class name
|
||||||
echo " "
|
# * -classpath
|
||||||
}
|
# * -D...appname settings
|
||||||
APP_ARGS=`save "$@"`
|
# * --module-path (only if needed)
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||||
|
|
||||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
if "$cygwin" || "$msys" ; then
|
||||||
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
|
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||||
|
|
||||||
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
|
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
for arg do
|
||||||
|
if
|
||||||
|
case $arg in #(
|
||||||
|
-*) false ;; # don't mess with options #(
|
||||||
|
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||||
|
[ -e "$t" ] ;; #(
|
||||||
|
*) false ;;
|
||||||
|
esac
|
||||||
|
then
|
||||||
|
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||||
|
fi
|
||||||
|
# Roll the args list around exactly as many times as the number of
|
||||||
|
# args, so each arg winds up back in the position where it started, but
|
||||||
|
# possibly modified.
|
||||||
|
#
|
||||||
|
# NB: a `for` loop captures its iteration list before it begins, so
|
||||||
|
# changing the positional parameters here affects neither the number of
|
||||||
|
# iterations, nor the values presented in `arg`.
|
||||||
|
shift # remove old arg
|
||||||
|
set -- "$@" "$arg" # push replacement arg
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Collect all arguments for the java command;
|
||||||
|
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||||
|
# shell script including quotes and variable substitutions, so put them in
|
||||||
|
# double quotes to make sure that they get re-expanded; and
|
||||||
|
# * put everything else in single quotes, so that it's not re-expanded.
|
||||||
|
|
||||||
|
set -- \
|
||||||
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
|
-classpath "$CLASSPATH" \
|
||||||
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
|
"$@"
|
||||||
|
|
||||||
|
# Use "xargs" to parse quoted args.
|
||||||
|
#
|
||||||
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
#
|
||||||
|
# In Bash we could simply go:
|
||||||
|
#
|
||||||
|
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||||
|
# set -- "${ARGS[@]}" "$@"
|
||||||
|
#
|
||||||
|
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||||
|
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||||
|
# character that might be a shell metacharacter, then use eval to reverse
|
||||||
|
# that process (while maintaining the separation between arguments), and wrap
|
||||||
|
# the whole thing up as a single "set" statement.
|
||||||
|
#
|
||||||
|
# This will of course break if any of these variables contains a newline or
|
||||||
|
# an unmatched quote.
|
||||||
|
#
|
||||||
|
|
||||||
|
eval "set -- $(
|
||||||
|
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||||
|
xargs -n1 |
|
||||||
|
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||||
|
tr '\n' ' '
|
||||||
|
)" '"$@"'
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
exec "$JAVACMD" "$@"
|
||||||
|
402
package-lock.json
generated
402
package-lock.json
generated
@ -16,10 +16,45 @@
|
|||||||
"@rollup/plugin-typescript": "^8.2.5",
|
"@rollup/plugin-typescript": "^8.2.5",
|
||||||
"requirejs": "^2.3.6",
|
"requirejs": "^2.3.6",
|
||||||
"rollup": "^2.33.1",
|
"rollup": "^2.33.1",
|
||||||
"terser": "^5.3.8",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
"typescript": "^4.0.5"
|
"typescript": "^4.0.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@babel/code-frame": {
|
||||||
|
"version": "7.16.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz",
|
||||||
|
"integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/highlight": "^7.16.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/helper-validator-identifier": {
|
||||||
|
"version": "7.15.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz",
|
||||||
|
"integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@babel/highlight": {
|
||||||
|
"version": "7.16.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz",
|
||||||
|
"integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/helper-validator-identifier": "^7.15.7",
|
||||||
|
"chalk": "^2.0.0",
|
||||||
|
"js-tokens": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rollup/plugin-typescript": {
|
"node_modules/@rollup/plugin-typescript": {
|
||||||
"version": "8.3.0",
|
"version": "8.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.3.0.tgz",
|
||||||
@ -61,18 +96,74 @@
|
|||||||
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
|
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/node": {
|
||||||
|
"version": "16.11.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.10.tgz",
|
||||||
|
"integrity": "sha512-3aRnHa1KlOEEhJ6+CvyHKK5vE9BcLGjtUpwvqYLRvYNQKMfabu3BwfJaA/SLW8dxe28LsNDjtHwePTuzn3gmOA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/ansi-styles": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"color-convert": "^1.9.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/buffer-from": {
|
"node_modules/buffer-from": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/chalk": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||||
|
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": "^3.2.1",
|
||||||
|
"escape-string-regexp": "^1.0.5",
|
||||||
|
"supports-color": "^5.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/color-convert": {
|
||||||
|
"version": "1.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||||
|
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"color-name": "1.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/color-name": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||||
|
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/commander": {
|
"node_modules/commander": {
|
||||||
"version": "2.20.3",
|
"version": "2.20.3",
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/escape-string-regexp": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||||
|
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/estree-walker": {
|
"node_modules/estree-walker": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
|
||||||
@ -111,6 +202,15 @@
|
|||||||
"node": ">= 0.4.0"
|
"node": ">= 0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/has-flag": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||||
|
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-core-module": {
|
"node_modules/is-core-module": {
|
||||||
"version": "2.8.0",
|
"version": "2.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz",
|
||||||
@ -123,6 +223,53 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jest-worker": {
|
||||||
|
"version": "26.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
|
||||||
|
"integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*",
|
||||||
|
"merge-stream": "^2.0.0",
|
||||||
|
"supports-color": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.13.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/jest-worker/node_modules/has-flag": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/jest-worker/node_modules/supports-color": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"has-flag": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/js-tokens": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/merge-stream": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/path-parse": {
|
"node_modules/path-parse": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||||
@ -142,14 +289,23 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/preact": {
|
"node_modules/preact": {
|
||||||
"version": "10.5.15",
|
"version": "10.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/preact/-/preact-10.5.15.tgz",
|
"resolved": "https://registry.npmjs.org/preact/-/preact-10.6.1.tgz",
|
||||||
"integrity": "sha512-5chK29n6QcJc3m1lVrKQSQ+V7K1Gb8HeQY6FViQ5AxCAEGu3DaHffWNDkC9+miZgsLvbvU9rxbV1qinGHMHzqA==",
|
"integrity": "sha512-ydCg+ISIq70vqiThvNWStZWLRjR9U2awP/JAmGdWUKm9+Tyuy+MqVdAIyEByeIspAVtD4GWC/SJtxO8XD4knVA==",
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/preact"
|
"url": "https://opencollective.com/preact"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/randombytes": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "^5.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/requirejs": {
|
"node_modules/requirejs": {
|
||||||
"version": "2.3.6",
|
"version": "2.3.6",
|
||||||
"resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz",
|
"resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz",
|
||||||
@ -177,9 +333,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "2.60.0",
|
"version": "2.60.1",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.60.0.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.60.1.tgz",
|
||||||
"integrity": "sha512-cHdv9GWd58v58rdseC8e8XIaPUo8a9cgZpnCMMDGZFDZKEODOiPPEQFXLriWr/TjXzhPPmG5bkAztPsOARIcGQ==",
|
"integrity": "sha512-akwfnpjY0rXEDSn1UTVfKXJhPsEBu+imi1gqBA1ZkHGydUnkV/fWCC90P7rDaLEW8KTwBcS1G3N4893Ndz+jwg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"rollup": "dist/bin/rollup"
|
"rollup": "dist/bin/rollup"
|
||||||
@ -191,6 +347,50 @@
|
|||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/rollup-plugin-terser": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/code-frame": "^7.10.4",
|
||||||
|
"jest-worker": "^26.2.1",
|
||||||
|
"serialize-javascript": "^4.0.0",
|
||||||
|
"terser": "^5.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"rollup": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/serialize-javascript": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"randombytes": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/source-map": {
|
"node_modules/source-map": {
|
||||||
"version": "0.7.3",
|
"version": "0.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
|
||||||
@ -219,6 +419,18 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/supports-color": {
|
||||||
|
"version": "5.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||||
|
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"has-flag": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/terser": {
|
"node_modules/terser": {
|
||||||
"version": "5.10.0",
|
"version": "5.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz",
|
||||||
@ -264,6 +476,32 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@babel/code-frame": {
|
||||||
|
"version": "7.16.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz",
|
||||||
|
"integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@babel/highlight": "^7.16.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@babel/helper-validator-identifier": {
|
||||||
|
"version": "7.15.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz",
|
||||||
|
"integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@babel/highlight": {
|
||||||
|
"version": "7.16.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz",
|
||||||
|
"integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@babel/helper-validator-identifier": "^7.15.7",
|
||||||
|
"chalk": "^2.0.0",
|
||||||
|
"js-tokens": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@rollup/plugin-typescript": {
|
"@rollup/plugin-typescript": {
|
||||||
"version": "8.3.0",
|
"version": "8.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.3.0.tgz",
|
||||||
@ -291,18 +529,65 @@
|
|||||||
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
|
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/node": {
|
||||||
|
"version": "16.11.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.10.tgz",
|
||||||
|
"integrity": "sha512-3aRnHa1KlOEEhJ6+CvyHKK5vE9BcLGjtUpwvqYLRvYNQKMfabu3BwfJaA/SLW8dxe28LsNDjtHwePTuzn3gmOA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"color-convert": "^1.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"buffer-from": {
|
"buffer-from": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"chalk": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||||
|
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"ansi-styles": "^3.2.1",
|
||||||
|
"escape-string-regexp": "^1.0.5",
|
||||||
|
"supports-color": "^5.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color-convert": {
|
||||||
|
"version": "1.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||||
|
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"color-name": "1.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color-name": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||||
|
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"commander": {
|
"commander": {
|
||||||
"version": "2.20.3",
|
"version": "2.20.3",
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"escape-string-regexp": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||||
|
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"estree-walker": {
|
"estree-walker": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
|
||||||
@ -331,6 +616,12 @@
|
|||||||
"function-bind": "^1.1.1"
|
"function-bind": "^1.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"has-flag": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||||
|
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"is-core-module": {
|
"is-core-module": {
|
||||||
"version": "2.8.0",
|
"version": "2.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz",
|
||||||
@ -340,6 +631,46 @@
|
|||||||
"has": "^1.0.3"
|
"has": "^1.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"jest-worker": {
|
||||||
|
"version": "26.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
|
||||||
|
"integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "*",
|
||||||
|
"merge-stream": "^2.0.0",
|
||||||
|
"supports-color": "^7.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"has-flag": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"supports-color": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"has-flag": "^4.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"js-tokens": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"merge-stream": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"path-parse": {
|
"path-parse": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||||
@ -353,9 +684,18 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"preact": {
|
"preact": {
|
||||||
"version": "10.5.15",
|
"version": "10.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/preact/-/preact-10.5.15.tgz",
|
"resolved": "https://registry.npmjs.org/preact/-/preact-10.6.1.tgz",
|
||||||
"integrity": "sha512-5chK29n6QcJc3m1lVrKQSQ+V7K1Gb8HeQY6FViQ5AxCAEGu3DaHffWNDkC9+miZgsLvbvU9rxbV1qinGHMHzqA=="
|
"integrity": "sha512-ydCg+ISIq70vqiThvNWStZWLRjR9U2awP/JAmGdWUKm9+Tyuy+MqVdAIyEByeIspAVtD4GWC/SJtxO8XD4knVA=="
|
||||||
|
},
|
||||||
|
"randombytes": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"safe-buffer": "^5.1.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"requirejs": {
|
"requirejs": {
|
||||||
"version": "2.3.6",
|
"version": "2.3.6",
|
||||||
@ -374,14 +714,41 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rollup": {
|
"rollup": {
|
||||||
"version": "2.60.0",
|
"version": "2.60.1",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.60.0.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.60.1.tgz",
|
||||||
"integrity": "sha512-cHdv9GWd58v58rdseC8e8XIaPUo8a9cgZpnCMMDGZFDZKEODOiPPEQFXLriWr/TjXzhPPmG5bkAztPsOARIcGQ==",
|
"integrity": "sha512-akwfnpjY0rXEDSn1UTVfKXJhPsEBu+imi1gqBA1ZkHGydUnkV/fWCC90P7rDaLEW8KTwBcS1G3N4893Ndz+jwg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"rollup-plugin-terser": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@babel/code-frame": "^7.10.4",
|
||||||
|
"jest-worker": "^26.2.1",
|
||||||
|
"serialize-javascript": "^4.0.0",
|
||||||
|
"terser": "^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"serialize-javascript": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"randombytes": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"source-map": {
|
"source-map": {
|
||||||
"version": "0.7.3",
|
"version": "0.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
|
||||||
@ -406,6 +773,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"supports-color": {
|
||||||
|
"version": "5.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||||
|
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"has-flag": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"terser": {
|
"terser": {
|
||||||
"version": "5.10.0",
|
"version": "5.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/terser/-/terser-5.10.0.tgz",
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
"@rollup/plugin-typescript": "^8.2.5",
|
"@rollup/plugin-typescript": "^8.2.5",
|
||||||
"requirejs": "^2.3.6",
|
"requirejs": "^2.3.6",
|
||||||
"rollup": "^2.33.1",
|
"rollup": "^2.33.1",
|
||||||
"terser": "^5.3.8",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
"typescript": "^4.0.5"
|
"typescript": "^4.0.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { readFileSync, promises as fs } from "fs";
|
import { readFileSync } from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
|
||||||
import typescript from "@rollup/plugin-typescript";
|
import typescript from "@rollup/plugin-typescript";
|
||||||
|
import { terser } from "rollup-plugin-terser";
|
||||||
|
|
||||||
const input = "src/web";
|
const input = "src/web";
|
||||||
const requirejs = readFileSync("node_modules/requirejs/require.js");
|
const requirejs = readFileSync("node_modules/requirejs/require.js");
|
||||||
@ -12,7 +13,14 @@ export default {
|
|||||||
file: "build/rollup/index.js",
|
file: "build/rollup/index.js",
|
||||||
// We bundle requirejs (and config) into the header. It's rather gross
|
// We bundle requirejs (and config) into the header. It's rather gross
|
||||||
// but also works reasonably well.
|
// but also works reasonably well.
|
||||||
banner: `${requirejs}\nrequire.config({ paths: { copycat: "https://copy-cat.squiddev.cc" } });`,
|
// Also suffix a ?v=${date} onto the end in the event we need to require a specific copy-cat version.
|
||||||
|
banner: `
|
||||||
|
${requirejs}
|
||||||
|
require.config({
|
||||||
|
paths: { copycat: "https://copy-cat.squiddev.cc" },
|
||||||
|
urlArgs: function(id) { return id == "copycat/embed" ? "?v=20211127" : ""; }
|
||||||
|
});
|
||||||
|
`,
|
||||||
format: "amd",
|
format: "amd",
|
||||||
preferConst: true,
|
preferConst: true,
|
||||||
amd: {
|
amd: {
|
||||||
@ -27,22 +35,6 @@ export default {
|
|||||||
|
|
||||||
{
|
{
|
||||||
name: "cc-tweaked",
|
name: "cc-tweaked",
|
||||||
async options(options) {
|
|
||||||
// Generate .d.ts files for all /mount files. This is the worst way to do it,
|
|
||||||
// but we need to run before the TS pass.
|
|
||||||
const template = "declare const contents : string;\nexport default contents;\n";
|
|
||||||
const files = await fs.readdir(`${input}/mount`);
|
|
||||||
|
|
||||||
await Promise.all(files
|
|
||||||
.filter(x => path.extname(x) !== ".ts")
|
|
||||||
.map(async file => {
|
|
||||||
const path = `${input}/mount/${file}.d.ts`;
|
|
||||||
const contents = await fs.readFile(path, { encoding: "utf-8" }).catch(() => "");
|
|
||||||
if (contents !== template) await fs.writeFile(path, template);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
return options;
|
|
||||||
},
|
|
||||||
async transform(code, file) {
|
async transform(code, file) {
|
||||||
// Allow loading files in /mount.
|
// Allow loading files in /mount.
|
||||||
const ext = path.extname(file);
|
const ext = path.extname(file);
|
||||||
@ -50,6 +42,8 @@ export default {
|
|||||||
? `export default ${JSON.stringify(code)};\n`
|
? `export default ${JSON.stringify(code)};\n`
|
||||||
: null;
|
: null;
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
|
|
||||||
|
terser(),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
@ -10,6 +10,8 @@ import net.minecraftforge.common.capabilities.Capability;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The interface that defines a peripheral.
|
* The interface that defines a peripheral.
|
||||||
@ -31,6 +33,18 @@ public interface IPeripheral
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
String getType();
|
String getType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return additional types/traits associated with this object.
|
||||||
|
*
|
||||||
|
* @return A collection of additional object traits.
|
||||||
|
* @see PeripheralType#getAdditionalTypes()
|
||||||
|
*/
|
||||||
|
@Nonnull
|
||||||
|
default Set<String> getAdditionalTypes()
|
||||||
|
{
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is called when when a computer is attaching to the peripheral.
|
* Is called when when a computer is attaching to the peripheral.
|
||||||
*
|
*
|
||||||
|
@ -6,9 +6,13 @@
|
|||||||
package dan200.computercraft.api.peripheral;
|
package dan200.computercraft.api.peripheral;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of a {@link GenericPeripheral}.
|
* The type of a {@link GenericPeripheral}.
|
||||||
@ -18,13 +22,19 @@ import javax.annotation.Nullable;
|
|||||||
*/
|
*/
|
||||||
public final class PeripheralType
|
public final class PeripheralType
|
||||||
{
|
{
|
||||||
private static final PeripheralType UNTYPED = new PeripheralType( null );
|
private static final PeripheralType UNTYPED = new PeripheralType( null, Collections.emptySet() );
|
||||||
|
|
||||||
private final String type;
|
private final String type;
|
||||||
|
private final Set<String> additionalTypes;
|
||||||
|
|
||||||
public PeripheralType( String type )
|
public PeripheralType( String type, Set<String> additionalTypes )
|
||||||
{
|
{
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
this.additionalTypes = additionalTypes;
|
||||||
|
if( additionalTypes.contains( null ) )
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException( "All additional types must be non-null" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,7 +56,55 @@ public final class PeripheralType
|
|||||||
public static PeripheralType ofType( @Nonnull String type )
|
public static PeripheralType ofType( @Nonnull String type )
|
||||||
{
|
{
|
||||||
if( Strings.isNullOrEmpty( type ) ) throw new IllegalArgumentException( "type cannot be null or empty" );
|
if( Strings.isNullOrEmpty( type ) ) throw new IllegalArgumentException( "type cannot be null or empty" );
|
||||||
return new PeripheralType( type );
|
return new PeripheralType( type, Collections.emptySet() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new non-empty peripheral type with additional traits.
|
||||||
|
*
|
||||||
|
* @param type The name of the type.
|
||||||
|
* @param additionalTypes Additional types, or "traits" of this peripheral. For instance, {@literal "inventory"}.
|
||||||
|
* @return The constructed peripheral type.
|
||||||
|
*/
|
||||||
|
public static PeripheralType ofType( @Nonnull String type, Collection<String> additionalTypes )
|
||||||
|
{
|
||||||
|
if( Strings.isNullOrEmpty( type ) ) throw new IllegalArgumentException( "type cannot be null or empty" );
|
||||||
|
return new PeripheralType( type, ImmutableSet.copyOf( additionalTypes ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new non-empty peripheral type with additional traits.
|
||||||
|
*
|
||||||
|
* @param type The name of the type.
|
||||||
|
* @param additionalTypes Additional types, or "traits" of this peripheral. For instance, {@literal "inventory"}.
|
||||||
|
* @return The constructed peripheral type.
|
||||||
|
*/
|
||||||
|
public static PeripheralType ofType( @Nonnull String type, @Nonnull String... additionalTypes )
|
||||||
|
{
|
||||||
|
if( Strings.isNullOrEmpty( type ) ) throw new IllegalArgumentException( "type cannot be null or empty" );
|
||||||
|
return new PeripheralType( type, ImmutableSet.copyOf( additionalTypes ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new peripheral type with no primary type but additional traits.
|
||||||
|
*
|
||||||
|
* @param additionalTypes Additional types, or "traits" of this peripheral. For instance, {@literal "inventory"}.
|
||||||
|
* @return The constructed peripheral type.
|
||||||
|
*/
|
||||||
|
public static PeripheralType ofAdditional( Collection<String> additionalTypes )
|
||||||
|
{
|
||||||
|
return new PeripheralType( null, ImmutableSet.copyOf( additionalTypes ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new peripheral type with no primary type but additional traits.
|
||||||
|
*
|
||||||
|
* @param additionalTypes Additional types, or "traits" of this peripheral. For instance, {@literal "inventory"}.
|
||||||
|
* @return The constructed peripheral type.
|
||||||
|
*/
|
||||||
|
public static PeripheralType ofAdditional( @Nonnull String... additionalTypes )
|
||||||
|
{
|
||||||
|
return new PeripheralType( null, ImmutableSet.copyOf( additionalTypes ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,4 +117,15 @@ public final class PeripheralType
|
|||||||
{
|
{
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get any additional types or "traits" of this peripheral. These effectively act as a standard set of interfaces
|
||||||
|
* a peripheral might have.
|
||||||
|
*
|
||||||
|
* @return All additional types.
|
||||||
|
*/
|
||||||
|
public Set<String> getAdditionalTypes()
|
||||||
|
{
|
||||||
|
return additionalTypes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -484,7 +484,7 @@ public class FSAPI implements ILuaAPI
|
|||||||
*
|
*
|
||||||
* This string is formatted like a normal path string, but can include any
|
* This string is formatted like a normal path string, but can include any
|
||||||
* number of wildcards ({@code *}) to look for files matching anything.
|
* number of wildcards ({@code *}) to look for files matching anything.
|
||||||
* For example, {@code rom/* /command*} will look for any path starting with
|
* For example, <code>rom/*/command*</code> will look for any path starting with
|
||||||
* {@code command} inside any subdirectory of {@code /rom}.
|
* {@code command} inside any subdirectory of {@code /rom}.
|
||||||
*
|
*
|
||||||
* @param path The wildcard-qualified path to search for.
|
* @param path The wildcard-qualified path to search for.
|
||||||
|
@ -17,6 +17,7 @@ import dan200.computercraft.core.asm.NamedMethod;
|
|||||||
import dan200.computercraft.core.asm.PeripheralMethod;
|
import dan200.computercraft.core.asm.PeripheralMethod;
|
||||||
import dan200.computercraft.core.computer.ComputerSide;
|
import dan200.computercraft.core.computer.ComputerSide;
|
||||||
import dan200.computercraft.core.tracking.TrackingField;
|
import dan200.computercraft.core.tracking.TrackingField;
|
||||||
|
import dan200.computercraft.shared.util.LuaUtil;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -36,6 +37,7 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
|||||||
private final IPeripheral peripheral;
|
private final IPeripheral peripheral;
|
||||||
|
|
||||||
private final String type;
|
private final String type;
|
||||||
|
private final Set<String> additionalTypes;
|
||||||
private final Map<String, PeripheralMethod> methodMap;
|
private final Map<String, PeripheralMethod> methodMap;
|
||||||
private boolean attached;
|
private boolean attached;
|
||||||
|
|
||||||
@ -47,6 +49,7 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
|||||||
attached = false;
|
attached = false;
|
||||||
|
|
||||||
type = Objects.requireNonNull( peripheral.getType(), "Peripheral type cannot be null" );
|
type = Objects.requireNonNull( peripheral.getType(), "Peripheral type cannot be null" );
|
||||||
|
additionalTypes = peripheral.getAdditionalTypes();
|
||||||
|
|
||||||
methodMap = PeripheralAPI.getMethods( peripheral );
|
methodMap = PeripheralAPI.getMethods( peripheral );
|
||||||
}
|
}
|
||||||
@ -61,6 +64,11 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<String> getAdditionalTypes()
|
||||||
|
{
|
||||||
|
return additionalTypes;
|
||||||
|
}
|
||||||
|
|
||||||
public Collection<String> getMethods()
|
public Collection<String> getMethods()
|
||||||
{
|
{
|
||||||
return methodMap.keySet();
|
return methodMap.keySet();
|
||||||
@ -298,7 +306,23 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
|
|||||||
synchronized( peripherals )
|
synchronized( peripherals )
|
||||||
{
|
{
|
||||||
PeripheralWrapper p = peripherals[side.ordinal()];
|
PeripheralWrapper p = peripherals[side.ordinal()];
|
||||||
if( p != null ) return new Object[] { p.getType() };
|
return p == null ? null : LuaUtil.consArray( p.getType(), p.getAdditionalTypes() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@LuaFunction
|
||||||
|
public final Object[] hasType( String sideName, String type )
|
||||||
|
{
|
||||||
|
ComputerSide side = ComputerSide.valueOfInsensitive( sideName );
|
||||||
|
if( side == null ) return null;
|
||||||
|
|
||||||
|
synchronized( peripherals )
|
||||||
|
{
|
||||||
|
PeripheralWrapper p = peripherals[side.ordinal()];
|
||||||
|
if( p != null )
|
||||||
|
{
|
||||||
|
return new Object[] { p.getType().equals( type ) || p.getAdditionalTypes().contains( type ) };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -38,13 +38,13 @@ public final class Peripherals
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static IPeripheral getPeripheral( Level world, BlockPos pos, Direction side, NonNullConsumer<LazyOptional<IPeripheral>> invalidate )
|
public static IPeripheral getPeripheral( Level world, BlockPos pos, Direction side, NonNullConsumer<Object> invalidate )
|
||||||
{
|
{
|
||||||
return world.isInWorldBounds( pos ) && !world.isClientSide ? getPeripheralAt( world, pos, side, invalidate ) : null;
|
return world.isInWorldBounds( pos ) && !world.isClientSide ? getPeripheralAt( world, pos, side, invalidate ) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static IPeripheral getPeripheralAt( Level world, BlockPos pos, Direction side, NonNullConsumer<LazyOptional<IPeripheral>> invalidate )
|
private static IPeripheral getPeripheralAt( Level world, BlockPos pos, Direction side, NonNullConsumer<? super Object> invalidate )
|
||||||
{
|
{
|
||||||
BlockEntity block = world.getBlockEntity( pos );
|
BlockEntity block = world.getBlockEntity( pos );
|
||||||
if( block != null )
|
if( block != null )
|
||||||
|
@ -59,7 +59,7 @@ public abstract class BlockComputerBase<T extends TileComputerBase> extends Bloc
|
|||||||
super.onPlace( state, world, pos, oldState, isMoving );
|
super.onPlace( state, world, pos, oldState, isMoving );
|
||||||
|
|
||||||
BlockEntity tile = world.getBlockEntity( pos );
|
BlockEntity tile = world.getBlockEntity( pos );
|
||||||
if( tile instanceof TileComputerBase computer ) computer.updateInput();
|
if( tile instanceof TileComputerBase computer ) computer.updateInputsImmediately( );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -31,14 +31,9 @@ import net.minecraft.world.Nameable;
|
|||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.Items;
|
import net.minecraft.world.item.Items;
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.block.Blocks;
|
|
||||||
import net.minecraft.world.level.block.DiodeBlock;
|
|
||||||
import net.minecraft.world.level.block.RedStoneWireBlock;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
|
||||||
import net.minecraftforge.common.util.NonNullConsumer;
|
import net.minecraftforge.common.util.NonNullConsumer;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -57,7 +52,9 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
|||||||
private boolean on = false;
|
private boolean on = false;
|
||||||
boolean startOn = false;
|
boolean startOn = false;
|
||||||
private boolean fresh = false;
|
private boolean fresh = false;
|
||||||
private final NonNullConsumer<LazyOptional<IPeripheral>>[] invalidate;
|
|
||||||
|
private int invalidSides = 0;
|
||||||
|
private final NonNullConsumer<Object>[] invalidate;
|
||||||
|
|
||||||
private final ComputerFamily family;
|
private final ComputerFamily family;
|
||||||
|
|
||||||
@ -68,10 +65,11 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
|||||||
|
|
||||||
// We cache these so we can guarantee we only ever register one listener for adjacent capabilities.
|
// We cache these so we can guarantee we only ever register one listener for adjacent capabilities.
|
||||||
@SuppressWarnings( { "unchecked", "rawtypes" } )
|
@SuppressWarnings( { "unchecked", "rawtypes" } )
|
||||||
NonNullConsumer<LazyOptional<IPeripheral>>[] invalidate = this.invalidate = new NonNullConsumer[6];
|
NonNullConsumer<Object>[] invalidate = this.invalidate = new NonNullConsumer[6];
|
||||||
for( Direction direction : Direction.values() )
|
for( Direction direction : Direction.values() )
|
||||||
{
|
{
|
||||||
invalidate[direction.ordinal()] = o -> updateInput( direction );
|
int mask = 1 << direction.ordinal();
|
||||||
|
invalidate[direction.ordinal()] = o -> invalidSides |= mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,19 +141,26 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
|||||||
@Override
|
@Override
|
||||||
public void onNeighbourChange( @Nonnull BlockPos neighbour )
|
public void onNeighbourChange( @Nonnull BlockPos neighbour )
|
||||||
{
|
{
|
||||||
updateInput( neighbour );
|
updateInputAt( neighbour );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour )
|
public void onNeighbourTileEntityChange( @Nonnull BlockPos neighbour )
|
||||||
{
|
{
|
||||||
updateInput( neighbour );
|
updateInputAt( neighbour );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void serverTick()
|
protected void serverTick()
|
||||||
{
|
{
|
||||||
ServerComputer computer = createServerComputer();
|
ServerComputer computer = createServerComputer();
|
||||||
if( computer == null ) return;
|
|
||||||
|
if( invalidSides != 0 )
|
||||||
|
{
|
||||||
|
for( Direction direction : DirectionUtil.FACINGS )
|
||||||
|
{
|
||||||
|
if( (invalidSides & (1 << direction.ordinal())) != 0 ) refreshPeripheral( computer, direction );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the computer isn't on and should be, then turn it on
|
// If the computer isn't on and should be, then turn it on
|
||||||
if( startOn || (fresh && on) )
|
if( startOn || (fresh && on) )
|
||||||
@ -222,89 +227,80 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
|||||||
return localSide;
|
return localSide;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateSideInput( ServerComputer computer, Direction dir, BlockPos offset )
|
private void updateRedstoneInput( @Nonnull ServerComputer computer, Direction dir, BlockPos targetPos )
|
||||||
{
|
{
|
||||||
Direction offsetSide = dir.getOpposite();
|
Direction offsetSide = dir.getOpposite();
|
||||||
ComputerSide localDir = remapToLocalSide( dir );
|
ComputerSide localDir = remapToLocalSide( dir );
|
||||||
|
|
||||||
computer.setRedstoneInput( localDir, getRedstoneInput( level, offset, dir ) );
|
computer.setRedstoneInput( localDir, RedstoneUtil.getRedstoneInput( level, targetPos, dir ) );
|
||||||
computer.setBundledRedstoneInput( localDir, BundledRedstone.getOutput( getLevel(), offset, offsetSide ) );
|
computer.setBundledRedstoneInput( localDir, BundledRedstone.getOutput( getLevel(), targetPos, offsetSide ) );
|
||||||
if( !isPeripheralBlockedOnSide( localDir ) )
|
}
|
||||||
{
|
|
||||||
IPeripheral peripheral = Peripherals.getPeripheral( getLevel(), offset, offsetSide, invalidate[dir.ordinal()] );
|
private void refreshPeripheral( @Nonnull ServerComputer computer, Direction dir )
|
||||||
computer.setPeripheral( localDir, peripheral );
|
{
|
||||||
}
|
invalidSides &= ~(1 << dir.ordinal());
|
||||||
|
|
||||||
|
ComputerSide localDir = remapToLocalSide( dir );
|
||||||
|
if( isPeripheralBlockedOnSide( localDir ) ) return;
|
||||||
|
|
||||||
|
Direction offsetSide = dir.getOpposite();
|
||||||
|
IPeripheral peripheral = Peripherals.getPeripheral( getLevel(), getBlockPos().relative( dir ), offsetSide, invalidate[dir.ordinal()] );
|
||||||
|
computer.setPeripheral( localDir, peripheral );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateInputsImmediately()
|
||||||
|
{
|
||||||
|
ServerComputer computer = getServerComputer();
|
||||||
|
if( computer != null ) updateInputsImmediately( computer );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the redstone input for an adjacent block.
|
* Update all redstone and peripherals.
|
||||||
*
|
*
|
||||||
* @param world The world we exist in
|
* This should only be really be called when the computer is being ticked (though there are some cases where it
|
||||||
* @param pos The position of the neighbour
|
* won't be), as peripheral scanning requires adjacent tiles to be in a "correct" state - which may not be the case
|
||||||
* @param side The side we are reading from
|
* if they're still updating!
|
||||||
* @return The effective redstone power
|
*
|
||||||
* @see DiodeBlock#getInputSignal(Level, BlockPos, BlockState)
|
* @param computer The current computer instance.
|
||||||
*/
|
*/
|
||||||
protected static int getRedstoneInput( Level world, BlockPos pos, Direction side )
|
private void updateInputsImmediately( @Nonnull ServerComputer computer )
|
||||||
{
|
{
|
||||||
int power = world.getSignal( pos, side );
|
BlockPos pos = getBlockPos();
|
||||||
if( power >= 15 ) return power;
|
|
||||||
|
|
||||||
BlockState neighbour = world.getBlockState( pos );
|
|
||||||
return neighbour.getBlock() == Blocks.REDSTONE_WIRE
|
|
||||||
? Math.max( power, neighbour.getValue( RedStoneWireBlock.POWER ) )
|
|
||||||
: power;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateInput()
|
|
||||||
{
|
|
||||||
if( getLevel() == null || getLevel().isClientSide ) return;
|
|
||||||
|
|
||||||
// Update all sides
|
|
||||||
ServerComputer computer = getServerComputer();
|
|
||||||
if( computer == null ) return;
|
|
||||||
|
|
||||||
BlockPos pos = computer.getPosition();
|
|
||||||
for( Direction dir : DirectionUtil.FACINGS )
|
for( Direction dir : DirectionUtil.FACINGS )
|
||||||
{
|
{
|
||||||
updateSideInput( computer, dir, pos.relative( dir ) );
|
updateRedstoneInput( computer, dir, pos.relative( dir ) );
|
||||||
|
refreshPeripheral( computer, dir );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateInput( BlockPos neighbour )
|
private void updateInputAt( @Nonnull BlockPos neighbour )
|
||||||
{
|
{
|
||||||
if( getLevel() == null || getLevel().isClientSide ) return;
|
|
||||||
|
|
||||||
ServerComputer computer = getServerComputer();
|
ServerComputer computer = getServerComputer();
|
||||||
if( computer == null ) return;
|
if( computer == null ) return;
|
||||||
|
|
||||||
for( Direction dir : DirectionUtil.FACINGS )
|
for( Direction dir : DirectionUtil.FACINGS )
|
||||||
{
|
{
|
||||||
BlockPos offset = worldPosition.relative( dir );
|
BlockPos offset = getBlockPos().relative( dir );
|
||||||
if( offset.equals( neighbour ) )
|
if( offset.equals( neighbour ) )
|
||||||
{
|
{
|
||||||
updateSideInput( computer, dir, offset );
|
updateRedstoneInput( computer, dir, offset );
|
||||||
|
invalidSides |= 1 << dir.ordinal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the position is not any adjacent one, update all inputs.
|
// If the position is not any adjacent one, update all inputs. This is pretty terrible, but some redstone mods
|
||||||
updateInput();
|
// handle this incorrectly.
|
||||||
}
|
BlockPos pos = getBlockPos();
|
||||||
|
for( Direction dir : DirectionUtil.FACINGS ) updateRedstoneInput( computer, dir, pos.relative( dir ) );
|
||||||
private void updateInput( Direction dir )
|
invalidSides = (1 << 6) - 1; // Mark all peripherals as dirty.
|
||||||
{
|
|
||||||
if( getLevel() == null || getLevel().isClientSide ) return;
|
|
||||||
|
|
||||||
ServerComputer computer = getServerComputer();
|
|
||||||
if( computer == null ) return;
|
|
||||||
|
|
||||||
updateSideInput( computer, dir, worldPosition.relative( dir ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the block's state and propagate redstone output.
|
||||||
|
*/
|
||||||
public void updateOutput()
|
public void updateOutput()
|
||||||
{
|
{
|
||||||
// Update redstone
|
|
||||||
updateBlock();
|
updateBlock();
|
||||||
for( Direction dir : DirectionUtil.FACINGS )
|
for( Direction dir : DirectionUtil.FACINGS )
|
||||||
{
|
{
|
||||||
@ -354,9 +350,10 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
|||||||
return family;
|
return family;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
public ServerComputer createServerComputer()
|
public ServerComputer createServerComputer()
|
||||||
{
|
{
|
||||||
if( getLevel().isClientSide ) return null;
|
if( getLevel().isClientSide ) throw new IllegalStateException( "Cannot access server computer on the client." );
|
||||||
|
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
if( instanceID < 0 )
|
if( instanceID < 0 )
|
||||||
@ -364,18 +361,21 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
|
|||||||
instanceID = ComputerCraft.serverComputerRegistry.getUnusedInstanceID();
|
instanceID = ComputerCraft.serverComputerRegistry.getUnusedInstanceID();
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
if( !ComputerCraft.serverComputerRegistry.contains( instanceID ) )
|
|
||||||
|
ServerComputer computer = ComputerCraft.serverComputerRegistry.get( instanceID );
|
||||||
|
if( computer == null )
|
||||||
{
|
{
|
||||||
ServerComputer computer = createComputer( instanceID, computerID );
|
computer = createComputer( instanceID, computerID );
|
||||||
ComputerCraft.serverComputerRegistry.add( instanceID, computer );
|
ComputerCraft.serverComputerRegistry.add( instanceID, computer );
|
||||||
fresh = true;
|
fresh = true;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( changed ) updateInput();
|
if( changed ) updateInputsImmediately( computer );
|
||||||
return ComputerCraft.serverComputerRegistry.get( instanceID );
|
return computer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public ServerComputer getServerComputer()
|
public ServerComputer getServerComputer()
|
||||||
{
|
{
|
||||||
return getLevel().isClientSide ? null : ComputerCraft.serverComputerRegistry.get( instanceID );
|
return getLevel().isClientSide ? null : ComputerCraft.serverComputerRegistry.get( instanceID );
|
||||||
|
@ -128,7 +128,7 @@ public class CommandBlockPeripheral implements IPeripheral, ICapabilityProvider
|
|||||||
public static void onCapability( AttachCapabilitiesEvent<BlockEntity> event )
|
public static void onCapability( AttachCapabilitiesEvent<BlockEntity> event )
|
||||||
{
|
{
|
||||||
BlockEntity tile = event.getObject();
|
BlockEntity tile = event.getObject();
|
||||||
if( tile instanceof CommandBlockEntity )
|
if( ComputerCraft.enableCommandBlock && tile instanceof CommandBlockEntity )
|
||||||
{
|
{
|
||||||
CommandBlockPeripheral peripheral = new CommandBlockPeripheral( (CommandBlockEntity) tile );
|
CommandBlockPeripheral peripheral = new CommandBlockPeripheral( (CommandBlockEntity) tile );
|
||||||
event.addCapability( CAP_ID, peripheral );
|
event.addCapability( CAP_ID, peripheral );
|
||||||
|
@ -18,18 +18,21 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
|||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
class GenericPeripheral implements IDynamicPeripheral
|
class GenericPeripheral implements IDynamicPeripheral
|
||||||
{
|
{
|
||||||
private final String type;
|
private final String type;
|
||||||
|
private final Set<String> additionalTypes;
|
||||||
private final BlockEntity tile;
|
private final BlockEntity tile;
|
||||||
private final List<SaturatedMethod> methods;
|
private final List<SaturatedMethod> methods;
|
||||||
|
|
||||||
GenericPeripheral( BlockEntity tile, String name, List<SaturatedMethod> methods )
|
GenericPeripheral( BlockEntity tile, String name, Set<String> additionalTypes, List<SaturatedMethod> methods )
|
||||||
{
|
{
|
||||||
ResourceLocation type = tile.getType().getRegistryName();
|
ResourceLocation type = tile.getType().getRegistryName();
|
||||||
this.tile = tile;
|
this.tile = tile;
|
||||||
this.type = name != null ? name : (type != null ? type.toString() : "unknown");
|
this.type = name != null ? name : (type != null ? type.toString() : "unknown");
|
||||||
|
this.additionalTypes = additionalTypes;
|
||||||
this.methods = methods;
|
this.methods = methods;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,6 +59,13 @@ class GenericPeripheral implements IDynamicPeripheral
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public Set<String> getAdditionalTypes()
|
||||||
|
{
|
||||||
|
return additionalTypes;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public Object getTarget()
|
public Object getTarget()
|
||||||
|
@ -9,6 +9,7 @@ import dan200.computercraft.api.peripheral.IPeripheral;
|
|||||||
import dan200.computercraft.api.peripheral.PeripheralType;
|
import dan200.computercraft.api.peripheral.PeripheralType;
|
||||||
import dan200.computercraft.core.asm.NamedMethod;
|
import dan200.computercraft.core.asm.NamedMethod;
|
||||||
import dan200.computercraft.core.asm.PeripheralMethod;
|
import dan200.computercraft.core.asm.PeripheralMethod;
|
||||||
|
import dan200.computercraft.shared.util.CapabilityUtil;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
@ -19,9 +20,7 @@ import net.minecraftforge.common.util.NonNullConsumer;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class GenericPeripheralProvider
|
public class GenericPeripheralProvider
|
||||||
{
|
{
|
||||||
@ -34,7 +33,7 @@ public class GenericPeripheralProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static IPeripheral getPeripheral( @Nonnull Level world, @Nonnull BlockPos pos, @Nonnull Direction side, NonNullConsumer<LazyOptional<IPeripheral>> invalidate )
|
public static IPeripheral getPeripheral( @Nonnull Level world, @Nonnull BlockPos pos, @Nonnull Direction side, NonNullConsumer<Object> invalidate )
|
||||||
{
|
{
|
||||||
BlockEntity tile = world.getBlockEntity( pos );
|
BlockEntity tile = world.getBlockEntity( pos );
|
||||||
if( tile == null ) return null;
|
if( tile == null ) return null;
|
||||||
@ -52,7 +51,7 @@ public class GenericPeripheralProvider
|
|||||||
if( capabilityMethods.isEmpty() ) return;
|
if( capabilityMethods.isEmpty() ) return;
|
||||||
|
|
||||||
saturated.addMethods( contents, capabilityMethods );
|
saturated.addMethods( contents, capabilityMethods );
|
||||||
wrapper.addListener( cast( invalidate ) );
|
CapabilityUtil.addListener( wrapper, invalidate );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,15 +60,16 @@ public class GenericPeripheralProvider
|
|||||||
|
|
||||||
private static class GenericPeripheralBuilder
|
private static class GenericPeripheralBuilder
|
||||||
{
|
{
|
||||||
String name;
|
private String name;
|
||||||
final ArrayList<SaturatedMethod> methods = new ArrayList<>( 0 );
|
private final Set<String> additionalTypes = new HashSet<>( 0 );
|
||||||
|
private final ArrayList<SaturatedMethod> methods = new ArrayList<>( 0 );
|
||||||
|
|
||||||
IPeripheral toPeripheral( BlockEntity tile )
|
IPeripheral toPeripheral( BlockEntity tile )
|
||||||
{
|
{
|
||||||
if( methods.isEmpty() ) return null;
|
if( methods.isEmpty() ) return null;
|
||||||
|
|
||||||
methods.trimToSize();
|
methods.trimToSize();
|
||||||
return new GenericPeripheral( tile, name, methods );
|
return new GenericPeripheral( tile, name, additionalTypes, methods );
|
||||||
}
|
}
|
||||||
|
|
||||||
void addMethods( Object target, List<NamedMethod<PeripheralMethod>> methods )
|
void addMethods( Object target, List<NamedMethod<PeripheralMethod>> methods )
|
||||||
@ -88,13 +88,8 @@ public class GenericPeripheralProvider
|
|||||||
String name = type.getPrimaryType();
|
String name = type.getPrimaryType();
|
||||||
if( this.name == null || this.name.compareTo( name ) > 0 ) this.name = name;
|
if( this.name == null || this.name.compareTo( name ) > 0 ) this.name = name;
|
||||||
}
|
}
|
||||||
|
if( type != null ) additionalTypes.addAll( type.getAdditionalTypes() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings( { "unchecked", "rawtypes" } )
|
|
||||||
private static <T> NonNullConsumer<T> cast( NonNullConsumer<?> consumer )
|
|
||||||
{
|
|
||||||
return (NonNullConsumer) consumer;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,9 @@
|
|||||||
package dan200.computercraft.shared.peripheral.generic.methods;
|
package dan200.computercraft.shared.peripheral.generic.methods;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.api.lua.GenericSource;
|
|
||||||
import dan200.computercraft.api.lua.LuaFunction;
|
import dan200.computercraft.api.lua.LuaFunction;
|
||||||
|
import dan200.computercraft.api.peripheral.GenericPeripheral;
|
||||||
|
import dan200.computercraft.api.peripheral.PeripheralType;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraftforge.energy.IEnergyStorage;
|
import net.minecraftforge.energy.IEnergyStorage;
|
||||||
|
|
||||||
@ -25,8 +26,15 @@ import javax.annotation.Nonnull;
|
|||||||
*
|
*
|
||||||
* @cc.module energy_storage
|
* @cc.module energy_storage
|
||||||
*/
|
*/
|
||||||
public class EnergyMethods implements GenericSource
|
public class EnergyMethods implements GenericPeripheral
|
||||||
{
|
{
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public PeripheralType getType()
|
||||||
|
{
|
||||||
|
return PeripheralType.ofAdditional( "energy_storage" );
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public ResourceLocation id()
|
public ResourceLocation id()
|
||||||
|
@ -6,13 +6,15 @@
|
|||||||
package dan200.computercraft.shared.peripheral.generic.methods;
|
package dan200.computercraft.shared.peripheral.generic.methods;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.api.lua.GenericSource;
|
|
||||||
import dan200.computercraft.api.lua.LuaException;
|
import dan200.computercraft.api.lua.LuaException;
|
||||||
import dan200.computercraft.api.lua.LuaFunction;
|
import dan200.computercraft.api.lua.LuaFunction;
|
||||||
|
import dan200.computercraft.api.peripheral.GenericPeripheral;
|
||||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
|
import dan200.computercraft.api.peripheral.PeripheralType;
|
||||||
import dan200.computercraft.shared.peripheral.generic.data.FluidData;
|
import dan200.computercraft.shared.peripheral.generic.data.FluidData;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.material.Fluid;
|
import net.minecraft.world.level.material.Fluid;
|
||||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
@ -34,8 +36,15 @@ import static dan200.computercraft.shared.peripheral.generic.methods.ArgumentHel
|
|||||||
*
|
*
|
||||||
* @cc.module fluid_storage
|
* @cc.module fluid_storage
|
||||||
*/
|
*/
|
||||||
public class FluidMethods implements GenericSource
|
public class FluidMethods implements GenericPeripheral
|
||||||
{
|
{
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public PeripheralType getType()
|
||||||
|
{
|
||||||
|
return PeripheralType.ofAdditional( "fluid_storage" );
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public ResourceLocation id()
|
public ResourceLocation id()
|
||||||
@ -155,13 +164,15 @@ public class FluidMethods implements GenericSource
|
|||||||
@Nullable
|
@Nullable
|
||||||
private static IFluidHandler extractHandler( @Nullable Object object )
|
private static IFluidHandler extractHandler( @Nullable Object object )
|
||||||
{
|
{
|
||||||
if( object instanceof ICapabilityProvider )
|
if( object instanceof BlockEntity blockEntity && blockEntity.isRemoved() ) return null;
|
||||||
|
|
||||||
|
if( object instanceof ICapabilityProvider provider )
|
||||||
{
|
{
|
||||||
LazyOptional<IFluidHandler> cap = ((ICapabilityProvider) object).getCapability( CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY );
|
LazyOptional<IFluidHandler> cap = provider.getCapability( CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY );
|
||||||
if( cap.isPresent() ) return cap.orElseThrow( NullPointerException::new );
|
if( cap.isPresent() ) return cap.orElseThrow( NullPointerException::new );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( object instanceof IFluidHandler ) return (IFluidHandler) object;
|
if( object instanceof IFluidHandler handler ) return handler;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,16 +6,18 @@
|
|||||||
package dan200.computercraft.shared.peripheral.generic.methods;
|
package dan200.computercraft.shared.peripheral.generic.methods;
|
||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.api.lua.GenericSource;
|
|
||||||
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.api.lua.LuaFunction;
|
import dan200.computercraft.api.lua.LuaFunction;
|
||||||
|
import dan200.computercraft.api.peripheral.GenericPeripheral;
|
||||||
import dan200.computercraft.api.peripheral.IComputerAccess;
|
import dan200.computercraft.api.peripheral.IComputerAccess;
|
||||||
import dan200.computercraft.api.peripheral.IPeripheral;
|
import dan200.computercraft.api.peripheral.IPeripheral;
|
||||||
|
import dan200.computercraft.api.peripheral.PeripheralType;
|
||||||
import dan200.computercraft.shared.peripheral.generic.data.ItemData;
|
import dan200.computercraft.shared.peripheral.generic.data.ItemData;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.Container;
|
import net.minecraft.world.Container;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
import net.minecraftforge.items.CapabilityItemHandler;
|
import net.minecraftforge.items.CapabilityItemHandler;
|
||||||
@ -36,8 +38,15 @@ import static dan200.computercraft.shared.peripheral.generic.methods.ArgumentHel
|
|||||||
*
|
*
|
||||||
* @cc.module inventory
|
* @cc.module inventory
|
||||||
*/
|
*/
|
||||||
public class InventoryMethods implements GenericSource
|
public class InventoryMethods implements GenericPeripheral
|
||||||
{
|
{
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public PeripheralType getType()
|
||||||
|
{
|
||||||
|
return PeripheralType.ofAdditional( "inventory" );
|
||||||
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public ResourceLocation id()
|
public ResourceLocation id()
|
||||||
@ -259,14 +268,16 @@ public class InventoryMethods implements GenericSource
|
|||||||
@Nullable
|
@Nullable
|
||||||
private static IItemHandler extractHandler( @Nullable Object object )
|
private static IItemHandler extractHandler( @Nullable Object object )
|
||||||
{
|
{
|
||||||
if( object instanceof ICapabilityProvider )
|
if( object instanceof BlockEntity blockEntity && blockEntity.isRemoved() ) return null;
|
||||||
|
|
||||||
|
if( object instanceof ICapabilityProvider provider )
|
||||||
{
|
{
|
||||||
LazyOptional<IItemHandler> cap = ((ICapabilityProvider) object).getCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY );
|
LazyOptional<IItemHandler> cap = provider.getCapability( CapabilityItemHandler.ITEM_HANDLER_CAPABILITY );
|
||||||
if( cap.isPresent() ) return cap.orElseThrow( NullPointerException::new );
|
if( cap.isPresent() ) return cap.orElseThrow( NullPointerException::new );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( object instanceof IItemHandler ) return (IItemHandler) object;
|
if( object instanceof IItemHandler handler ) return handler;
|
||||||
if( object instanceof Container ) return new InvWrapper( (Container) object );
|
if( object instanceof Container container ) return new InvWrapper( container );
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,8 +77,9 @@ public class TileCable extends TileGeneric
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean invalidPeripheral;
|
||||||
private boolean peripheralAccessAllowed;
|
private boolean peripheralAccessAllowed;
|
||||||
private final WiredModemLocalPeripheral peripheral = new WiredModemLocalPeripheral( this::refreshPeripheral );
|
private final WiredModemLocalPeripheral peripheral = new WiredModemLocalPeripheral( this::queueRefreshPeripheral );
|
||||||
|
|
||||||
private boolean destroyed = false;
|
private boolean destroyed = false;
|
||||||
|
|
||||||
@ -234,12 +235,20 @@ public class TileCable extends TileGeneric
|
|||||||
if( !level.isClientSide && peripheralAccessAllowed )
|
if( !level.isClientSide && peripheralAccessAllowed )
|
||||||
{
|
{
|
||||||
Direction facing = getDirection();
|
Direction facing = getDirection();
|
||||||
if( getBlockPos().relative( facing ).equals( neighbour ) ) refreshPeripheral();
|
if( getBlockPos().relative( facing ).equals( neighbour ) ) queueRefreshPeripheral();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void queueRefreshPeripheral()
|
||||||
|
{
|
||||||
|
if( invalidPeripheral ) return;
|
||||||
|
invalidPeripheral = true;
|
||||||
|
TickScheduler.schedule( this );
|
||||||
|
}
|
||||||
|
|
||||||
private void refreshPeripheral()
|
private void refreshPeripheral()
|
||||||
{
|
{
|
||||||
|
invalidPeripheral = false;
|
||||||
if( level != null && !isRemoved() && peripheral.attach( level, getBlockPos(), getDirection() ) )
|
if( level != null && !isRemoved() && peripheral.attach( level, getBlockPos(), getDirection() ) )
|
||||||
{
|
{
|
||||||
updateConnectedPeripherals();
|
updateConnectedPeripherals();
|
||||||
@ -310,6 +319,8 @@ public class TileCable extends TileGeneric
|
|||||||
{
|
{
|
||||||
if( getLevel().isClientSide ) return;
|
if( getLevel().isClientSide ) return;
|
||||||
|
|
||||||
|
if( invalidPeripheral ) refreshPeripheral();
|
||||||
|
|
||||||
if( modem.getModemState().pollChanged() ) updateBlockState();
|
if( modem.getModemState().pollChanged() ) updateBlockState();
|
||||||
|
|
||||||
if( !connectionsFormed )
|
if( !connectionsFormed )
|
||||||
|
@ -108,13 +108,15 @@ public class TileWiredModemFull extends TileGeneric
|
|||||||
|
|
||||||
private final NonNullConsumer<LazyOptional<IWiredElement>> connectedNodeChanged = x -> connectionsChanged();
|
private final NonNullConsumer<LazyOptional<IWiredElement>> connectedNodeChanged = x -> connectionsChanged();
|
||||||
|
|
||||||
|
private int invalidSides = 0;
|
||||||
|
|
||||||
public TileWiredModemFull( BlockEntityType<TileWiredModemFull> type, BlockPos pos, BlockState state )
|
public TileWiredModemFull( BlockEntityType<TileWiredModemFull> type, BlockPos pos, BlockState state )
|
||||||
{
|
{
|
||||||
super( type, pos, state );
|
super( type, pos, state );
|
||||||
for( int i = 0; i < peripherals.length; i++ )
|
for( int i = 0; i < peripherals.length; i++ )
|
||||||
{
|
{
|
||||||
Direction facing = Direction.from3DDataValue( i );
|
Direction facing = Direction.from3DDataValue( i );
|
||||||
peripherals[i] = new WiredModemLocalPeripheral( () -> refreshPeripheral( facing ) );
|
peripherals[i] = new WiredModemLocalPeripheral( () -> queueRefreshPeripheral( facing ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,13 +175,20 @@ public class TileWiredModemFull extends TileGeneric
|
|||||||
{
|
{
|
||||||
for( Direction facing : DirectionUtil.FACINGS )
|
for( Direction facing : DirectionUtil.FACINGS )
|
||||||
{
|
{
|
||||||
if( getBlockPos().relative( facing ).equals( neighbour ) ) refreshPeripheral( facing );
|
if( getBlockPos().relative( facing ).equals( neighbour ) ) queueRefreshPeripheral( facing );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void queueRefreshPeripheral( @Nonnull Direction facing )
|
||||||
|
{
|
||||||
|
if( invalidSides == 0 ) TickScheduler.schedule( this );
|
||||||
|
invalidSides |= 1 << facing.ordinal();
|
||||||
|
}
|
||||||
|
|
||||||
private void refreshPeripheral( @Nonnull Direction facing )
|
private void refreshPeripheral( @Nonnull Direction facing )
|
||||||
{
|
{
|
||||||
|
invalidSides &= ~(1 << facing.ordinal());
|
||||||
WiredModemLocalPeripheral peripheral = peripherals[facing.ordinal()];
|
WiredModemLocalPeripheral peripheral = peripherals[facing.ordinal()];
|
||||||
if( level != null && !isRemoved() && peripheral.attach( level, getBlockPos(), facing ) )
|
if( level != null && !isRemoved() && peripheral.attach( level, getBlockPos(), facing ) )
|
||||||
{
|
{
|
||||||
@ -262,6 +271,14 @@ public class TileWiredModemFull extends TileGeneric
|
|||||||
{
|
{
|
||||||
if( getLevel().isClientSide ) return;
|
if( getLevel().isClientSide ) return;
|
||||||
|
|
||||||
|
if( invalidSides != 0 )
|
||||||
|
{
|
||||||
|
for( Direction direction : DirectionUtil.FACINGS )
|
||||||
|
{
|
||||||
|
if( (invalidSides & (1 << direction.ordinal())) != 0 ) refreshPeripheral( direction );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( modemState.pollChanged() ) updateBlockState();
|
if( modemState.pollChanged() ) updateBlockState();
|
||||||
|
|
||||||
if( !connectionsFormed )
|
if( !connectionsFormed )
|
||||||
|
@ -15,7 +15,6 @@ import net.minecraft.nbt.CompoundTag;
|
|||||||
import net.minecraft.nbt.Tag;
|
import net.minecraft.nbt.Tag;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
|
||||||
import net.minecraftforge.common.util.NonNullConsumer;
|
import net.minecraftforge.common.util.NonNullConsumer;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -38,7 +37,7 @@ public final class WiredModemLocalPeripheral
|
|||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
private IPeripheral peripheral;
|
private IPeripheral peripheral;
|
||||||
private final NonNullConsumer<LazyOptional<IPeripheral>> invalidate;
|
private final NonNullConsumer<Object> invalidate;
|
||||||
|
|
||||||
public WiredModemLocalPeripheral( @Nonnull Runnable invalidate )
|
public WiredModemLocalPeripheral( @Nonnull Runnable invalidate )
|
||||||
{
|
{
|
||||||
|
@ -21,6 +21,7 @@ import dan200.computercraft.core.apis.PeripheralAPI;
|
|||||||
import dan200.computercraft.core.asm.PeripheralMethod;
|
import dan200.computercraft.core.asm.PeripheralMethod;
|
||||||
import dan200.computercraft.shared.peripheral.modem.ModemPeripheral;
|
import dan200.computercraft.shared.peripheral.modem.ModemPeripheral;
|
||||||
import dan200.computercraft.shared.peripheral.modem.ModemState;
|
import dan200.computercraft.shared.peripheral.modem.ModemState;
|
||||||
|
import dan200.computercraft.shared.util.LuaUtil;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -118,13 +119,35 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW
|
|||||||
* @param name The peripheral's name.
|
* @param name The peripheral's name.
|
||||||
* @return The peripheral's name.
|
* @return The peripheral's name.
|
||||||
* @cc.treturn string|nil The peripheral's type, or {@code nil} if it is not present.
|
* @cc.treturn string|nil The peripheral's type, or {@code nil} if it is not present.
|
||||||
|
* @cc.changed 1.99 Peripherals can have multiple types - this function returns multiple values.
|
||||||
* @see PeripheralAPI#getType
|
* @see PeripheralAPI#getType
|
||||||
*/
|
*/
|
||||||
@LuaFunction
|
@LuaFunction
|
||||||
public final Object[] getTypeRemote( IComputerAccess computer, String name )
|
public final Object[] getTypeRemote( IComputerAccess computer, String name )
|
||||||
{
|
{
|
||||||
RemotePeripheralWrapper wrapper = getWrapper( computer, name );
|
RemotePeripheralWrapper wrapper = getWrapper( computer, name );
|
||||||
return wrapper != null ? new Object[] { wrapper.getType() } : null;
|
return wrapper == null ? null : LuaUtil.consArray( wrapper.getType(), wrapper.getAdditionalTypes() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check a peripheral is of a particular type.
|
||||||
|
*
|
||||||
|
* <blockquote><strong>Important:</strong> This function only appears on wired modems. Check {@link #isWireless}
|
||||||
|
* returns false before calling it.</blockquote>
|
||||||
|
*
|
||||||
|
* @param computer The calling computer.
|
||||||
|
* @param name The peripheral's name.
|
||||||
|
* @param type The type to check.
|
||||||
|
* @return The peripheral's name.
|
||||||
|
* @cc.treturn boolean|nil If a peripheral has a particular type, or {@literal nil} if it is not present.
|
||||||
|
* @cc.since 1.99
|
||||||
|
* @see PeripheralAPI#getType
|
||||||
|
*/
|
||||||
|
@LuaFunction
|
||||||
|
public final Object[] hasTypeRemote( IComputerAccess computer, String name, String type )
|
||||||
|
{
|
||||||
|
RemotePeripheralWrapper wrapper = getWrapper( computer, name );
|
||||||
|
return wrapper == null ? null : new Object[] { wrapper.getType().equals( type ) || wrapper.getAdditionalTypes().contains( getType() ) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -307,6 +330,7 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW
|
|||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
private final String type;
|
private final String type;
|
||||||
|
private final Set<String> additionalTypes;
|
||||||
private final Map<String, PeripheralMethod> methodMap;
|
private final Map<String, PeripheralMethod> methodMap;
|
||||||
|
|
||||||
private volatile boolean attached;
|
private volatile boolean attached;
|
||||||
@ -320,6 +344,7 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
||||||
type = Objects.requireNonNull( peripheral.getType(), "Peripheral type cannot be null" );
|
type = Objects.requireNonNull( peripheral.getType(), "Peripheral type cannot be null" );
|
||||||
|
additionalTypes = peripheral.getAdditionalTypes();
|
||||||
methodMap = PeripheralAPI.getMethods( peripheral );
|
methodMap = PeripheralAPI.getMethods( peripheral );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,6 +378,11 @@ public abstract class WiredModemPeripheral extends ModemPeripheral implements IW
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<String> getAdditionalTypes()
|
||||||
|
{
|
||||||
|
return additionalTypes;
|
||||||
|
}
|
||||||
|
|
||||||
public Collection<String> getMethodNames()
|
public Collection<String> getMethodNames()
|
||||||
{
|
{
|
||||||
return methodMap.keySet();
|
return methodMap.keySet();
|
||||||
|
@ -331,8 +331,10 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
|
|||||||
{
|
{
|
||||||
if( dir.getAxis() == Direction.Axis.Y ) dir = Direction.NORTH;
|
if( dir.getAxis() == Direction.Axis.Y ) dir = Direction.NORTH;
|
||||||
level.setBlockAndUpdate( worldPosition, getBlockState().setValue( BlockTurtle.FACING, dir ) );
|
level.setBlockAndUpdate( worldPosition, getBlockState().setValue( BlockTurtle.FACING, dir ) );
|
||||||
|
|
||||||
updateOutput();
|
updateOutput();
|
||||||
updateInput();
|
updateInputsImmediately();
|
||||||
|
|
||||||
onTileEntityChange();
|
onTileEntityChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,16 +332,17 @@ public class TurtleBrain implements ITurtleAccess
|
|||||||
// Copy the old turtle state into the new turtle
|
// Copy the old turtle state into the new turtle
|
||||||
newTurtle.setLevel( world );
|
newTurtle.setLevel( world );
|
||||||
newTurtle.transferStateFrom( oldOwner );
|
newTurtle.transferStateFrom( oldOwner );
|
||||||
newTurtle.createServerComputer().setLevel( world );
|
|
||||||
newTurtle.createServerComputer().setPosition( pos );
|
ServerComputer computer = newTurtle.createServerComputer();
|
||||||
|
computer.setLevel( world );
|
||||||
|
computer.setPosition( pos );
|
||||||
|
|
||||||
// Remove the old turtle
|
// Remove the old turtle
|
||||||
oldWorld.removeBlock( oldPos, false );
|
oldWorld.removeBlock( oldPos, false );
|
||||||
|
|
||||||
// Make sure everybody knows about it
|
// Make sure everybody knows about it
|
||||||
newTurtle.updateBlock();
|
|
||||||
newTurtle.updateInput();
|
|
||||||
newTurtle.updateOutput();
|
newTurtle.updateOutput();
|
||||||
|
newTurtle.updateInputsImmediately();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -613,16 +614,16 @@ public class TurtleBrain implements ITurtleAccess
|
|||||||
@Override
|
@Override
|
||||||
public void setUpgrade( @Nonnull TurtleSide side, ITurtleUpgrade upgrade )
|
public void setUpgrade( @Nonnull TurtleSide side, ITurtleUpgrade upgrade )
|
||||||
{
|
{
|
||||||
if( !setUpgradeDirect( side, upgrade ) ) return;
|
if( !setUpgradeDirect( side, upgrade ) || owner.getLevel() == null ) return;
|
||||||
|
|
||||||
// This is a separate function to avoid updating the block when reading the NBT. We don't need to do this as
|
// This is a separate function to avoid updating the block when reading the NBT. We don't need to do this as
|
||||||
// either the block is newly placed (and so won't have changed) or is being updated with /data, which calls
|
// either the block is newly placed (and so won't have changed) or is being updated with /data, which calls
|
||||||
// updateBlock for us.
|
// updateBlock for us.
|
||||||
if( owner.getLevel() != null )
|
owner.updateBlock();
|
||||||
{
|
|
||||||
owner.updateBlock();
|
// Recompute peripherals in case an upgrade being removed has exposed a new peripheral.
|
||||||
owner.updateInput();
|
// TODO: Only update peripherals, or even only two sides?
|
||||||
}
|
owner.updateInputsImmediately();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean setUpgradeDirect( @Nonnull TurtleSide side, ITurtleUpgrade upgrade )
|
private boolean setUpgradeDirect( @Nonnull TurtleSide side, ITurtleUpgrade upgrade )
|
||||||
@ -644,7 +645,7 @@ public class TurtleBrain implements ITurtleAccess
|
|||||||
if( upgrade != null ) upgrades.put( side, upgrade );
|
if( upgrade != null ) upgrades.put( side, upgrade );
|
||||||
|
|
||||||
// Notify clients and create peripherals
|
// Notify clients and create peripherals
|
||||||
if( owner.getLevel() != null )
|
if( owner.getLevel() != null && !owner.getLevel().isClientSide )
|
||||||
{
|
{
|
||||||
updatePeripherals( owner.createServerComputer() );
|
updatePeripherals( owner.createServerComputer() );
|
||||||
}
|
}
|
||||||
|
@ -35,12 +35,20 @@ public final class CapabilityUtil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T> void addListener( LazyOptional<T> p, NonNullConsumer<? super LazyOptional<T>> invalidate )
|
||||||
|
{
|
||||||
|
// We can make this safe with invalidate::accept, but then we're allocating it's just kind of absurd.
|
||||||
|
@SuppressWarnings( "unchecked" )
|
||||||
|
NonNullConsumer<LazyOptional<T>> safeInvalidate = (NonNullConsumer<LazyOptional<T>>) invalidate;
|
||||||
|
p.addListener( safeInvalidate );
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static <T> T unwrap( LazyOptional<T> p, NonNullConsumer<LazyOptional<T>> invalidate )
|
public static <T> T unwrap( LazyOptional<T> p, NonNullConsumer<? super LazyOptional<T>> invalidate )
|
||||||
{
|
{
|
||||||
if( !p.isPresent() ) return null;
|
if( !p.isPresent() ) return null;
|
||||||
|
|
||||||
p.addListener( invalidate );
|
addListener( p, invalidate );
|
||||||
return p.orElseThrow( NullPointerException::new );
|
return p.orElseThrow( NullPointerException::new );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
23
src/main/java/dan200/computercraft/shared/util/LuaUtil.java
Normal file
23
src/main/java/dan200/computercraft/shared/util/LuaUtil.java
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||||
|
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
|
||||||
|
* Send enquiries to dratcliffe@gmail.com
|
||||||
|
*/
|
||||||
|
package dan200.computercraft.shared.util;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public class LuaUtil
|
||||||
|
{
|
||||||
|
public static Object[] consArray( Object value, Collection<?> rest )
|
||||||
|
{
|
||||||
|
if( rest.isEmpty() ) return new Object[] { value };
|
||||||
|
|
||||||
|
// I'm not proud of this code.
|
||||||
|
Object[] out = new Object[rest.size() + 1];
|
||||||
|
out[0] = value;
|
||||||
|
int i = 1;
|
||||||
|
for( Object additionalType : rest ) out[i++] = additionalType;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,9 @@ package dan200.computercraft.shared.util;
|
|||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.DiodeBlock;
|
||||||
|
import net.minecraft.world.level.block.RedStoneWireBlock;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraftforge.event.ForgeEventFactory;
|
import net.minecraftforge.event.ForgeEventFactory;
|
||||||
|
|
||||||
@ -15,6 +18,30 @@ import java.util.EnumSet;
|
|||||||
|
|
||||||
public final class RedstoneUtil
|
public final class RedstoneUtil
|
||||||
{
|
{
|
||||||
|
private RedstoneUtil()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the redstone input for an adjacent block.
|
||||||
|
*
|
||||||
|
* @param world The world we exist in
|
||||||
|
* @param pos The position of the neighbour
|
||||||
|
* @param side The side we are reading from
|
||||||
|
* @return The effective redstone power
|
||||||
|
* @see DiodeBlock#getInputSignal(Level, BlockPos, BlockState)
|
||||||
|
*/
|
||||||
|
public static int getRedstoneInput( Level world, BlockPos pos, Direction side )
|
||||||
|
{
|
||||||
|
int power = world.getSignal( pos, side );
|
||||||
|
if( power >= 15 ) return power;
|
||||||
|
|
||||||
|
BlockState neighbour = world.getBlockState( pos );
|
||||||
|
return neighbour.getBlock() == Blocks.REDSTONE_WIRE
|
||||||
|
? Math.max( power, neighbour.getValue( RedStoneWireBlock.POWER ) )
|
||||||
|
: power;
|
||||||
|
}
|
||||||
|
|
||||||
public static void propagateRedstoneOutput( Level world, BlockPos pos, Direction side )
|
public static void propagateRedstoneOutput( Level world, BlockPos pos, Direction side )
|
||||||
{
|
{
|
||||||
// Propagate ordinary output. See BlockRedstoneDiode.notifyNeighbors
|
// Propagate ordinary output. See BlockRedstoneDiode.notifyNeighbors
|
||||||
|
@ -68,7 +68,7 @@ end
|
|||||||
-- @{paintutils.drawImage}, or `nil` if the file does not exist.
|
-- @{paintutils.drawImage}, or `nil` if the file does not exist.
|
||||||
-- @usage Load an image and draw it.
|
-- @usage Load an image and draw it.
|
||||||
--
|
--
|
||||||
-- local image = paintutils.loadImage("test-image.nfp")
|
-- local image = paintutils.loadImage("data/example.nfp")
|
||||||
-- paintutils.drawImage(image, term.getCursorPos())
|
-- paintutils.drawImage(image, term.getCursorPos())
|
||||||
function loadImage(path)
|
function loadImage(path)
|
||||||
expect(1, path, "string")
|
expect(1, path, "string")
|
||||||
|
@ -1,18 +1,90 @@
|
|||||||
--- The Peripheral API is for interacting with peripherals connected to the
|
--[[- Peripherals are blocks (or turtle and pocket computer upgrades) which can
|
||||||
-- computer, such as the Disk Drive, the Advanced Monitor and Monitor.
|
be controlled by a computer. For instance, the @{speaker} peripheral allows a
|
||||||
--
|
computer to play music and the @{monitor} peripheral allows you to display text
|
||||||
-- Each peripheral block has a name, either referring to the side the peripheral
|
in the world.
|
||||||
-- can be found on, or a name on an adjacent wired network.
|
|
||||||
--
|
## Referencing peripherals
|
||||||
-- If the peripheral is next to the computer, its side is either `front`,
|
|
||||||
-- `back`, `left`, `right`, `top` or `bottom`. If the peripheral is attached by
|
Computers can interact with adjacent peripherals. Each peripheral is given a
|
||||||
-- a cable, its side will follow the format `type_id`, for example `printer_0`.
|
name based on which direction it is in. For instance, a disk drive below your
|
||||||
--
|
computer will be called `"bottom"` in your Lua code, one to the left called
|
||||||
-- Peripheral functions are called *methods*, a term borrowed from Java.
|
`"left"` , and so on for all 6 directions (`"bottom"`, `"top"`, `"left"`,
|
||||||
--
|
`"right"`, `"front"`, `"back"`).
|
||||||
-- @module peripheral
|
|
||||||
-- @since 1.3
|
You can list the names of all peripherals with the `peripherals` program, or the
|
||||||
-- @changed 1.51 Add support for wired modems.
|
@{peripheral.getNames} function.
|
||||||
|
|
||||||
|
It's also possible to use peripherals which are further away from your computer
|
||||||
|
through the use of @{modem|Wired Modems}. Place one modem against your computer,
|
||||||
|
run Networking Cable to your peripheral, and then place another modem against
|
||||||
|
that block. You can then right click the modem to use (or *attach*) the
|
||||||
|
peripheral. This will print a peripheral name to chat, which can then be used
|
||||||
|
just like a direction name to access the peripheral. You can click on the message
|
||||||
|
to copy the name to your clipboard.
|
||||||
|
|
||||||
|
## Using peripherals
|
||||||
|
|
||||||
|
Once you have the name of a peripheral, you can call functions on it using the
|
||||||
|
@{peripheral.call} function. This takes the name of our peripheral, the name of
|
||||||
|
the function we want to call, and then its arguments.
|
||||||
|
|
||||||
|
> Some bits of the peripheral API call peripheral functions *methods* instead
|
||||||
|
> (for example, the @{peripheral.getMethods} function). Don't worry, they're the
|
||||||
|
> same thing!
|
||||||
|
|
||||||
|
Let's say we have a monitor above our computer (and so "top") and want to
|
||||||
|
@{monitor.write|write some text to it}. We'd write the following:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
peripheral.call("top", "write", "This is displayed on a monitor!")
|
||||||
|
```
|
||||||
|
|
||||||
|
Once you start calling making a couple of peripheral calls this can get very
|
||||||
|
repetitive, and so we can @{peripheral.wrap|wrap} a peripheral. This builds a
|
||||||
|
table of all the peripheral's functions so you can use it like an API or module.
|
||||||
|
|
||||||
|
For instance, we could have written the above example as follows:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local my_monitor = peripheral.wrap("top")
|
||||||
|
my_monitor.write("This is displayed on a monitor!")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Finding peripherals
|
||||||
|
|
||||||
|
Sometimes when you're writing a program you don't care what a peripheral is
|
||||||
|
called, you just need to know it's there. For instance, if you're writing a
|
||||||
|
music player, you just need a speaker - it doesn't matter if it's above or below
|
||||||
|
the computer.
|
||||||
|
|
||||||
|
Thankfully there's a quick way to do this: @{peripheral.find}. This takes a
|
||||||
|
*peripheral type* and returns all the attached peripherals which are of this
|
||||||
|
type.
|
||||||
|
|
||||||
|
What is a peripheral type though? This is a string which describes what a
|
||||||
|
peripheral is, and so what functions are available on it. For instance, speakers
|
||||||
|
are just called `"speaker"`, and monitors `"monitor"`. Some peripherals might
|
||||||
|
have more than one type; a Minecraft chest is both a `"minecraft:chest"` and
|
||||||
|
`"inventory"`.
|
||||||
|
|
||||||
|
You can get all the types a peripheral has with @{peripheral.getType}, and check
|
||||||
|
a peripheral is a specific type with @{peripheral.hasType}.
|
||||||
|
|
||||||
|
To return to our original example, let's use @{peripheral.find} to find an
|
||||||
|
attached speaker:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local speaker = peripheral.find("speaker")
|
||||||
|
speaker.playNote("harp")
|
||||||
|
```
|
||||||
|
|
||||||
|
@module peripheral
|
||||||
|
@see event!peripheral This event is fired whenever a new peripheral is attached.
|
||||||
|
@see event!peripheral_detach This event is fired whenever a peripheral is detached.
|
||||||
|
@since 1.3
|
||||||
|
@changed 1.51 Add support for wired modems.
|
||||||
|
@changed 1.99 Peripherals can have multiple types.
|
||||||
|
]]
|
||||||
|
|
||||||
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
local expect = dofile("rom/modules/main/cc/expect.lua").expect
|
||||||
|
|
||||||
@ -33,7 +105,7 @@ function getNames()
|
|||||||
local side = sides[n]
|
local side = sides[n]
|
||||||
if native.isPresent(side) then
|
if native.isPresent(side) then
|
||||||
table.insert(results, side)
|
table.insert(results, side)
|
||||||
if native.getType(side) == "modem" and not native.call(side, "isWireless") then
|
if native.hasType(side, "modem") and not native.call(side, "isWireless") then
|
||||||
local remote = native.call(side, "getNamesRemote")
|
local remote = native.call(side, "getNamesRemote")
|
||||||
for _, name in ipairs(remote) do
|
for _, name in ipairs(remote) do
|
||||||
table.insert(results, name)
|
table.insert(results, name)
|
||||||
@ -58,7 +130,7 @@ function isPresent(name)
|
|||||||
|
|
||||||
for n = 1, #sides do
|
for n = 1, #sides do
|
||||||
local side = sides[n]
|
local side = sides[n]
|
||||||
if native.getType(side) == "modem" and not native.call(side, "isWireless") and
|
if native.hasType(side, "modem") and not native.call(side, "isWireless") and
|
||||||
native.call(side, "isPresentRemote", name)
|
native.call(side, "isPresentRemote", name)
|
||||||
then
|
then
|
||||||
return true
|
return true
|
||||||
@ -67,12 +139,17 @@ function isPresent(name)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get the type of a wrapped peripheral, or a peripheral with the given name.
|
--[[- Get the types of a named or wrapped peripheral.
|
||||||
--
|
|
||||||
-- @tparam string|table peripheral The name of the peripheral to find, or a
|
@tparam string|table peripheral The name of the peripheral to find, or a
|
||||||
-- wrapped peripheral instance.
|
wrapped peripheral instance.
|
||||||
-- @treturn string|nil The peripheral's type, or `nil` if it is not present.
|
@treturn string... The peripheral's types, or `nil` if it is not present.
|
||||||
-- @changed 1.88.0 Accepts a wrapped peripheral as an argument.
|
@changed 1.88.0 Accepts a wrapped peripheral as an argument.
|
||||||
|
@changed 1.99 Now returns multiple types.
|
||||||
|
@usage Get the type of a peripheral above this computer.
|
||||||
|
|
||||||
|
peripheral.getType("top")
|
||||||
|
]]
|
||||||
function getType(peripheral)
|
function getType(peripheral)
|
||||||
expect(1, peripheral, "string", "table")
|
expect(1, peripheral, "string", "table")
|
||||||
if type(peripheral) == "string" then -- Peripheral name passed
|
if type(peripheral) == "string" then -- Peripheral name passed
|
||||||
@ -81,7 +158,7 @@ function getType(peripheral)
|
|||||||
end
|
end
|
||||||
for n = 1, #sides do
|
for n = 1, #sides do
|
||||||
local side = sides[n]
|
local side = sides[n]
|
||||||
if native.getType(side) == "modem" and not native.call(side, "isWireless") and
|
if native.hasType(side, "modem") and not native.call(side, "isWireless") and
|
||||||
native.call(side, "isPresentRemote", peripheral)
|
native.call(side, "isPresentRemote", peripheral)
|
||||||
then
|
then
|
||||||
return native.call(side, "getTypeRemote", peripheral)
|
return native.call(side, "getTypeRemote", peripheral)
|
||||||
@ -90,10 +167,43 @@ function getType(peripheral)
|
|||||||
return nil
|
return nil
|
||||||
else
|
else
|
||||||
local mt = getmetatable(peripheral)
|
local mt = getmetatable(peripheral)
|
||||||
if not mt or mt.__name ~= "peripheral" or type(mt.type) ~= "string" then
|
if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then
|
||||||
error("bad argument #1 (table is not a peripheral)", 2)
|
error("bad argument #1 (table is not a peripheral)", 2)
|
||||||
end
|
end
|
||||||
return mt.type
|
return table.unpack(mt.types)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[- Check if a peripheral is of a particular type.
|
||||||
|
|
||||||
|
@tparam string|table peripheral The name of the peripheral or a wrapped peripheral instance.
|
||||||
|
@tparam string peripheral_type The type to check.
|
||||||
|
|
||||||
|
@treturn boolean|nil If a peripheral has a particular type, or `nil` if it is not present.
|
||||||
|
@since 1.99
|
||||||
|
]]
|
||||||
|
function hasType(peripheral, peripheral_type)
|
||||||
|
expect(1, peripheral, "string", "table")
|
||||||
|
expect(2, peripheral_type, "string")
|
||||||
|
if type(peripheral) == "string" then -- Peripheral name passed
|
||||||
|
if native.isPresent(peripheral) then
|
||||||
|
return native.hasType(peripheral, peripheral_type)
|
||||||
|
end
|
||||||
|
for n = 1, #sides do
|
||||||
|
local side = sides[n]
|
||||||
|
if native.hasType(side, "modem") and not native.call(side, "isWireless") and
|
||||||
|
native.call(side, "isPresentRemote", peripheral)
|
||||||
|
then
|
||||||
|
return native.call(side, "hasTypeRemote", peripheral, peripheral_type)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
local mt = getmetatable(peripheral)
|
||||||
|
if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then
|
||||||
|
error("bad argument #1 (table is not a peripheral)", 2)
|
||||||
|
end
|
||||||
|
return mt.types[peripheral_type] ~= nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -109,7 +219,7 @@ function getMethods(name)
|
|||||||
end
|
end
|
||||||
for n = 1, #sides do
|
for n = 1, #sides do
|
||||||
local side = sides[n]
|
local side = sides[n]
|
||||||
if native.getType(side) == "modem" and not native.call(side, "isWireless") and
|
if native.hasType(side, "modem") and not native.call(side, "isWireless") and
|
||||||
native.call(side, "isPresentRemote", name)
|
native.call(side, "isPresentRemote", name)
|
||||||
then
|
then
|
||||||
return native.call(side, "getMethodsRemote", name)
|
return native.call(side, "getMethodsRemote", name)
|
||||||
@ -151,7 +261,7 @@ function call(name, method, ...)
|
|||||||
|
|
||||||
for n = 1, #sides do
|
for n = 1, #sides do
|
||||||
local side = sides[n]
|
local side = sides[n]
|
||||||
if native.getType(side) == "modem" and not native.call(side, "isWireless") and
|
if native.hasType(side, "modem") and not native.call(side, "isWireless") and
|
||||||
native.call(side, "isPresentRemote", name)
|
native.call(side, "isPresentRemote", name)
|
||||||
then
|
then
|
||||||
return native.call(side, "callRemote", name, method, ...)
|
return native.call(side, "callRemote", name, method, ...)
|
||||||
@ -160,15 +270,16 @@ function call(name, method, ...)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get a table containing functions pointing to the peripheral's methods, which
|
--- Get a table containing all functions available on a peripheral. These can
|
||||||
-- can then be called as if using @{peripheral.call}.
|
-- then be called instead of using @{peripheral.call} every time.
|
||||||
--
|
--
|
||||||
-- @tparam string name The name of the peripheral to wrap.
|
-- @tparam string name The name of the peripheral to wrap.
|
||||||
-- @treturn table|nil The table containing the peripheral's methods, or `nil` if
|
-- @treturn table|nil The table containing the peripheral's methods, or `nil` if
|
||||||
-- there is no peripheral present with the given name.
|
-- there is no peripheral present with the given name.
|
||||||
-- @usage Open the modem on the top of this computer.
|
-- @usage Open the modem on the top of this computer.
|
||||||
--
|
--
|
||||||
-- peripheral.wrap("top").open(1)
|
-- local modem = peripheral.wrap("top")
|
||||||
|
-- modem.open(1)
|
||||||
function wrap(name)
|
function wrap(name)
|
||||||
expect(1, name, "string")
|
expect(1, name, "string")
|
||||||
|
|
||||||
@ -177,10 +288,14 @@ function wrap(name)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- We store our types array as a list (for getType) and a lookup table (for hasType).
|
||||||
|
local types = { peripheral.getType(name) }
|
||||||
|
for i = 1, #types do types[types[i]] = true end
|
||||||
local result = setmetatable({}, {
|
local result = setmetatable({}, {
|
||||||
__name = "peripheral",
|
__name = "peripheral",
|
||||||
name = name,
|
name = name,
|
||||||
type = peripheral.getType(name),
|
type = types[1],
|
||||||
|
types = types,
|
||||||
})
|
})
|
||||||
for _, method in ipairs(methods) do
|
for _, method in ipairs(methods) do
|
||||||
result[method] = function(...)
|
result[method] = function(...)
|
||||||
@ -222,7 +337,7 @@ function find(ty, filter)
|
|||||||
|
|
||||||
local results = {}
|
local results = {}
|
||||||
for _, name in ipairs(peripheral.getNames()) do
|
for _, name in ipairs(peripheral.getNames()) do
|
||||||
if peripheral.getType(name) == ty then
|
if peripheral.hasType(name, ty) then
|
||||||
local wrapped = peripheral.wrap(name)
|
local wrapped = peripheral.wrap(name)
|
||||||
if filter == nil or filter(name, wrapped) then
|
if filter == nil or filter(name, wrapped) then
|
||||||
table.insert(results, wrapped)
|
table.insert(results, wrapped)
|
||||||
|
@ -1,3 +1,34 @@
|
|||||||
|
# New features in CC: Tweaked 1.99.0
|
||||||
|
|
||||||
|
* Pocket computers in their offhand will open without showing a terminal. You can look around and interact with the world, but your keyboard will be forwarded to the computer. (Wojbie, MagGen-hub).
|
||||||
|
* Peripherals can now have multiple types. `peripheral.getType` now returns multiple values, and `peripheral.hasType` checks if a peripheral has a specific type.
|
||||||
|
* Add several missing keys to the `keys` table. (ralphgod3)
|
||||||
|
* Add feature introduction/changed version information to the documentation. (MCJack123)
|
||||||
|
* Increase the file upload limit to 512KiB.
|
||||||
|
* Rednet can now handle computer IDs larger than 65535. (Ale32bit)
|
||||||
|
* Optimise deduplication of rednet messages (MCJack123)
|
||||||
|
* Make `term.blit` colours case insensitive. (Ocawesome101)
|
||||||
|
* Add a new `about` program for easier version identification. (MCJack123)
|
||||||
|
* Optimise peripheral calls in `rednet.run`. (xAnavrins)
|
||||||
|
* Add dimension parameter to `commands.getBlockInfo`.
|
||||||
|
* Add `cc.pretty.pretty_print` helper function (Lupus590).
|
||||||
|
* Add back JEI integration.
|
||||||
|
* Turtle and pocket computer upgrades can now be added and modified with data packs.
|
||||||
|
* Various translation updates (MORIMORI3017, Ale2Bit, mindy15963)
|
||||||
|
|
||||||
|
And several bug fixes:
|
||||||
|
* Fix various computer commands failing when OP level was 4.
|
||||||
|
* Various documentation fixes. (xXTurnerLP, MCJack123)
|
||||||
|
* Fix `textutils.serialize` not serialising infinity and nan values. (Wojbie)
|
||||||
|
* Wired modems now correctly clean up mounts when a peripheral is detached.
|
||||||
|
* Fix incorrect turtle and pocket computer upgrade recipes in the recipe book.
|
||||||
|
* Fix speakers not playing sounds added via resource packs which are not registered in-game.
|
||||||
|
* Fix speaker upgrades sending packets after the server has stopped.
|
||||||
|
* Monitor sizing has been rewritten, hopefully making it more stable.
|
||||||
|
* Peripherals are now invalidated when the computer ticks, rather than when the peripheral changes.
|
||||||
|
* Fix printouts and pocket computers rendering at fullbright when in item frames.
|
||||||
|
* All mod blocks now have an effective tool (pickaxe).
|
||||||
|
|
||||||
# New features in CC: Tweaked 1.98.2
|
# New features in CC: Tweaked 1.98.2
|
||||||
|
|
||||||
* Add JP translation (MORIMORI0317)
|
* Add JP translation (MORIMORI0317)
|
||||||
|
@ -1,13 +1,32 @@
|
|||||||
New features in CC: Tweaked 1.98.2
|
New features in CC: Tweaked 1.99.0
|
||||||
|
|
||||||
* Add JP translation (MORIMORI0317)
|
* Pocket computers in their offhand will open without showing a terminal. You can look around and interact with the world, but your keyboard will be forwarded to the computer. (Wojbie, MagGen-hub).
|
||||||
* Migrate several recipes to data generators.
|
* Peripherals can now have multiple types. `peripheral.getType` now returns multiple values, and `peripheral.hasType` checks if a peripheral has a specific type.
|
||||||
|
* Add several missing keys to the `keys` table. (ralphgod3)
|
||||||
|
* Add feature introduction/changed version information to the documentation. (MCJack123)
|
||||||
|
* Increase the file upload limit to 512KiB.
|
||||||
|
* Rednet can now handle computer IDs larger than 65535. (Ale32bit)
|
||||||
|
* Optimise deduplication of rednet messages (MCJack123)
|
||||||
|
* Make `term.blit` colours case insensitive. (Ocawesome101)
|
||||||
|
* Add a new `about` program for easier version identification. (MCJack123)
|
||||||
|
* Optimise peripheral calls in `rednet.run`. (xAnavrins)
|
||||||
|
* Add dimension parameter to `commands.getBlockInfo`.
|
||||||
|
* Add `cc.pretty.pretty_print` helper function (Lupus590).
|
||||||
|
* Add back JEI integration.
|
||||||
|
* Turtle and pocket computer upgrades can now be added and modified with data packs.
|
||||||
|
* Various translation updates (MORIMORI3017, Ale2Bit, mindy15963)
|
||||||
|
|
||||||
Several bug fixes:
|
And several bug fixes:
|
||||||
* Fix volume speaker sounds are played at.
|
* Fix various computer commands failing when OP level was 4.
|
||||||
* Fix several rendering issues when holding pocket computers and printouts in
|
* Various documentation fixes. (xXTurnerLP, MCJack123)
|
||||||
hand.
|
* Fix `textutils.serialize` not serialising infinity and nan values. (Wojbie)
|
||||||
* Ensure wired modems and cables join the wired network on chunk load.
|
* Wired modems now correctly clean up mounts when a peripheral is detached.
|
||||||
* Fix stack overflow when using wired networks.
|
* Fix incorrect turtle and pocket computer upgrade recipes in the recipe book.
|
||||||
|
* Fix speakers not playing sounds added via resource packs which are not registered in-game.
|
||||||
|
* Fix speaker upgrades sending packets after the server has stopped.
|
||||||
|
* Monitor sizing has been rewritten, hopefully making it more stable.
|
||||||
|
* Peripherals are now invalidated when the computer ticks, rather than when the peripheral changes.
|
||||||
|
* Fix printouts and pocket computers rendering at fullbright when in item frames.
|
||||||
|
* All mod blocks now have an effective tool (pickaxe).
|
||||||
|
|
||||||
Type "help changelog" to see the full version history.
|
Type "help changelog" to see the full version history.
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
-- @usage Load an image from `example.nft` and draw it.
|
-- @usage Load an image from `example.nft` and draw it.
|
||||||
--
|
--
|
||||||
-- local nft = require "cc.image.nft"
|
-- local nft = require "cc.image.nft"
|
||||||
-- local image = assert(nft.load("example.nft"))
|
-- local image = assert(nft.load("data/example.nft"))
|
||||||
-- nft.draw(image)
|
-- nft.draw(image, term.getCursorPos())
|
||||||
|
|
||||||
local expect = require "cc.expect".expect
|
local expect = require "cc.expect".expect
|
||||||
|
|
||||||
@ -41,6 +41,7 @@ local function parse(image)
|
|||||||
end
|
end
|
||||||
|
|
||||||
line = line + 1
|
line = line + 1
|
||||||
|
foreground, background = "0", "f"
|
||||||
else
|
else
|
||||||
local next = image:find("[\n\30\31]", i) or #image + 1
|
local next = image:find("[\n\30\31]", i) or #image + 1
|
||||||
local seg_len = next - i
|
local seg_len = next - i
|
||||||
|
@ -19,7 +19,7 @@ The structure of this module is based on [A Prettier Printer][prettier].
|
|||||||
@usage Print a table to the terminal
|
@usage Print a table to the terminal
|
||||||
|
|
||||||
local pretty = require "cc.pretty"
|
local pretty = require "cc.pretty"
|
||||||
pretty.print(pretty.pretty({ 1, 2, 3 }))
|
pretty.pretty_print({ 1, 2, 3 })
|
||||||
|
|
||||||
@usage Build a custom document and display it
|
@usage Build a custom document and display it
|
||||||
|
|
||||||
@ -463,6 +463,7 @@ end
|
|||||||
--
|
--
|
||||||
-- local pretty = require "cc.pretty"
|
-- local pretty = require "cc.pretty"
|
||||||
-- pretty.print(pretty.pretty({ 1, 2, 3 }))
|
-- pretty.print(pretty.pretty({ 1, 2, 3 }))
|
||||||
|
-- @see pretty_print for a shorthand to prettify and print an object.
|
||||||
local function pretty(obj, options)
|
local function pretty(obj, options)
|
||||||
expect(2, options, "table", "nil")
|
expect(2, options, "table", "nil")
|
||||||
options = options or {}
|
options = options or {}
|
||||||
@ -474,6 +475,33 @@ local function pretty(obj, options)
|
|||||||
return pretty_impl(obj, actual_options, {})
|
return pretty_impl(obj, actual_options, {})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--[[- A shortcut for calling @{pretty} and @{print} together.
|
||||||
|
|
||||||
|
@param obj The object to pretty-print.
|
||||||
|
@tparam[opt] { function_args = boolean, function_source = boolean } options
|
||||||
|
Controls how various properties are displayed.
|
||||||
|
- `function_args`: Show the arguments to a function if known (`false` by default).
|
||||||
|
- `function_source`: Show where the function was defined, instead of
|
||||||
|
`function: xxxxxxxx` (`false` by default).
|
||||||
|
@tparam[opt] number ribbon_frac The maximum fraction of the width that we should write in.
|
||||||
|
|
||||||
|
@usage Display a table on the screen.
|
||||||
|
|
||||||
|
local pretty = require "cc.pretty"
|
||||||
|
pretty.pretty_print({ 1, 2, 3 })
|
||||||
|
|
||||||
|
@see pretty
|
||||||
|
@see print
|
||||||
|
@since 1.99
|
||||||
|
]]
|
||||||
|
local function pretty_print(obj, options, ribbon_frac)
|
||||||
|
expect(2, options, "table", "nil")
|
||||||
|
options = options or {}
|
||||||
|
expect(3, ribbon_frac, "number", "nil")
|
||||||
|
|
||||||
|
return print(pretty(obj, options), ribbon_frac)
|
||||||
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
empty = empty,
|
empty = empty,
|
||||||
space = space,
|
space = space,
|
||||||
@ -489,4 +517,6 @@ return {
|
|||||||
render = render,
|
render = render,
|
||||||
|
|
||||||
pretty = pretty,
|
pretty = pretty,
|
||||||
|
|
||||||
|
pretty_print = pretty_print,
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ print("Attached Peripherals:")
|
|||||||
if #tPeripherals > 0 then
|
if #tPeripherals > 0 then
|
||||||
for n = 1, #tPeripherals do
|
for n = 1, #tPeripherals do
|
||||||
local sPeripheral = tPeripherals[n]
|
local sPeripheral = tPeripherals[n]
|
||||||
print(sPeripheral .. " (" .. peripheral.getType(sPeripheral) .. ")")
|
print(sPeripheral .. " (" .. table.concat({ peripheral.getType(sPeripheral) }, ", ") .. ")")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
print("None")
|
print("None")
|
||||||
|
@ -15,6 +15,7 @@ import kotlinx.coroutines.channels.Channel
|
|||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.withTimeout
|
import kotlinx.coroutines.withTimeout
|
||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
|
import kotlin.time.Duration.Companion.seconds
|
||||||
import kotlin.time.ExperimentalTime
|
import kotlin.time.ExperimentalTime
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
describe("The peripheral library", function()
|
describe("The peripheral library", function()
|
||||||
local it_modem = peripheral.getType("top") == "modem" and it or pending
|
local it_modem = peripheral.getType("top") == "modem" and it or pending
|
||||||
|
|
||||||
|
local multitype_peripheral = setmetatable({}, {
|
||||||
|
__name = "peripheral",
|
||||||
|
name = "top",
|
||||||
|
type = "modem",
|
||||||
|
types = { "modem", "inventory", modem = true, inventory = true },
|
||||||
|
})
|
||||||
|
|
||||||
describe("peripheral.isPresent", function()
|
describe("peripheral.isPresent", function()
|
||||||
it("validates arguments", function()
|
it("validates arguments", function()
|
||||||
peripheral.isPresent("")
|
peripheral.isPresent("")
|
||||||
@ -26,6 +33,10 @@ describe("The peripheral library", function()
|
|||||||
expect.error(peripheral.getType, {}):eq("bad argument #1 (table is not a peripheral)")
|
expect.error(peripheral.getType, {}):eq("bad argument #1 (table is not a peripheral)")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it("returns nil when no peripheral is present", function()
|
||||||
|
expect(peripheral.getType("bottom")):eq(nil)
|
||||||
|
end)
|
||||||
|
|
||||||
it_modem("can get the type of a peripheral by side", function()
|
it_modem("can get the type of a peripheral by side", function()
|
||||||
expect(peripheral.getType("top")):eq("modem")
|
expect(peripheral.getType("top")):eq("modem")
|
||||||
end)
|
end)
|
||||||
@ -33,6 +44,38 @@ describe("The peripheral library", function()
|
|||||||
it_modem("can get the type of a wrapped peripheral", function()
|
it_modem("can get the type of a wrapped peripheral", function()
|
||||||
expect(peripheral.getType(peripheral.wrap("top"))):eq("modem")
|
expect(peripheral.getType(peripheral.wrap("top"))):eq("modem")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it("can return multiple types", function()
|
||||||
|
expect({ peripheral.getType(multitype_peripheral) }):same { "modem", "inventory" }
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe("peripheral.hasType", function()
|
||||||
|
it("validates arguments", function()
|
||||||
|
peripheral.getType("")
|
||||||
|
expect.error(peripheral.hasType, nil):eq("bad argument #1 (expected string or table, got nil)")
|
||||||
|
expect.error(peripheral.hasType, {}, ""):eq("bad argument #1 (table is not a peripheral)")
|
||||||
|
expect.error(peripheral.hasType, ""):eq("bad argument #2 (expected string, got nil)")
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("returns nil when no peripherals are present", function()
|
||||||
|
expect(peripheral.hasType("bottom", "modem")):eq(nil)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it_modem("can check type of a peripheral by side", function()
|
||||||
|
expect(peripheral.hasType("top", "modem")):eq(true)
|
||||||
|
expect(peripheral.hasType("top", "not_a_modem")):eq(false)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it_modem("can check the type of a wrapped peripheral (true)", function()
|
||||||
|
expect(peripheral.hasType(peripheral.wrap("top"), "modem")):eq(true)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("can check the type of a wrapped peripheral (fake)", function()
|
||||||
|
expect(peripheral.hasType(multitype_peripheral, "modem")):eq(true)
|
||||||
|
expect(peripheral.hasType(multitype_peripheral, "inventory")):eq(true)
|
||||||
|
expect(peripheral.hasType(multitype_peripheral, "something else")):eq(false)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe("peripheral.getMethods", function()
|
describe("peripheral.getMethods", function()
|
||||||
|
21
src/web/copy-cat.d.ts
vendored
21
src/web/copy-cat.d.ts
vendored
@ -1,21 +0,0 @@
|
|||||||
import { h, Component, render, ComponentChild } from "preact";
|
|
||||||
|
|
||||||
export { h, Component, render };
|
|
||||||
|
|
||||||
export type ComputerAccess = unknown;
|
|
||||||
|
|
||||||
export type MainProps = {
|
|
||||||
hdFont?: boolean | string,
|
|
||||||
persistId?: number,
|
|
||||||
files?: { [filename: string]: string | ArrayBuffer },
|
|
||||||
label?: string,
|
|
||||||
width?: number,
|
|
||||||
height?: number,
|
|
||||||
resolve?: (computer: ComputerAccess) => void,
|
|
||||||
}
|
|
||||||
|
|
||||||
declare class Computer extends Component<MainProps, unknown> {
|
|
||||||
public render(props: MainProps, state: unknown): ComponentChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
export { Computer };
|
|
@ -4,15 +4,15 @@ import type { ComponentChild } from "preact";
|
|||||||
import settingsFile from "./mount/.settings";
|
import settingsFile from "./mount/.settings";
|
||||||
import startupFile from "./mount/startup.lua";
|
import startupFile from "./mount/startup.lua";
|
||||||
import exprTemplate from "./mount/expr_template.lua";
|
import exprTemplate from "./mount/expr_template.lua";
|
||||||
import exampleImage from "./mount/example.nfp";
|
import exampleNfp from "./mount/example.nfp";
|
||||||
|
import exampleNft from "./mount/example.nft";
|
||||||
|
|
||||||
const defaultFiles: { [filename: string]: string } = {
|
const defaultFiles: { [filename: string]: string } = {
|
||||||
".settings": settingsFile,
|
".settings": settingsFile,
|
||||||
"startup.lua": startupFile,
|
"startup.lua": startupFile,
|
||||||
|
|
||||||
// TODO: Ideally this'd be in data/image.nfp or something, but copy-cat's
|
"data/example.nfp": exampleNfp,
|
||||||
// dir bootstrapping doesn't cope with that right now.
|
"data/example.nft": exampleNft,
|
||||||
"test-image.nfp": exampleImage
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const clamp = (value: number, min: number, max: number): number => {
|
const clamp = (value: number, min: number, max: number): number => {
|
||||||
|
15
src/web/mount/example.nft
Normal file
15
src/web/mount/example.nft
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
4
|
||||||
|
4
|
||||||
|
4 4
|
||||||
|
0 4 4>0 ls 4
|
||||||
|
0 4 drom/ 4 0
|
||||||
|
0 4 startup.lua 4
|
||||||
|
0 4 4> 0hello 4
|
||||||
|
0 4 aHello World! 0 4
|
||||||
|
0 4 4
|
||||||
|
0 4 4
|
||||||
|
0 4 4
|
||||||
|
0 4
|
||||||
|
0 4 4
|
||||||
|
0 4
|
45
src/web/typings.ts
Normal file
45
src/web/typings.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
declare module "*.lua" {
|
||||||
|
const contents: string;
|
||||||
|
export default contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "*.nfp" {
|
||||||
|
const contents: string;
|
||||||
|
export default contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "*.nft" {
|
||||||
|
const contents: string;
|
||||||
|
export default contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "*.settings" {
|
||||||
|
const contents: string;
|
||||||
|
export default contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare module "copycat/embed" {
|
||||||
|
import { h, Component, render, ComponentChild } from "preact";
|
||||||
|
|
||||||
|
export { h, Component, render };
|
||||||
|
|
||||||
|
export type ComputerAccess = unknown;
|
||||||
|
|
||||||
|
export type MainProps = {
|
||||||
|
hdFont?: boolean | string,
|
||||||
|
persistId?: number,
|
||||||
|
files?: { [filename: string]: string | ArrayBuffer },
|
||||||
|
label?: string,
|
||||||
|
width?: number,
|
||||||
|
height?: number,
|
||||||
|
resolve?: (computer: ComputerAccess) => void,
|
||||||
|
}
|
||||||
|
|
||||||
|
class Computer extends Component<MainProps, unknown> {
|
||||||
|
public render(props: MainProps, state: unknown): ComponentChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Computer };
|
||||||
|
}
|
@ -22,11 +22,6 @@
|
|||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"importsNotUsedAsValues": "error",
|
"importsNotUsedAsValues": "error",
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"paths": {
|
|
||||||
"copycat/embed": [
|
|
||||||
"src/web/copy-cat.d.ts"
|
|
||||||
],
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src/web",
|
"src/web",
|
||||||
|
Loading…
Reference in New Issue
Block a user