This commit is contained in:
Leon van Kammen 2025-01-09 12:14:26 +01:00
parent 986c40a50f
commit 18b32f088e
19 changed files with 1367 additions and 36 deletions

View File

@ -23,6 +23,7 @@ test -f ~/.profile.js && chmod +x ~/.profile.js && ~/.profile.js | grep -v undef
## forward not-found commands to javascript (via jsh) ## forward not-found commands to javascript (via jsh)
command_not_found_handle(){ command_not_found_handle(){
set +e
echo "[!] '$1' not found, did you mean $1(...) (javascript?)" echo "[!] '$1' not found, did you mean $1(...) (javascript?)"
test -n "$ONBOARDING" && echo "[i] type 'help' for handy commands" test -n "$ONBOARDING" && echo "[i] type 'help' for handy commands"
test -n "$ONBOARDING" || help_tips test -n "$ONBOARDING" || help_tips
@ -65,15 +66,21 @@ which screen &> /dev/null && {
test -n "$STY" || { test -n "$STY" || {
resize # call twice resize # call twice
resize # otherwise COLUMNS/ROWS is 0 resize # otherwise COLUMNS/ROWS is 0
# add URL-hash as extra screen session # resize # call twice
test -z "$HASH" || { # resize # otherwise COLUMNS/ROWS is 0
grep 'screen -t #' /root/.screenrc || { # # add URL-hash as extra screen session
echo "screen -t xrsh+URL 3 /bin/sh -c '${HASH}; sh'" | sed "s/'#/'/g" >> /root/.screenrc # test -z "$HASH" || {
} # grep 'screen -t #' /root/.screenrc || {
} # echo "screen -t xrsh+URL 3 /bin/sh -c 'source /etc/profile.sh; ${HASH}; sh'" | sed "s/'#/'/g" >> /root/.screenrc
screen -Aa -R -T screen-256color -c /root/.screenrc # }
# }
# execute URL hash or GNU screen
test -n "$HASH" && hook URI/fragment "${HASH:1}"
test -z "$HASH" && screen -Aa -R -T screen-256color -c /root/.screenrc
} }
test -n "$STY" && { test -n "$STY" && {
resize # call twice
resize # otherwise COLUMNS/ROWS is 0
test -f /root/motd && cat /root/motd || cat /etc/motd; test -f /root/motd && cat /root/motd || cat /etc/motd;
say "welcome to eex r, shell. For an optimal user experience, connect a Bluetooth keyboard." & say "welcome to eex r, shell. For an optimal user experience, connect a Bluetooth keyboard." &
} }

View File

@ -8,7 +8,7 @@ hook(){
logger " |+ hook $hook $*" logger " |+ hook $hook $*"
{ $hook "$@" || true; } | awk '{ gsub(/\/root\/\//,"",$1); $1 = sprintf("%-40s", $1)} 1' { $hook "$@" || true; } | awk '{ gsub(/\/root\/\//,"",$1); $1 = sprintf("%-40s", $1)} 1'
done done
} &> ~/hook.d/log.txt } | tee -a ~/hook.d/log.txt
} }
alert(){ alert(){
@ -46,6 +46,7 @@ console(){
# #
# info: adds javascript/css url/script to DOM # info: adds javascript/css url/script to DOM
require(){ require(){
test -n "$1" || { echo "usage: require <url>"; exit 0; }
file=$(basename "$1") file=$(basename "$1")
ext="${file/*\./}" ext="${file/*\./}"

View File

@ -58,7 +58,7 @@ test -d /dev/browser || {
setup_mounts(){ setup_mounts(){
mkdir /mnt/helloworld /mnt/THREE mkdir /mnt/helloworld /mnt/THREE
fusescript /root/fs/helloworld /mnt/helloworld fusescript /root/fs/helloworld /mnt/helloworld
fusescript /root/fs/THREE.js /mnt/THREE fusescript /root/fs/THREE /mnt/THREE
} }
modprobe fuse # load fuse modprobe fuse # load fuse

View File

@ -9,5 +9,5 @@ exitVR
exitAR exitAR
tail -n1 -f /dev/browser/console /var/log/messages tail -n1 -f /dev/browser/console /var/log/messages
require https://snips.sh/f/VBz-iWm8so?r=1 require https://snips.sh/f/VBz-iWm8so?r=1
require https://xrfragment.org/example/assets/index.glb a-gltf-model https://xrfragment.org/example/assets/index.glb
require https://coderofsalvation.github.io/xrsh-media/assets/background.glb a-gltf-model https://coderofsalvation.github.io/xrsh-media/assets/background.glb

View File

@ -27,6 +27,9 @@ cd(){
} }
} }
# get latest xrfragments to support interactive models
require https://xrfragment.org/dist/xrfragment.aframe.js
# start index.js if /dev/browser/js filesize is not great than 0 # start index.js if /dev/browser/js filesize is not great than 0
if [ ! -s /dev/browser/js ]; then if [ ! -s /dev/browser/js ]; then
chmod +x /mnt/root/index.js && /mnt/root/index.js | grep -v undefined chmod +x /mnt/root/index.js && /mnt/root/index.js | grep -v undefined

View File

@ -0,0 +1,4 @@
#!/bin/sh
test -n "$1" || { echo "usage: teleport <http://...foo.glb>"; exit 0; }
echo "" > ~/index.html # empty scene
a-gltf-model $*

View File

@ -8,6 +8,7 @@ logger "$0: extracting $file"
mkdir -p "/root/$dir" mkdir -p "/root/$dir"
cd "/root/$dir" cd "/root/$dir"
unzip "$file" unzip "$file"
cd "/root/$dir" # trigger auto-env (.env file)
test -f .env && test "$(cat ~/.config/autoenv/package)" = 1 && { test -f .env && test "$(cat ~/.config/autoenv/package)" = 1 && {
logger "$0: detected $(pwd)/.env [autoenv]" logger "$0: detected $(pwd)/.env [autoenv]"

View File

@ -0,0 +1,71 @@
#!/bin/sh
# virtual file interface for THREE
STATE=/run/THREE
LOG=~/.fuse.log
update(){
js '
let fuse_dir = () => '16877 2 0 0 4096 8'
let fuse_file = (size) => `33188 1 0 0 ${size||1} 1`
function traverseScene(object, path = '/', result = '') {
const objectName = object.name? object.name : object.id;
result += `${path}${objectName} ${fuse_dir()}\n`;
result += `${path}${objectName}/position ${fuse_dir()}\n`;
result += `${path}${objectName}/position/x ${fuse_file()}\n`;
result += `${path}${objectName}/position/y ${fuse_file()}\n`;
result += `${path}${objectName}/position/z ${fuse_file()}\n`;
result += `${path}${objectName}/rotation ${fuse_dir()}\n`;
result += `${path}${objectName}/rotation/x ${fuse_file()}\n`;
result += `${path}${objectName}/rotation/y ${fuse_file()}\n`;
result += `${path}${objectName}/rotation/z ${fuse_file()}\n`;
if( object.userData ){
result += `${path}${objectName}/userData 1 1 1 1\n`;
for( let k in object.userData )
result += `${path}${objectName}/userData/${k} 1 1 1 1\n`;
}
object.children.forEach(child => {
result = traverseScene(child, `${path}${objectName}/`, result);
});
return result;
}
return traverseScene( document.querySelector('a-scene').object3D );
' > $STATE
}
readdir(){ # print first column [filename] from header
test -f $STATE || update
awk '/^#\'$1'/ {
gsub("^#'$1'[/]?","",$1); # strip dirname
gsub("\\/.*","",$1); # strip subdirs/files
if( $1 ) print $1
}' $STATE | uniq
}
getattr(){ # print column 2 till 7 from header
awk '$1 == "#'$1'" { print $2" "$3" "$4" "$5" "$6" "$7 }' $STATE
grep -qE '#$1' $0 || return 2 # FUSE expects -NOENT if file does not exist
}
read(){ # print everything (data) after 7th column
awk '$1 == "#'$1'" { $1=$2=$3=$4=$5=$6=$7=""; sub(/^ +/, ""); print $0 }' $0
}
getxattr(){ # print xattr value from commentheader
awk '$1 == "#xattr:'$1'" && $2 == "'$2'" { print $3 }' $STATE
}
setxattr(){ # save xattr value from commentheader
file=$1 ; key=$2 ; shift; shift
sed -i "s/^#xattr:\\$key .*/#xattr:\\$key $*" $STATE || echo "#xattr:$file $key $*" >> $0
}
listxattr(){ # list xattr keys
awk '$1 == "#xattr:'$1'" { printf("%s\0",$2) }' $STATE
}
echo "> $0 $*" >> $LOG
"$@" | tee -a $LOG

View File

@ -1,14 +1,13 @@
#!/bin/js #!/bin/js
// Function to handle getattr command // Function to handle getattr command
function getattr(path,obj) { function getattr(path,opts){
let size = 1 let size = 1
if (path === '/' || path.match(/\/[0-9]+$/) ) { if (path === '/' || opts.obj ){
return "16877 2 1000 1000 4096 8\n" return "16877 2 0 0 4096 8\n"
} else { } else {
return `33188 1 1000 1000 ${size} 1\n` return `33188 1 0 0 ${size} 1\n`
} }
return ''
} }
function getPath(str){ function getPath(str){
@ -18,22 +17,23 @@ function getPath(str){
const parent = path.pop() const parent = path.pop()
let obj = name == "" let obj = name == ""
? scene ? scene
: scene.getObjectById( parseInt(name.substr(1)) ) : scene.getObjectByName( name ) ||
const propvalue = "" scene.getObjectById( parseInt(name.substr(1)) )
if( obj && obj[ name ] ) propvalue = obj[name] console.dir({parent,name,obj})
return {obj,propname:name,propvalue}
return {obj,propname:name}
} }
// Main function to handle commands // Main function to handle commands
function main(args) { function main(args) {
console.log( 'fs/THREE '+args.join(' ') ) console.log( 'fs/THREE '+args.join(' ') )
let children = '' let children = ''
let props = ['name','uuid','position','rotation'] let props = ['uuid','position','rotation']
switch (args[0]) { switch (args[0]) {
case 'readdir':{ case 'readdir':{
const {obj,propvalue,propname} = getPath( args[1] ) const {obj} = getPath( args[1] )
if( obj && obj.children ){ if( obj && obj.children ){
children = obj.children.map( (n) => n.name || n.id ) children = obj.children.map( (n) => n.name || n.id )
.join("\n") .join("\n")
@ -43,14 +43,14 @@ function main(args) {
} }
case 'getattr':{ case 'getattr':{
const {obj,propvalue,propname} = getPath( args[1] ) const opts = getPath( args[1] )
return getattr(args[1],{args,obj,propvalue,propname}); return getattr(args[1],{...opts, args});
break; break;
} }
case 'read':{ case 'read':{
const {propvalue,propname} = getPath( args[1] ) const {obj,propname} = getPath( args[1] )
return propvalue; return obj[propname];
break; break;
} }
@ -62,3 +62,4 @@ function main(args) {
// Run the main function // Run the main function
return main(args.slice(1)); return main(args.slice(1));

View File

@ -13,10 +13,10 @@ echo "$0 $*" >> $LOG
# format: mode nlink uid gid size block # format: mode nlink uid gid size block
case "$2" in case "$2" in
/) /)
echo "16877 2 1000 1000 4096 8" && exit 0 # dir (mode 0755) echo "16877 2 0 0 4096 8" && exit 0 # dir (mode 0755)
;; ;;
/file1) /file1)
echo "33188 1 1000 1000 ${#file1} 1" && exit 0 # file (mode 0644, size 6) echo "33188 1 0 0 ${#file1} 1" && exit 0 # file (mode 0644, size 6)
;; ;;
esac esac
exit 1 exit 1

View File

@ -20,8 +20,8 @@ function log_command() {
} }
function print_getattr(p) { function print_getattr(p) {
if (p == "/") print "16877 2 1000 1000 4096 8" if (p == "/") print "16877 2 0 0 4096 8"
else if (p == "/file1") print "33188 1 1000 1000 " length(file1) " 1" else if (p == "/file1") print "33188 1 0 0 " length(file1) " 1"
else exit 1 else exit 1
} }

View File

@ -6,9 +6,9 @@ const file1 = "hello world";
// Function to handle getattr command // Function to handle getattr command
function getattr(path) { function getattr(path) {
if (path === '/') { if (path === '/') {
return "16877 2 1000 1000 4096 8" return "16877 2 0 0 4096 8"
} else if (path === '/file1') { } else if (path === '/file1') {
return `33188 1 1000 1000 ${file1.length} 1` return `33188 1 0 0 ${file1.length} 1`
} else { } else {
return '' return ''
} }

View File

@ -7,8 +7,8 @@ local function log_command(args)
end end
local function getattr(path) local function getattr(path)
if path == "/" then print("16877 2 1000 1000 4096 8") if path == "/" then print("16877 2 0 0 4096 8")
elseif path == "/file1" then print(string.format("33188 1 1000 1000 %d 1", #file1)) elseif path == "/file1" then print(string.format("33188 1 0 0 %d 1", #file1))
else os.exit(1) end else os.exit(1) end
end end

View File

@ -4,7 +4,7 @@ LOG_PATH = os.path.join(os.getenv("HOME", "/tmp"), ".fuse.log")
file1 = "hello world" file1 = "hello world"
def log(msg): open(LOG_PATH, "a").write(msg + "\n") def log(msg): open(LOG_PATH, "a").write(msg + "\n")
def getattr(path): return {"16877 2 1000 1000 4096 8" if path == "/" else f"33188 1 1000 1000 {len(file1)} 1"} if path in ["/", "/file1"] else None def getattr(path): return {"16877 2 0 0 4096 8" if path == "/" else f"33188 1 0 0 {len(file1)} 1"} if path in ["/", "/file1"] else None
def readdir(): print("file1") def readdir(): print("file1")
def read(path): print(file1) if path == "/file1" else sys.exit(1) def read(path): print(file1) if path == "/file1" else sys.exit(1)

View File

@ -0,0 +1,6 @@
#!/bin/sh
source /etc/profile.sh # expose xrsh cmds like require etc
echo "" # clear line
$* # simply execute
echo "$*" >> /tmp/frag.log

View File

@ -0,0 +1 @@
../../../../bin/ziprun

View File

@ -2,7 +2,16 @@
test -n "$1" || { echo "usage: codemirror <file> <x> <y> <z>"; exit 0; } test -n "$1" || { echo "usage: codemirror <file> <x> <y> <z>"; exit 0; }
me="$(dirname $(readlink -f $0))" me="$(dirname $(readlink -f $0))"
file="$(readlink -f "$1")" set -e
if [[ "$1" =~ ^http ]]; then
file="$(basename "$1")"
test -f $file && rm $file # *TODO* ask permission
wget "${1/*:\/\/}"
else
file="$(readlink -f "$1")"
fi
$me/codemirror.js "$file" $2 $3 $4 $me/codemirror.js "$file" $2 $3 $4
echo "press ctrl-Q to exit editor" echo "press ctrl-Q to exit editor"

File diff suppressed because it is too large Load Diff

BIN
dist/v86-linux.iso vendored

Binary file not shown.