Compare commits

..

13 Commits

Author SHA1 Message Date
f3d1af1d45 add buildings too, not only ways
Signed-off-by: philippe lhardy <philippe.lhardy@astrolabe.coop>
2025-11-01 19:33:20 +01:00
9bb481d0b3 x is longitude y is latitude
and y axis is reversed in maze ( (0,0) is upper left square of maze ).

Signed-off-by: philippe lhardy <philippe.lhardy@astrolabe.coop>
2025-11-01 19:32:20 +01:00
8fdea9ed3a copytominetest using metascript
Signed-off-by: philippe lhardy <philippe.lhardy@astrolabe.coop>
2025-11-01 16:15:15 +01:00
1d96ee089b don't bind to artlog toolbox
Signed-off-by: philippe lhardy <philippe.lhardy@astrolabe.coop>
2025-11-01 15:39:35 +01:00
f27120cc50 discard c code was an empty stub
Signed-off-by: philippe lhardy <philippe.lhardy@astrolabe.coop>
2025-11-01 15:37:25 +01:00
06a46343e0 markdown README.md
Signed-off-by: philippe lhardy <philippe.lhardy@astrolabe.coop>
2025-11-01 15:23:10 +01:00
ab6746ed5c metascript and printclonedep
will move to metascript

Signed-off-by: philippe lhardy <philippe.lhardy@astrolabe.coop>
2025-11-01 15:12:45 +01:00
65cc0f4c62 pending files commited
don't really knwon what i am doing here, commit pending code ...

Signed-off-by: philippe lhardy <philippe.lhardy@astrolabe.coop>
2025-11-01 14:09:35 +01:00
philippe lhardy
70744610cc Merge branch 'rebasepi' into pi
# Conflicts:
#	fetch_dependencies.sh
2023-07-30 10:23:02 +02:00
philippe lhardy
9792b79c56 MaimMim Man in the middle minetest interceptor
- prototype
- between client and server, allow to capture all exchanges and potentially change them
- created to capture server maps in laby
- first test get only MapBlock, support version serialization version 28
  - prepartion for 29 with zstd but untested.

# Conflicts:
#	fetch_dependencies.sh
2023-07-30 10:18:45 +02:00
philippe lhardy
6d7c03d468 MaimMim Man in the middle minetest interceptor
- prototype
- between client and server, allow to capture all exchanges and potentially change them
- created to capture server maps in laby
- first test get only MapBlock, support version serialization version 28
  - prepartion for 29 with zstd but untested.
2022-04-23 11:54:25 +02:00
philippe lhardy
1e03ae561c Merge branch 'pi' of framagit.org:artlog/artloglaby into pi 2022-04-17 13:37:58 +02:00
philippe lhardy
744999802c fix first column and firt line not drawable
- within() method should include first point and exclude last.
2022-04-17 13:36:35 +02:00
78 changed files with 2706 additions and 166 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
devenv_params
artloglaby
build/

6
.idea/ant.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AntConfiguration">
<buildFile url="file://$PROJECT_DIR$/build.xml" />
</component>
</project>

1
.idea/laby.iml generated
View File

@@ -25,5 +25,6 @@
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="artgaphics-0.2.0" level="project" /> <orderEntry type="library" name="artgaphics-0.2.0" level="project" />
<orderEntry type="library" name="zstd-jni-1.5.2-2" level="project" />
</component> </component>
</module> </module>

View File

@@ -1,9 +0,0 @@
<component name="libraryTable">
<library name="artgaphics-0.1.0">
<CLASSES>
<root url="jar://$PROJECT_DIR$/libs/artgaphics-0.1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

9
.idea/libraries/zstd_jni_1_5_2_2.xml generated Normal file
View File

@@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="zstd-jni-1.5.2-2">
<CLASSES>
<root url="jar://$PROJECT_DIR$/libs/zstd-jni-1.5.2-2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -3,24 +3,23 @@
This project was done in java so it requires a java compiler to be build under an executable form. This project was done in java so it requires a java compiler to be build under an executable form.
It is expected you already obtained content of source since you are readeing this BUILD.md It is expected you already obtained content of source since you are reading this BUILD.md
within same directory as this BUILD.md : within same directory as this BUILD.md :
``` ```
./init.sh
# will create build scripts from artlog_toolbox
# ./doit.sh # ./doit.sh
# depends on sharedrawweb for stl export # depends on sharedrawweb for stl export
./fetch_dependencies.sh ./fetch_dependencies.sh
ant dist ant dist
``` ```
Then create de .zip Then create de .zip
``` ```
source ./specificdoit.sh; create_zip_package source ./specificdoit.sh; create_zip_package
``` ```
you ccan then provide and copy laby.zip to install it. you can then provide and copy laby.zip to install it.
See README to find documentation how to install and run it.

View File

@@ -13,13 +13,10 @@ sous windows lancez le laby.bat
il s'agit d'un programme java qui peut aussi être lancé avec l'interpréteur java ainsi : il s'agit d'un programme java qui peut aussi être lancé avec l'interpréteur java ainsi :
java -jar artloglaby-1.0.jar java -jar artloglaby-1.2.jar
mail pl@artisanlogiciel.net mail pl@artisanlogiciel.net
vous pouvez le distribuer ou bien même le vendre vous pouvez le distribuer ou bien même le vendre
ses sources sont sur https://github.com/artlog/labystl
( et utilise aussi https://github.com/artlog/sharedrawweb )
Les labyrinthes que vous sauvegardez le sont dans le répertoire lab. Les labyrinthes que vous sauvegardez le sont dans le répertoire lab.

View File

@@ -1,2 +0,0 @@
SUBDIRS = c
dist_doc_DATA = README

View File

@@ -1,12 +1,11 @@
# This is a personal project to generate a 2D maze using in depth path generation.
This is a personal project to generate a 2D maze using in depth path generation. This can generate a stl file, overall goal was to print it with a 3D printer.
Download the 'latest' laby.zip containing java jar from my blog http://blog.artisanlogiciel.net/public/tech/laby.zip
this can generate a stl file, overall goal was to print it with a 3D printer.
After years i finaly printed one maze, find it at https://www.thingiverse.com/thing:2814655 After years i finaly printed one maze, find it at https://www.thingiverse.com/thing:2814655
This is the very first usable part. This is the very first usable part.
It was developped under debian 7/8 but since it is java based it might be very easily recompiled or even just copied on other platform. It was developped under debian 7/8 but since it is java based it might be very easily recompiled or even just copied on other platform.
There is a console gui menu based with ./doit.sh There is a console gui menu based with ./doit.sh
@@ -15,11 +14,30 @@ requirement : you need a java jdk environment installed ( java + javac ) and ant
ex ubuntu : sudo apt-get install default-jdk ant ex ubuntu : sudo apt-get install default-jdk ant
It can take various input
* raw this tool raw format : see documentation raw
* imc esoteric internal format
* Drawing ?
* osm openstreetmap exported map
* we minetest/luanti world edit format
* Auto-generated
* Created through GUI
and output
* svg SVG / to handle with inkscape
* png
* raw this tool raw format : see documentation raw
* stl for 3d printers
* imc esoteric internal format
* txt labyrinth as text
* we minetest/luanti world edit format
===== BUILD ===== ===== BUILD =====
See BUILD.md See BUILD.md
===== INSTALL ===== ===== INSTALL =====
obtain laby.zip directly build or from you own build ( see BUILD above ). obtain laby.zip directly build or from you own build ( see BUILD above ).

View File

@@ -10,8 +10,11 @@
<property name="src" location="java"/> <property name="src" location="java"/>
<property name="build" location="build"/> <property name="build" location="build"/>
<property name="dist" location="dist"/> <property name="dist" location="dist"/>
<!-- Fill me please / todo --> <!-- Fill me please / todo
see fetch_dependencies
-->
<property name="artgraphicslib" value="artgaphics-0.2.0"/> <property name="artgraphicslib" value="artgaphics-0.2.0"/>
<property name="zstd-jnilib" value="zstd-jni-1.5.2-2"/>
<target name="gather_project_params"> <target name="gather_project_params">
<!-- original source parameter is in project_params project_version --> <!-- original source parameter is in project_params project_version -->
<loadfile property="distversion" srcfile="${basedir}/project_params"> <loadfile property="distversion" srcfile="${basedir}/project_params">
@@ -38,7 +41,7 @@
<target name="compile" depends="init" <target name="compile" depends="init"
description="compile the source " > description="compile the source " >
<!-- Compile the java code from ${src} into ${build} --> <!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}" includeantruntime="false" classpath="libs/${artgraphicslib}.jar"> <javac srcdir="${src}" destdir="${build}" includeantruntime="false" classpath="libs/${artgraphicslib}.jar:libs/${zstd-jnilib}.jar">
<exclude name="org/artisanlogiciel/games/javafx/*"/> <exclude name="org/artisanlogiciel/games/javafx/*"/>
<compilerarg value="-Xlint:deprecation,unchecked" /> <compilerarg value="-Xlint:deprecation,unchecked" />
</javac> </javac>

View File

@@ -1,12 +0,0 @@
# Makefile.am is REALLY where changes should be done
# Makefile.in and Makefile are generated from this.
bin_PROGRAMS = laby
laby_SOURCES = allaby_reader.c allaby_main.c
laby_CPPFLAGS = $(ARTLOG_CPPFLAGS) $(ALEXPANDER_CPPFLAGS)
# in LDADD and not in LDFLAGS to be linked AFTER
laby_LDADD = $(ARTLOG_LDFLAGS) $(ALEXPANDER_LDFLAGS)

View File

@@ -1,17 +0,0 @@
#include "al_options.h"
// NOT YET IMPLEMENTED
int main(int argc, char ** argv)
{
int exitcode = 1;
struct al_options * options = al_options_create(argc,argv);
al_options_set_debug(options,0);
struct alhash_datablock * debugdata = al_option_get(options,"debug");
if ( debugdata != NULL )
{
exitcode = 0;
}
al_options_release(options);
return exitcode;
}

View File

@@ -1,2 +0,0 @@
#include "allaby_reader.h"

View File

@@ -1,9 +0,0 @@
#ifndef __ALLABY_READER_H__
#define __ALLABY_READER_H__
/** goal : read a labyrinth/maze created
by java laby project
**/
#endif // __ALLABY_READER_H__

View File

@@ -1 +1 @@
sharedrawweb artlog_toolbox sharedrawweb

View File

@@ -1,37 +0,0 @@
# written manually, this is root entry files for automake together with Makefile.am
# inspired from
# http://www.gnu.org/software/automake/manual/html_node/Creating-amhello.html#Creating-amhello
AC_INIT([allaby], [0.1], [pl@artisanlogiciel.net])
# set ARTLOG_TOOLBOX where artlog_toolbox is to use it.
[ARTLOG_TOOLBOX=`pwd`/`./locate_artlog_toolbox.sh`]
# non need to propagate it in .h ...
# AC_DEFINE_UNQUOTED([ARTLOG_TOOLBOX],["$ARTLOG_TOOLBOX"],[where artog toolbox is])
ARTLOG_CPPFLAGS="-I${ARTLOG_TOOLBOX}/build/include"
ARTLOG_LDFLAGS="-Wl,-Bstatic -L${ARTLOG_TOOLBOX}/build/lib -lalsave -laltest -laljson -lalstack -lalhash -laldev -Wl,-Bdynamic"
AC_SUBST(ARTLOG_CPPFLAGS)
AC_SUBST(ARTLOG_LDFLAGS)
[if [ "$ALEXPANDER_DIR" = "" ]]
[then]
[ALEXPANDER_DIR=`pwd`/../sharedrawweb]
[fi]
ALEXPANDER_CPPFLAGS="-I${ALEXPANDER_DIR}/build/include -D CHARSPERRECORD=80"
ALEXPANDER_LDFLAGS="-Wl,-Bstatic -L${ALEXPANDER_DIR}/build/lib -lalima -lalcommon -Wl,-Bdynamic"
AC_SUBST(ALEXPANDER_CPPFLAGS)
AC_SUBST(ALEXPANDER_LDFLAGS)
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
AC_DEFINE([MAX_FLAT_VIEWS],[20],[maximum number of view])
AC_CONFIG_FILES([
Makefile
c/Makefile
])
AC_OUTPUT

57
copytominetest.sh Executable file
View File

@@ -0,0 +1,57 @@
#!/bin/bash
# SPDX-FileCopyrightText: 2025 artlog@l0g.eu
# SPDX-License-Identifier: AGPL-3.0-or-later
# header generated by lib/metascript.sh header
# metascript_version=v1.0.0
toolsdir=lib
pushd $toolsdir >/dev/null
toolsdir=$(pwd)
source metascript.sh
popd >/dev/null
usage() {
cat <<EOF
copy a .we generated lab into minetest local game directory
name=name of generated .we without extension
game=name of game
EOF
}
metarun=metarun
# change default to sudo if needed
# metasudo=sudo
name="$1.we"
srcdir="lab/"
game="nm"
while [[ $# > 0 ]]
do
case "$1" in
name=*)
name=${1/name=}.we
;;
game=*)
game=${1/game=}
;;
*)
parsemetaarg "$1"
;;
esac
shift
done
dest=~/.minetest/worlds/$game/schems
src=${srcdir}$name
enforce file $src exists
enforce dir $dest exists
if [[ -f $src ]]
then
$defer cp $src $dest/
else
log_error "missing $src"
fi

View File

@@ -1,3 +1,3 @@
DEV_ENV=~/artisanlogiciel/devel_tools DEV_ENV=~/home/plhardy/clients/artlog/code/laby/devel_tools
JDK_PATH=~/artisanlogiciel/devel_tools/jdk1.8.0_74 JDK_PATH=/usr/lib/jvm/java-11-openjdk-amd64
ECLIPSE_PATH=~/artisanlogiciel/devel_tools/eclipse ECLIPSE_PATH=/snap/bin

View File

@@ -1,20 +1,14 @@
#!/bin/bash #!/bin/bash
# SPDX-FileCopyrightText: 2025 artlog@l0g.eu
# SPDX-License-Identifier: AGPL-3.0-or-later
# header generated by lib/metascript.sh header
# metascript_version=v1.0.0
log_any() toolsdir=lib
{ pushd $toolsdir >/dev/null
echo "$@" >&2 toolsdir=$(pwd)
} source metascript.sh
popd >/dev/null
log_error()
{
log_any "[ERROR] $@"
}
log_info()
{
log_any "[INFO] $@"
}
fetch_jackson_databind() fetch_jackson_databind()
{ {
@@ -22,27 +16,61 @@ fetch_jackson_databind()
if [[ ! -e libs/$lib_jackson_databind ]] if [[ ! -e libs/$lib_jackson_databind ]]
then then
jacksonmaven=https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/${libversion_jackson_databind}/$lib_jackson_databind jacksonmaven=https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/${libversion_jackson_databind}/$lib_jackson_databind
pushd libs $defer pushd libs
wget $jacksonmaven $metarun wget $jacksonmaven
popd $defer popd
fi fi
} }
fetch_zstd-jni()
{
# echo "compiled from https://github.com/luben/zstd-jni commit 54d3d50c16d96bd8a30e2d4c0a9648001a52d6f9"
# had to hack through jar generation ...
# cp ~/artisanlogiciel/ext_projects/java/zstd-jni/target/zstd-jni-1.5.2-2.jar .
$defer pushd libs
$metarun wget https://repo1.maven.org/maven2/com/github/luben/zstd-jni/${libversion_zstdjni}/zstd-jni-${libversion_zstdjni}.jar
$defer popd
}
# HARDCODED START
libversion_zstdjni=1.5.2-2
libversion_jackson_databind=2.12.0 libversion_jackson_databind=2.12.0
sharedrawweb_git_url="ssh://philippe@www4.artisanlogiciel.net:2023/home/philippe/artisanlogiciel/code/sharedrawweb" sharedrawweb_git_url="ssh://git@www4.artisanlogiciel.net:2023/home/git/artisanlogiciel/code/sharedrawweb"
libversion_artgaphic=0.2.0 libversion_artgaphic=0.2.0
# HARDCODED END
lib_artgaphic=artgaphics-${libversion_artgaphic}.jar lib_artgaphic=artgaphics-${libversion_artgaphic}.jar
if [[ ! -d ../sharedrawweb ]] metarun=metarun
# change default to sudo if needed
# metasudo=sudo
while [[ $# > 0 ]]
do
case "$1" in
use_jackson)
use_jackson=$1
;;
use_zstd)
use_zstd=1
;;
*)
parsemetaarg "$1"
;;
esac
shift
done
if [[ ! -d sharedrawweb ]]
then then
log_error "expected a sharedrawweb project parent ( for exports ). Please clone related project." log_error "expected a sharedrawweb project parent ( for exports ). Please clone related project."
log_info "cd ..; git clone $sharedrawweb_git_url" log_info "git clone $sharedrawweb_git_url sharedrawweb"
fi fi
if [[ ! -d libs ]] if [[ ! -d libs ]]
then then
mkdir libs $metarun mkdir libs
fi fi
if [[ ! -e libs/$lib_artgaphic ]] if [[ ! -e libs/$lib_artgaphic ]]
@@ -51,7 +79,7 @@ then
if [[ -f $lib_artgaphic_source_file ]] if [[ -f $lib_artgaphic_source_file ]]
then then
# ../ since libs is one level below current project # ../ since libs is one level below current project
ln -s ../$lib_artgaphic_source_file libs/ $metarun ln -s ../$lib_artgaphic_source_file libs/
else else
log_error "Missing $lib_artgaphic_source_file. It is require to build it sharedrawweb project first" log_error "Missing $lib_artgaphic_source_file. It is require to build it sharedrawweb project first"
fi fi
@@ -61,3 +89,8 @@ if [[ -n $use_jackson ]]
then then
fetch_jackson_databind fetch_jackson_databind
fi fi
if [[ -n $use_zstd ]]
then
fetch_zstd-jni
fi

18
init.sh
View File

@@ -1,18 +1,5 @@
#!/bin/bash #!/bin/bash
setup()
{
artlog_toolbox_path=../artlog_toolbox
if [[ ! -d $artlog_toolbox_path ]]
then
git clone $artlog_toolbox_remote_origin_url $artlog_toolbox_path
pushd $artlog_toolbox_path
git checkout
popd
fi
$artlog_toolbox_path/deploy.sh
}
# parses project.gitref # parses project.gitref
project= project=
gitref=project.gitref gitref=project.gitref
@@ -33,9 +20,6 @@ do
artloglaby) artloglaby)
artloglaby_remote_origin_url=$remote_origin_url artloglaby_remote_origin_url=$remote_origin_url
;; ;;
artlog_toolbox)
artlog_toolbox_remote_origin_url=$remote_origin_url
;;
*) *)
echo "ERROR unrecognized project='$project' line='$line'" echo "ERROR unrecognized project='$project' line='$line'"
;; ;;
@@ -43,4 +27,4 @@ do
fi fi
done <$gitref done <$gitref
setup

View File

@@ -1,7 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="src" path=""/> <classpathentry kind="src" path=""/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.fx.ide.jdt.core.JAVAFX_CONTAINER"/> <classpathentry kind="con" path="org.eclipse.fx.ide.jdt.core.JAVAFX_CONTAINER"/>
<classpathentry kind="lib" path="/home/plhardy/clients/artlog/code/laby/libs/artgaphics-0.2.0.jar"/>
<classpathentry kind="lib" path="/home/plhardy/artisanlogiciel/code/laby/libs/sharedrawweb-0.2.0.jar"/>
<classpathentry kind="lib" path="/home/plhardy/artisanlogiciel/code/laby/libs/artgaphics-0.2.0.jar"/>
<classpathentry kind="output" path=""/> <classpathentry kind="output" path=""/>
</classpath> </classpath>

1
java/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/module-info.class

View File

@@ -0,0 +1 @@
/JWToken.class

View File

@@ -0,0 +1,4 @@
package org.artisanlogiciel.aaa.authorize;
public class JWToken {
}

View File

@@ -0,0 +1,20 @@
/Brick.class
/BrickTextMapping.class
/DrawingGenerator.class
/LabyLayers.class
/LabyMap.class
/LabyModel.class
/Main.class
/Maze$1.class
/Maze$2.class
/Maze$3.class
/Maze.class
/MazeCreationListener.class
/MazeParamEditor.class
/MazeParams.class
/MazeParamsFixed.class
/MovesProvider.class
/Position.class
/PositionWithDepth.class
/WallsProvider.class
/XYGridIterator.class

View File

@@ -0,0 +1,26 @@
package org.artisanlogiciel.games.maze;
import org.artisanlogiciel.games.minetest.net.MiM;
import java.net.InetSocketAddress;
public class MainMim {
void minetestMime(String serverName, int port) {
MiM mim = new MiM(30002, new InetSocketAddress(serverName, port));
mim.launch();
}
public static void main(String pArgs[])
{
if ( pArgs.length > 1)
{
new MainMim().minetestMime(pArgs[0], Integer.parseInt(pArgs[1]));
}
else
{
System.err.println("[ERROR] please set minetest server hostname and port as arguments");
}
}
}

View File

@@ -307,9 +307,11 @@ public class Maze {
OsmReader reader = new OsmReader(infile.getCanonicalPath()); OsmReader reader = new OsmReader(infile.getCanonicalPath());
reader.read(); reader.read();
OsmToDrawing converter = new OsmToDrawing(reader, mulx,muly); OsmToDrawing converter = new OsmToDrawing(reader, mulx,muly);
Drawing drawing = converter.getDrawing(reader.getWays()); Drawing ways = converter.getDrawing(reader.getWays());
Drawing buildings = converter.getDrawing(reader.getBuildings());
setStatusEnable(false); setStatusEnable(false);
addDrawing(drawing,add); addDrawing(ways,add);
addDrawing(buildings,add);
setStatusEnable(true); setStatusEnable(true);
} catch (IOException io) { } catch (IOException io) {
io.printStackTrace(System.err); io.printStackTrace(System.err);

View File

@@ -0,0 +1,44 @@
/CellGridComponent.class
/Display$1.class
/Display$2.class
/Display$3.class
/Display$MazeFrame.class
/Display.class
/HexagonCellRenderer$UV.class
/HexagonCellRenderer.class
/Maze3dSettings.class
/MazeCellRenderer.class
/MazeColorMap.class
/MazeComponent.class
/MazeControler$1.class
/MazeControler$10.class
/MazeControler$11.class
/MazeControler$12.class
/MazeControler$13.class
/MazeControler$14.class
/MazeControler$15.class
/MazeControler$16.class
/MazeControler$17.class
/MazeControler$18.class
/MazeControler$19.class
/MazeControler$2.class
/MazeControler$20.class
/MazeControler$21.class
/MazeControler$22.class
/MazeControler$23.class
/MazeControler$24.class
/MazeControler$25.class
/MazeControler$26.class
/MazeControler$27.class
/MazeControler$3.class
/MazeControler$4.class
/MazeControler$5.class
/MazeControler$6.class
/MazeControler$7.class
/MazeControler$8.class
/MazeControler$9.class
/MazeControler.class
/MazeDefault.class
/MazeSettings$1.class
/MazeSettings.class
/StatusListener.class

View File

@@ -4,6 +4,7 @@ import org.artisanlogiciel.games.maze.*;
import org.artisanlogiciel.games.maze.model.WidthHeightProvider; import org.artisanlogiciel.games.maze.model.WidthHeightProvider;
import org.artisanlogiciel.games.maze.persist.MazePersistRaw; import org.artisanlogiciel.games.maze.persist.MazePersistRaw;
import org.artisanlogiciel.games.maze.solve.SolvingModel; import org.artisanlogiciel.games.maze.solve.SolvingModel;
import org.artisanlogiciel.games.minetest.net.MiM;
import org.artisanlogiciel.graphics.Drawing; import org.artisanlogiciel.graphics.Drawing;
import org.artisanlogiciel.xpm.Xpm; import org.artisanlogiciel.xpm.Xpm;
@@ -14,6 +15,7 @@ import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Locale; import java.util.Locale;
/** /**
@@ -270,6 +272,7 @@ implements StatusListener
} }
}; };
System.out.println("Default Locale " + Locale.getDefault()); System.out.println("Default Locale " + Locale.getDefault());
if ((pArgs.length > 0) && (pArgs[0].length() > 0)) { if ((pArgs.length > 0) && (pArgs[0].length() > 0)) {

View File

@@ -31,13 +31,13 @@ public class Maze3dSettings
void createSettingsGui() { void createSettingsGui() {
if (params != null) { if (params != null) {
IntegerField xl = new IntegerField("width",params.getXl()); xl = new IntegerField("width",params.getXl());
addField(xl); addField(xl);
IntegerField zl = new IntegerField("height",params.getZl()); zl = new IntegerField("height",params.getZl());
addField(zl); addField(zl);
IntegerField yl = new IntegerField("depth",params.getYl()); yl = new IntegerField("depth",params.getYl());
addField(yl); addField(yl);
reverse = new JCheckBox("reverse",params.isReverse()); reverse = new JCheckBox("reverse",params.isReverse());
@@ -52,6 +52,9 @@ public class Maze3dSettings
hg = new IntegerField(params.getHg()); hg = new IntegerField(params.getHg());
addField(hg); addField(hg);
} }
else {
System.err.println("params null");
}
} }
Maze3dParams createParams() Maze3dParams createParams()

View File

@@ -0,0 +1,2 @@
/IntegerField.class
/Panel.class

View File

@@ -0,0 +1,9 @@
/BooleanLongSet.class
/HalfSquareModelCreator$SetXY.class
/HalfSquareModelCreator.class
/HalfSquareProvider.class
/HalfSquareRasterModel.class
/HexagonModelProvider.class
/LabyModelProvider.class
/LineColumnModel.class
/WidthHeightProvider.class

View File

@@ -6,7 +6,7 @@ import org.artisanlogiciel.games.maze.WallsProvider;
/** /**
* minimal model without repetition * minimal model without repetition
* keep only left and down wall and rely on neightbor squeres to obtain right and up * keep only left and down wall and rely on neightbor squares to obtain right and up
* left down compatible with Bricks * left down compatible with Bricks
* *
* LEFT 01 * LEFT 01

View File

@@ -0,0 +1,3 @@
/HalfSquareRasterModelPersistRaw.class
/MazePersistRaw.class
/MazePersistWorldEdit.class

View File

@@ -0,0 +1,3 @@
/DirectionPosition.class
/MazeResolutionListener.class
/SolvingModel.class

View File

@@ -0,0 +1,8 @@
/Material.class
/Node.class
/Range.class
/Raw.class
/Slice.class
/WorlEditGenerator.class
/World.class
/WorldEditReader.class

View File

@@ -0,0 +1,97 @@
package org.artisanlogiciel.games.minetest;
import com.github.luben.zstd.Zstd;
import org.artisanlogiciel.games.minetest.core.Constant;
import org.artisanlogiciel.games.minetest.core.PacketException;
import org.artisanlogiciel.games.minetest.core.Serialize;
import java.nio.ByteBuffer;
import java.util.ArrayList;
/**
* A block of nodes of MAP_BLOCKSIZE in any x,y,z direction
*/
public class MapBlock {
final static int nodecount = Constant.MAP_BLOCKSIZE * Constant.MAP_BLOCKSIZE * Constant.MAP_BLOCKSIZE;
int m_lighting_complete;
ArrayList<MapNode> nodes;
ArrayList<MapNode> getNodes()
{
if ( nodes == null )
{
nodes = new ArrayList<>(nodecount);
}
return nodes;
}
// in memory case
public void deSerialize(ByteBuffer buffer, int version)
throws PacketException
{
int flags = 0;
int content_width = 0;
int params_width = 0;
if ( version >= 29) {
// ByteBuffer byteBuffer = ByteBuffer.wrap(networkPacket.getBuffer(),offset,networkPacket.getLength() - offset);
/*
// force to have a direct buffer.
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(networkPacket.getLength());
byteBuffer.put(networkPacket.getBuffer());
byteBuffer.position(networkPacket.getOffset());
//System.arraycopy(networkPacket.getBuffer(), 0, byteBuffer.array(), 0, length);
// zstd compression
// FIXME, can we know original size ? somehow related to BLOCKSIZE³
long originalSizeMax = Zstd.decompressedSize(byteBuffer);
System.out.println(String.format("originalSizeMax=%d", originalSizeMax));
ByteBuffer decompressed = Zstd.decompress(byteBuffer,(int) originalSizeMax);
*/
byte out[] = new byte[16386];
long outLength = Zstd.decompressByteArray(out, 0, out.length, buffer.array(), buffer.arrayOffset(), buffer.limit());
// Should be a MapBlock
MapBlock block = new MapBlock();
ByteBuffer decompressed = ByteBuffer.wrap(out, 0, (int) outLength);
buffer = decompressed;
}
flags = Serialize.readU8(buffer);
if ( version >= 27 ) {
m_lighting_complete = Serialize.readU16(buffer);
}
content_width = Serialize.readU8(buffer);
params_width = Serialize.readU8(buffer);
System.out.println(String.format(" flags %x lightning_complete %d content_witd %d params_width %d ",flags, m_lighting_complete, content_width, params_width));
if (( version < 29 ) && ( version >= 11 ))
{
// ZLib decompression
try {
byte decompressed[] = Serialize.decompress(buffer);
buffer = ByteBuffer.wrap(decompressed);
}
catch ( Exception e)
{
// TODO
System.err.println(e);
e.printStackTrace(System.err);
return;
}
}
nodes = getNodes();
MapNode.deSerializeBulk(buffer,version, nodes,nodecount,content_width,params_width);
//m_node_metadata.deSerialize(is, m_gamedef->idef());
}
}

View File

@@ -0,0 +1,99 @@
package org.artisanlogiciel.games.minetest;
import org.artisanlogiciel.games.minetest.core.PacketException;
import org.artisanlogiciel.games.minetest.core.Serialize;
import java.nio.ByteBuffer;
import java.util.List;
public class MapNode {
/*
Main content
*/
short param0;
/*
Misc parameter. Initialized to 0.
- For light_propagates() blocks, this is light intensity,
stored logarithmically from 0 to LIGHT_MAX.
Sunlight is LIGHT_SUN, which is LIGHT_MAX+1.
- Contains 2 values, day- and night lighting. Each takes 4 bits.
- Uhh... well, most blocks have light or nothing in here.
*/
byte param1;
/*
The second parameter. Initialized to 0.
E.g. direction for torches and flowing water.
*/
byte param2;
public void deSerialize(ByteBuffer buffer)
throws PacketException
{
// version >= 24
param0 = (short) Serialize.readU16(buffer);
buffer.position(buffer.position() + 2);
param1 = (byte) Serialize.readU8(buffer);
buffer.position(buffer.position() + 1);
param2 = (byte) Serialize.readU8(buffer);
// network specific ...
// readU8(is);
}
// Deserialize bulk node data
public static void deSerializeBulk(ByteBuffer buffer, int version,
List<MapNode> nodes, int nodecount,
int content_width, int params_width)
throws PacketException
{
byte[] intern = buffer.array();
int initialOffset = buffer.position();
// Deserialize content
if(content_width == 1)
{
for(int i=0; i<nodecount; i++) {
nodes.add(i, new MapNode());
nodes.get(i).param0 = (short) Serialize.readU8( intern, initialOffset + i, intern.length);
}
}
else if(content_width == 2)
{
for(int i=0; i<nodecount; i++) {
nodes.add(i, new MapNode());
nodes.get(i).param0 = (short) Serialize.readU8( intern, initialOffset + (i*2), intern.length);
}
}
// Deserialize param1
int start1 = initialOffset + (content_width * nodecount);
for(int i=0; i<nodecount; i++) {
nodes.get(i).param1 = (byte) Serialize.readU8( intern, start1 + i, intern.length);
}
// Deserialize param2
int start2 = initialOffset + ((content_width + 1) * nodecount);
if(content_width == 1)
{
for(int i=0; i<nodecount; i++) {
MapNode node = nodes.get(i);
node.param2 = (byte) Serialize.readU8( intern, start2 + i, intern.length);
if(node.param0 > 0x7F){
node.param0 <<= 4;
node.param0 |= (node.param2&0xF0)>>4;
node.param2 &= 0x0F;
}
}
}
else if(content_width == 2)
{
for(int i=0; i<nodecount; i++) {
nodes.get(i).param2 = (byte) Serialize.readU8(intern, start2 + i, intern.length);
}
}
}
}

View File

@@ -3,6 +3,7 @@ package org.artisanlogiciel.games.minetest;
import java.util.HashMap; import java.util.HashMap;
public class Node { public class Node {
// could be a core.v3s16
int x; int x;
int y; int y;
int z; int z;

View File

@@ -0,0 +1,6 @@
package org.artisanlogiciel.games.minetest.core;
public class Constant {
public final static int MAP_BLOCKSIZE = 16;
}

View File

@@ -0,0 +1,10 @@
package org.artisanlogiciel.games.minetest.core;
public class PacketException
extends Exception
{
public PacketException(String message)
{
super(message);
}
}

View File

@@ -0,0 +1,116 @@
package org.artisanlogiciel.games.minetest.core;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.util.zip.Inflater;
public class Serialize {
public final static int BUFFER_SIZE = 16386;
public static int readS16(byte buffer[], int offset, int length)
throws PacketException
{
if ( offset + 2 < length) {
return 256 * buffer[offset] + buffer[offset + 1];
}
else
{
throw new PacketException("out of bound offset U16");
}
}
// MSB network order
public static int readU32(byte[] buffer, int offset, int length)
throws PacketException
{
if ( offset + 4 < length) {
return 16777216 * Byte.toUnsignedInt(buffer[offset]) +
65536 * Byte.toUnsignedInt(buffer[offset + 1]) +
256 * Byte.toUnsignedInt(buffer[offset + 2]) +
Byte.toUnsignedInt(buffer[offset + 3]);
}
else
{
throw new PacketException("out of bound offset U32");
}
}
// MSB network order
public static int readU16(byte[] buffer, int offset, int length)
throws PacketException
{
if ( offset + 2 < length) {
return 256 * Byte.toUnsignedInt(buffer[offset]) +
Byte.toUnsignedInt(buffer[offset + 1]);
}
else
{
throw new PacketException("out of bound offset U16");
}
}
// will update position
public static int readU16(ByteBuffer byteBuffer)
throws PacketException
{
int u16 = readU16(byteBuffer.array(), byteBuffer.position(), byteBuffer.array().length);
byteBuffer.position(byteBuffer.position()+2);
return u16;
}
public static int readU8(byte[] buffer, int offset, int length)
throws PacketException
{
if ( offset + 1 < length) {
return Byte.toUnsignedInt(buffer[offset]);
}
else
{
throw new PacketException("out of bound offset U8");
}
}
// will update position
public static int readU8(ByteBuffer byteBuffer)
throws PacketException
{
int u8 = readU8(byteBuffer.array(), byteBuffer.position(), byteBuffer.array().length);
byteBuffer.position(byteBuffer.position()+1);
return u8;
}
public static v3s16 readV3S16(byte buffer[], int offset, int length)
throws PacketException
{
if ( offset + 6 <= length) {
int x = readS16(buffer, offset, length);
int y = readS16(buffer, offset + 2, length);
int z = readS16(buffer, offset + 4, length);
return new v3s16(x, y, z);
}
else
{
throw new PacketException("out of bound offset v3s16");
}
}
// Zlib decompression
public static byte[] decompress(ByteBuffer byteBuffer) throws Exception
{
final Inflater inflater = new Inflater(false);
inflater.setInput(byteBuffer.array(), byteBuffer.position(), byteBuffer.limit() - byteBuffer.position());
try (final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(byteBuffer.limit()))
{
byte[] buffer = new byte[BUFFER_SIZE];
while (!inflater.finished())
{
final int count = inflater.inflate(buffer);
outputStream.write(buffer, 0, count);
}
return outputStream.toByteArray();
}
}
}

View File

@@ -0,0 +1,13 @@
package org.artisanlogiciel.games.minetest.core;
public class v2s16 {
public int X;
public int Y;
public v2s16(int x, int y) {
X = x;
Y = y;
}
}

View File

@@ -0,0 +1,14 @@
package org.artisanlogiciel.games.minetest.core;
public class v3s16 {
public int X;
public int Y;
public int Z;
public v3s16(int x, int y, int z) {
X = x;
Y = y;
Z = z;
}
}

View File

@@ -0,0 +1,4 @@
package org.artisanlogiciel.games.minetest.net;
public class Address {
}

View File

@@ -0,0 +1,28 @@
package org.artisanlogiciel.games.minetest.net;
import org.artisanlogiciel.games.minetest.core.PacketException;
import org.artisanlogiciel.games.minetest.core.Serialize;
public class BufferedPacket {
public static int BASE_HEADER_SIZE = 7;
// Data of the packet, including headers
byte[] m_data;
BufferedPacket(byte[] data)
{
m_data = data;
}
int getSeqNum()
throws PacketException
{
return Serialize.readU16(m_data, BASE_HEADER_SIZE + 1, size());
}
int size()
{
return m_data.length;
}
}

View File

@@ -0,0 +1,9 @@
package org.artisanlogiciel.games.minetest.net;
public class Channel {
int readNextIncomingSeqNum()
{
return 0;
}
}

View File

@@ -0,0 +1,45 @@
package org.artisanlogiciel.games.minetest.net;
public class ConnectionEvent {
ConnectionEventType m_event_type;
int m_peer_id;
byte[] m_data;
boolean m_timeout;
ConnectionEvent(ConnectionEventType eventType)
{
m_event_type = eventType;
}
String describe()
{
return m_event_type.toString();
}
ConnectionEventPtr create(ConnectionEventType type)
{
return null;
}
ConnectionEventPtr dataReceived(int peer_id, byte[] data)
{
return null;
}
ConnectionEventPtr peerAdded(int peer_id, Address address)
{
return null;
}
ConnectionEventPtr peerRemoved(int peer_id, boolean is_timeout, Address address)
{
return null;
}
ConnectionEventPtr bindFailed()
{
return null;
}
}

View File

@@ -0,0 +1,4 @@
package org.artisanlogiciel.games.minetest.net;
public class ConnectionEventPtr {
}

View File

@@ -0,0 +1,9 @@
package org.artisanlogiciel.games.minetest.net;
public enum ConnectionEventType {
CONNEVENT_NONE,
CONNEVENT_DATA_RECEIVED,
CONNEVENT_PEER_ADDED,
CONNEVENT_PEER_REMOVED,
CONNEVENT_BIND_FAILED
}

View File

@@ -0,0 +1,90 @@
package org.artisanlogiciel.games.minetest.net;
import org.artisanlogiciel.games.minetest.core.PacketException;
import org.artisanlogiciel.games.minetest.core.Serialize;
import java.util.ArrayList;
public class IncomingSplitBuffer {
int m_seqnum;
int m_chunk_count;
int m_chunk_num;
// number of chunks
int m_got = 0;
NetworkPacket m_list[] = null;
BufferedPacket m_reassembled = null;
BufferedPacket insert(NetworkPacket networkPacket)
throws PacketException
{
byte[] buffer = networkPacket.getBuffer();
int length = networkPacket.getLength();
int offset = networkPacket.getOffset();
int type = Serialize.readU8(buffer , offset, length);
int seqnum = Serialize.readU16(buffer, offset + 1, length);
// total number of chunk
int chunk_count = Serialize.readU16(buffer, offset + 3, length);
// this chunk number
int chunk_num = Serialize.readU16(buffer, offset+ 5, length);
System.out.println("Split length " + length + " type " + type + " seqnum " + seqnum + " chunk_num/chunk_count " + chunk_num + "/" + chunk_count );
// move to next header
networkPacket.addOffset(7);
if (m_reassembled != null)
{
return m_reassembled;
}
if (m_list == null )
{
m_list = new NetworkPacket[chunk_count];
}
if ( chunk_num < chunk_count && (m_list[chunk_num] == null) )
{
m_list[chunk_num] = networkPacket;
m_got ++;
}
//todo seqnum
m_seqnum = seqnum;
// fully obtained
if ( m_got == chunk_count )
{
reassemble();
}
return m_reassembled;
}
private void reassemble()
{
// keep first header since result is a valid BufferedPacket
int fullLength = BufferedPacket.BASE_HEADER_SIZE;
for (NetworkPacket networkPacket : m_list )
{
fullLength += networkPacket.getLength() - networkPacket.getOffset();
}
byte[] reassembled = new byte[fullLength];
NetworkPacket first = m_list[0];
System.arraycopy(first.getBuffer(),0,reassembled,0,BufferedPacket.BASE_HEADER_SIZE);
int offset = BufferedPacket.BASE_HEADER_SIZE;
for (NetworkPacket networkPacket : m_list )
{
int dataLength = networkPacket.getLength() - networkPacket.getOffset();
System.arraycopy(networkPacket.getBuffer(), networkPacket.getOffset(),reassembled,offset,dataLength);
offset+=dataLength;
}
m_reassembled = new BufferedPacket(reassembled);
}
}

View File

@@ -0,0 +1,127 @@
package org.artisanlogiciel.games.minetest.net;
import org.artisanlogiciel.games.minetest.core.PacketException;
import java.io.IOException;
import java.net.*;
/**
* Man in the middle UDP
* very simple for one client only
*/
public class MiM {
DatagramSocket serverSocket;
boolean running = false;
InetSocketAddress serverAddress;
// will be captured, incoming address & port
SocketAddress fromClient = null;
int localPort;
PacketHandler handler = null;
public MiM(int myPort, InetSocketAddress remoteAddress)
{
localPort = myPort;
serverAddress = remoteAddress;
}
public void launch()
{
// ServerSocket socket = new ServerSocket()
try {
handler = new PacketHandler();
serverSocket = new DatagramSocket(localPort);
DatagramSocket in = serverSocket;
SocketAddress fromServer = serverAddress;
Thread toServer = new Thread( () -> {runFromToServer(in,fromServer);});
running = true;
toServer.start();
}
catch(Exception e)
{
System.out.println("problem");
e.printStackTrace(System.err);
running = false;
}
}
public void stop()
{
running = false;
}
public void runFromToServer(DatagramSocket in, SocketAddress fromServer) {
try {
while (running) {
// quick way, a new buffer at each reception
// to handle split packets that are buffered
byte[] buf = new byte[4096];
SocketAddress toRemote = null;
DatagramPacket packet = new DatagramPacket(buf, buf.length);
in.receive(packet);
SocketAddress from = packet.getSocketAddress();
if ( from.equals(fromServer)) {
// no client yet
if ( fromClient == null )
{
continue;
}
fromServer(buf,packet.getLength());
toRemote = fromClient;
}
else
{
// record client
// later on to be smart : could try to record peer id ?
// will add a constraint : only one auth at a time
if ( fromClient == null ) {
fromClient = from;
}
fromClient(buf,packet.getLength());
toRemote = fromServer;
}
packet = new DatagramPacket(buf, packet.getLength(), toRemote);
in.send(packet);
}
}
catch( IOException ioException)
{
//
System.out.println("oops");
}
// socket.close();
}
void fromServer(byte[] buffer, int length)
{
try {
// reply from server
if (handler != null) {
handler.fromServer(buffer, length);
}
}
catch (PacketException packetException)
{
//
}
}
void fromClient(byte[] buffer, int length)
{
try {
// reply from client
if (handler != null) {
handler.fromClient(buffer, length);
}
}
catch (PacketException packetException)
{
//
}
}
}

View File

@@ -0,0 +1,70 @@
package org.artisanlogiciel.games.minetest.net;
import org.artisanlogiciel.games.minetest.core.PacketException;
import org.artisanlogiciel.games.minetest.core.Serialize;
import org.artisanlogiciel.games.minetest.core.v3s16;
import java.nio.ByteBuffer;
public class NetworkPacket {
int m_protocol_id;
int m_peer_id;
int m_channel;
public PacketType packetType;
// somehow a BufferedPacket ...
byte[] m_buffer; // m_data
// used part in buffer
int m_length; // m_datasize ?
// current header index in packet
int m_offset; // m_read_offset
short m_command = 0;
public NetworkPacket(int protocol_id, int peer_id, int channel, PacketType type, byte[] buffer, int length) {
this.m_protocol_id = protocol_id;
this.m_peer_id = peer_id;
this.m_channel = channel;
this.packetType = type;
m_buffer = buffer;
m_length = length;
m_offset = 0;
}
public int getChannel()
{
return m_channel;
}
public byte[] getBuffer()
{
return m_buffer;
}
public int getOffset() {
return m_offset;
}
public int getLength() {
return m_length;
}
void addOffset(int offset)
{
m_offset += offset;
}
// Serialization
public v3s16 v3s16()
throws PacketException
{
return Serialize.readV3S16(m_buffer, m_offset, m_length);
}
public ByteBuffer getByteBuffer()
{
ByteBuffer buffer = ByteBuffer.wrap(m_buffer,m_offset,m_length-m_offset);
return buffer;
}
}

View File

@@ -0,0 +1,287 @@
package org.artisanlogiciel.games.minetest.net;
import com.github.luben.zstd.Zstd;
import org.artisanlogiciel.games.minetest.MapBlock;
import org.artisanlogiciel.games.minetest.MapNode;
import org.artisanlogiciel.games.minetest.core.PacketException;
import org.artisanlogiciel.games.minetest.core.Serialize;
import org.artisanlogiciel.games.minetest.core.v2s16;
import org.artisanlogiciel.games.minetest.core.v3s16;
import java.nio.ByteBuffer;
/**
* see src/network/networkprotocol.h of minetest sources
*
*
* === NOTES ===
*
* A packet is sent through a channel to a peer with a basic header:
* Header (7 bytes):
* [0] u32 protocol_id
* [4] session_t sender_peer_id
* [6] u8 channel
* sender_peer_id:
* Unique to each peer.
* value 0 (PEER_ID_INEXISTENT) is reserved for making new connections
* value 1 (PEER_ID_SERVER) is reserved for server
* these constants are defined in constants.h
* channel:
* Channel numbers have no intrinsic meaning. Currently only 0, 1, 2 exist.
*
*
* */
public class PacketHandler {
ReliablePacketBuffer reliableBuffer = null;
IncomingSplitBuffer[] incomingChanneleSplitBuffer = new IncomingSplitBuffer[4];
// server serialization in hello version
int ser_version;
// minetest protocol should be 0x4f457403
static int readProtocolId(byte[] buffer, int length)
throws PacketException
{
return Serialize.readU32(buffer, 0, length);
}
static int readPeerId(byte[] buffer, int length)
throws PacketException
{
return Serialize.readU16(buffer,4,length);
}
static int readChannel(byte[] buffer, int length)
throws PacketException
{
return Serialize.readU8(buffer, 6, length);
}
NetworkPacket handleAny(byte[] buffer, int length)
throws PacketException
{
int protocol_id = readProtocolId(buffer, length);
int peer_id = readPeerId(buffer, length);
int channel = readChannel(buffer, length);
int type = Serialize.readU8(buffer,7,length);
PacketType packetType = PacketType.getPacketType(type);
NetworkPacket networkPacket = new NetworkPacket(protocol_id,peer_id,channel,packetType, buffer, length);
// offset of packet within buffer.
networkPacket.addOffset(BufferedPacket.BASE_HEADER_SIZE);
System.out.println("length " + length + " protocol_id " + String.format("%x", protocol_id) + " peer_id " + peer_id + " channel " + channel + " type " + packetType);
return networkPacket;
}
void handlePacketType_Control(NetworkPacket networkPacket)
throws PacketException {
}
void handlePacketType_Reliable(NetworkPacket networkPacket)
throws PacketException
{
// TODO handle misordered...
/*
if ( reliableBuffer == null )
{
reliableBuffer = new ReliablePacketBuffer();
}
BufferedPacket packet = new BufferedPacket(buffer);
int nextExpected = 0;
reliableBuffer.insert(packet, nextExpected);
*/
// handle nested packet
networkPacket.addOffset(3);
int offset = networkPacket.getOffset();
byte buffer[] = networkPacket.getBuffer();
int length = networkPacket.getLength();
PacketType packetType = PacketType.getPacketType(Serialize.readU8(buffer,offset,length));
System.out.println( "reliable " + packetType.toString());
switch (packetType)
{
case PACKET_TYPE_CONTROL:
//
handlePacketType_Control(networkPacket);
break;
case PACKET_TYPE_ORIGINAL:
handlePacketType_Original(networkPacket);
break;
case PACKET_TYPE_SPLIT:
handlePacketType_Split(networkPacket);
break;
case PACKET_TYPE_RELIABLE:
// this is an error, no nested reliable accepted.
throw new PacketException("nested reliable");
default: // error
throw new PacketException("unknown type");
}
}
void handleCommand_Hello(NetworkPacket networkPacket)
throws PacketException {
// u8 deployed serialisation version
ByteBuffer buffer = networkPacket.getByteBuffer();
int ser_ver = Serialize.readU8(buffer);
ser_version = ser_ver;
// u16 deployed network compression mode
int net_compress = Serialize.readU16(buffer);
// u16 deployed protocol version
int deployed = Serialize.readU16(buffer);
System.out.println(String.format("HELLO ser_ver=%d net_compress %d deployed %d", ser_ver,net_compress,deployed));
// u32 supported auth methods
// std::string username that should be used for legacy hash (for proper casing)
}
// clientpackethandler.cpp Client::handleCommand_BlockData(NetworkPacket* pkt)
// TOCLIENT_BLOCKDATA
void handleCommand_BlockData(NetworkPacket networkPacket)
throws PacketException
{
v3s16 p = networkPacket.v3s16();
// will be used to get vector...
// v2s16 p2d = new v2s16(p.X,p.Z);
System.out.println(String.format(" (X,Y,Z) %d %d %d", p.X, p.Y,p.Z));
//
networkPacket.addOffset(6);
// FIXME get it from handshake
int version = 28;
// Should be a MapBlock
MapBlock block = new MapBlock();
block.deSerialize(networkPacket.getByteBuffer(),version);
// now we have a block ! what to do with it ?
}
void handlePacketCommand(NetworkPacket networkPacket)
throws PacketException {
// consume type and ??? well ... 2
int command = Serialize.readU16(networkPacket.getBuffer(),networkPacket.getOffset(),networkPacket.getLength());
System.out.println(String.format("command %x length %d", command, networkPacket.getLength()));
networkPacket.addOffset(2);
// Original ... toClient - toServer
switch (command)
{
case 0x02:
{
System.out.println("TOCLIENT_HELLO");
handleCommand_Hello(networkPacket);
}
break;
case 0x20:
{
System.out.println("TOCLIENT_BLOCKDATA");
handleCommand_BlockData(networkPacket);
}
break;
case 0x4f:
{
//TOCLIENT_SET_SKY = 0x4f,
System.out.println("TOCLIENT_SET_SKY");
}
break;
}
}
void handlePacketType_Original(NetworkPacket networkPacket)
throws PacketException {
// eat original type 1.
networkPacket.addOffset(1);
handlePacketCommand(networkPacket);
}
void handlePacketType_Split(NetworkPacket networkPacket)
throws PacketException {
int channel = networkPacket.getChannel();
if ( channel < incomingChanneleSplitBuffer.length) {
IncomingSplitBuffer splitBuffer = incomingChanneleSplitBuffer[channel];
if ( splitBuffer == null )
{
splitBuffer = new IncomingSplitBuffer();
incomingChanneleSplitBuffer[channel] = splitBuffer;
}
if ( splitBuffer != null ) {
BufferedPacket bufferedPacket = splitBuffer.insert(networkPacket);
if ( bufferedPacket != null ) {
// well should handle it.
System.out.println("Reassembled packet size " + bufferedPacket.m_data.length);
// reset it.
incomingChanneleSplitBuffer[channel] = new IncomingSplitBuffer();
handleBufferedPacket(bufferedPacket);
}
}
}
else {
throw new PacketException("invalid channel " + channel);
}
}
void handleBufferedPacket(BufferedPacket bufferedPacket)
throws PacketException
{
// FIXME, why a BufferedPacket anyway since we finaly need a NetworkPacket ?
NetworkPacket networkPacket = new NetworkPacket(0,0,0, PacketType.PACKET_TYPE_ORIGINAL,bufferedPacket.m_data, bufferedPacket.size());
networkPacket.addOffset(BufferedPacket.BASE_HEADER_SIZE);
handlePacketCommand(networkPacket);
}
void fromServer(byte[] buffer, int length)
throws PacketException
{
System.out.print(" <- ");
NetworkPacket networkPacket = handleAny(buffer,length);
switch (networkPacket.packetType)
{
case PACKET_TYPE_CONTROL:
//
handlePacketType_Control(networkPacket);
break;
case PACKET_TYPE_RELIABLE:
//
handlePacketType_Reliable(networkPacket);
break;
case PACKET_TYPE_ORIGINAL:
handlePacketType_Original(networkPacket);
break;
case PACKET_TYPE_SPLIT:
handlePacketType_Split(networkPacket);
break;
default: // error
throw new PacketException("unknown type");
}
}
void fromClient(byte[] buffer, int length)
throws PacketException
{
System.out.print(" -> ");
handleAny(buffer,length);
}
}

View File

@@ -0,0 +1,27 @@
package org.artisanlogiciel.games.minetest.net;
public enum PacketType {
PACKET_TYPE_CONTROL,
PACKET_TYPE_ORIGINAL,
PACKET_TYPE_SPLIT,
PACKET_TYPE_RELIABLE,
PACKET_TYPE_ERROR;
static PacketType getPacketType(int value)
{
switch (value)
{
case 0:
return PACKET_TYPE_CONTROL;
case 1:
return PACKET_TYPE_ORIGINAL;
case 2:
return PACKET_TYPE_SPLIT;
case 3:
return PACKET_TYPE_RELIABLE;
default:
return PACKET_TYPE_ERROR;
}
}
}

View File

@@ -0,0 +1,20 @@
package org.artisanlogiciel.games.minetest.net;
import org.artisanlogiciel.games.minetest.core.PacketException;
import java.util.LinkedList;
import java.util.List;
public class ReliablePacketBuffer {
List<BufferedPacket> m_list = new LinkedList<>();
void insert(BufferedPacket packet, int nextExpected)
throws PacketException
{
//
int seqNum = packet.getSeqNum();
m_list.add(packet);
}
}

View File

@@ -0,0 +1,3 @@
/Maze3dParams.class
/Wall3d.class
/Wall3dStream.class

View File

@@ -0,0 +1,7 @@
/CharProvider.class
/LuaNumber.class
/LuaObject.class
/LuaSequence.class
/LuaString.class
/LuaTuple.class
/Parser.class

View File

@@ -62,7 +62,7 @@ public class Parser {
pushBackChar(c); pushBackChar(c);
if ( errors == null) if ( errors == null)
{ {
errors = new ArrayList(); errors = new ArrayList<String>();
} }
System.err.println(info); System.err.println(info);
errors.add(info); errors.add(info);

View File

@@ -0,0 +1,4 @@
/Node.class
/NodeRef.class
/OsmReader.class
/Way.class

View File

@@ -0,0 +1 @@
/OsmToDrawing.class

View File

@@ -37,9 +37,10 @@ public class OsmToDrawing {
public OsmToDrawing(OsmReader reader, int mulx, int muly) public OsmToDrawing(OsmReader reader, int mulx, int muly)
{ {
this.refx = reader.getMinlat(); this.refx = reader.getMinlon();
this.refy = reader.getMaxlat();
this.minlat = reader.getMinlat(); this.minlat = reader.getMinlat();
this.refy = reader.getMinlon();
this.minlon = reader.getMinlon(); this.minlon = reader.getMinlon();
this.maxlat = reader.getMaxlat(); this.maxlat = reader.getMaxlat();
this.maxlon = reader.getMaxlon(); this.maxlon = reader.getMaxlon();
@@ -92,7 +93,7 @@ public class OsmToDrawing {
boundserror ++; boundserror ++;
System.err.println("lon > minlon " + lon); System.err.println("lon > minlon " + lon);
} }
drawingLine.addPoint(new Point((int) ( (lon - refy ) * muly), (int) ( (lat - refx)* mulx ) )); drawingLine.addPoint(new Point((int) ( ( lon - refx ) * mulx), (int) ( ( refy - lat ) * muly ) ));
} }
return drawingLine; return drawingLine;
} }

View File

@@ -0,0 +1 @@
/UTF8Control.class

View File

@@ -0,0 +1 @@
/Xpm.class

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path=""/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.fx.ide.jdt.core.JAVAFX_CONTAINER"/>
<classpathentry kind="output" path=""/>
</classpath>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Karmazoff</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,15 @@
width = Width
height = Height
depth = Depth
north = North
south = South
east = East
west = West
resolve = Resolve
create = Create
save = Save
quit = Quit
title = A Maz ing
seed = seed
load = Load
reverse = Reverse

View File

@@ -0,0 +1,15 @@
width = Largeur
height = Hauteur
depth = Profondeur
north = Nord
south = Sud
east = Est
west = Ouest
resolve = Résoudre
create = Créer
save = Sauver
quit = Quitter
title = La Bireinte
seed = graine
load = Charger
reverse = Inverse

View File

@@ -0,0 +1,59 @@
PACKAGE=org.artisanlogiciel.games
PACKAGE_DIR=$(subst .,/,$(PACKAGE))
# maps with ant build.xml
OUT=../build
# external libraries
LIBS=../libs/artgaphics-0.1.0.jar
EDITOR=emacs
$(OUT):
echo "[ERROR] Missing $(OUT)"
# mkdir -p $(OUT)
clean:
@find $(PACKAGE_DIR) -name "*.class" -type f -print0|xargs -0 --no-run-if-empty rm 2>/dev/null
@find $(OUT) -name "*.class" -type f -print0|xargs -0 --no-run-if-empty rm 2>/dev/null
test:
echo "$(pwd)/$(PACKAGE_DIR)"
javac -sourcepath . -cp $(LIBS) -d $(OUT) $(PACKAGE_DIR)/LabyModel.java
javac -sourcepath . -cp $(LIBS) -d $(OUT) $(PACKAGE_DIR)/Main.java
java -cp $(OUT):$(LIBS):../lang $(PACKAGE).Main
run/%: $(OUT)
javac -cp $(LIBS):$(OUT) -d $(OUT) $(PACKAGE_DIR)/$(subst run/,,$@).java
java -cp $(OUT):$(LIBS) $(PACKAGE)/$(subst run/,,$@)
display: run/Display
display/%: $(OUT)
javac -cp $(LIBS) -d $(OUT) $(PACKAGE_DIR)/Display.java
java -cp $(OUT):$(LIBS) $(PACKAGE).Display $(subst display/,,$@)
compile/%:
javac -d $(OUT) $(PACKAGE_DIR)/$(subst compile/,,$@).java
$(PACKAGE_DIR)/%.java:
./generate_new.sh class $(subst .java,,$(subst $(PACKAGE_DIR)/,,$@))
interface/%:
./generate_new.sh interface package_dir=$(PACKAGE_DIR) $(subst interface/,,$@)
$(EDITOR) $(PACKAGE_DIR)/$(subst interface/,,$@).java
work/%: $(PACKAGE_DIR)/$(subst work/,,%).java
$(EDITOR) $<
work: work/LabyModel
save:
git citool
.PHONY: clean test work display work/% run/% save compile/% interface/%
# tried to avoid intermediate file removal : does not work
# .SECONDARY: $(PACKAGE_DIR)/%.java
# this does work : once precious intermediate file is not removed.
.PRECIOUS: $(PACKAGE_DIR)/%.java

View File

@@ -0,0 +1,24 @@
A Maze generator that keep all reverse paths to solutions.
See Makefile
#clean
make clean
#console
make test
#gui
make display
#code emacs : work/ClassName
make work/Display
#run a class
make run/Display
#save work with git (ie git citool )
make save
# create an interface
make interface/InterfaceName

View File

@@ -0,0 +1,16 @@
By pref
- rendering
GUI
* WALK it...
* regenerate it
CONSOLE :
* provide interactive ( view a part of maze )
- model
* saving in stream ( better than in toString() that basically fails... )
- format :
3D format ( for 3Dprinting )

19
lib/awk_lib.sh Normal file
View File

@@ -0,0 +1,19 @@
awk_inplace() {
local awk_script="$1"
local file="$2"
enforce file "$awk_script" exists
enforce file "$file" exists
local tmp_file='awkXXXXXXXXXX.out'
[[ -z $defer ]] && tmp_file=$(mktemp "$tmp_file")
enforcefile "$tmp_file" exists
execredirectto $tmp_file awk -f $awk_script $file
$metarun cp $tmp_file $file
$metarun rm $tmp_file
# gawk uniquely
# if gawk is wanted
# $metarun apt install gawk
# $metarun awk -i inplace -f $awk_script $file
}

43
lib/log_functions.sh Normal file
View File

@@ -0,0 +1,43 @@
# SHOULD BE INCLUDED WITH source or . from a bash script
# EXAMPLE
# log_functions=./log_functions.sh
# [[ -f $log_functions ]] || { echo "[FATAL] Missing $log_functions" >&2 ; exit 1 ;}
# source $log_functions
log_any()
{
priority=$1
shift
echo "[$priority] $@" >&2
}
log_fatal()
{
log_any FATAL "$*"
}
log_error()
{
log_any ERROR "$*"
}
log_warn()
{
log_any WARN "$*"
}
log_info()
{
log_any INFO "$*"
}
log_debug()
{
[[ -n $debug ]] && log_any DEBUG "$*"
}
verbose()
{
[[ -n $verbose ]] && log_any $verbose $@
}

990
lib/metascript.sh Normal file
View File

@@ -0,0 +1,990 @@
#!/bin/bash
# SPDX-FileCopyrightText: 2025 artlog@l0g.eu
# SPDX-License-Identifier: AGPL-3.0-or-later
#
# metascript to include
#
# to generate file header for caller script do :
# bash <relative_path_to>/metascript.sh header
# ex:
# bash lib/metascript.sh header
metascript_version=v1.0.0
# if called directly
if [[ "$0" =~ ^(.*)/metascript.sh$ ]]
then
prefix=${BASH_REMATCH[1]}
case $1 in
header)
cat <<EOF
#!/bin/bash
# SPDX-FileCopyrightText: 2025 artlog@l0g.eu
# SPDX-License-Identifier: AGPL-3.0-or-later
# header generated by $0 $1
# metascript_version=$metascript_version
toolsdir=$prefix
pushd \$toolsdir >/dev/null
toolsdir=\$(pwd)
source metascript.sh
popd >/dev/null
metarun=metarun
# change default to sudo if needed
# metasudo=sudo
while [[ \$# > 0 ]]
do
case "\$1" in
*)
parsemetaarg "\$1"
;;
esac
shift
done
usage
EOF
;;
version)
echo $metascript_version
;;
*)
echo "[WARNING] only header and version arguments are supported. (prefix=$prefix), this script is intended to be included not to be directly called." >&2
exit 1
esac
exit 0
fi
if [[ "$metascript_included" == "yes" ]]
then
log_warn "metascript already included ($0)"
else
metascript_included=yes
# at this step $(pwd) should be this of metascript.sh
# while $0 is this of caller script using metascript
if [[ -z $toolsdir ]]
then
# assume all tools are in lib/
toolsdir=$(dirname $(readlink -f $0))/lib
# all tools resources are relative to this directory
fi
if [[ -z $log_functions ]]
then
log_functions=$toolsdir/log_functions.sh
[[ -f $log_functions ]] || { echo "[FATAL] Missing $log_functions , toolsdir=$toolsdir script=$0" >&2 ; exit 1 ;}
source $log_functions
fi
metascript_usage()
{
cat <<EOF >&2
metascript commands :
help|usage help or usage of this {$0} tool. stop after usage display.
dryrun|show|showdoc display what should/will be done
defersource= script file defining defer() non standard function
defer= defer function to use, default is showdoc
toolsresourcesdir= where to pick resource
default to parent of script $toolsresourcesdir
mostly used with dryrun
apply default : will actual do work without defer
EOF
}
usage()
{
echo "[WARNING} no specific usage function for {$0}, to improve by developer" >&2
echo >&2
metascript_usage
}
showinfo()
{
echo "$@"
}
metarun()
{
$defer $metasudo "$@"
}
autoquoteargs()
{
echo -n "$1"
shift
while [[ $# > 0 ]]
do
if [[ "$1" =~ [\ \$] ]]
then
echo -n " '$1'"
else
echo -n " $1"
fi
shift
done
}
echoarray()
{
declare -a arr=("${@}")
declare -i len=${#arr[@]}
# Show passed array
for ((n = 0; n < len; n++))
do
echo -en " \"${arr[$n]}\""
done
echo
}
deferpipe()
{
cat
echo "# <previous line> | $@"
}
include_source()
{
if [[ -f $1 ]]
then
source $1
else
log_fatal "Missing $1 script"
exit 1
fi
}
showdoc()
{
if [[ $1 =~ ^tools/ ]]
then
# assumes it handles ENV_METASCRIPT_DEFER
"$@"
else
echo '```'
autoquoteargs "$@"
echo
echo '```'
fi
}
redirectto()
{
tofile=$1
if [[ -n $defer ]]
then
echo "Copy to $tofile"
echo '```'
cat
echo '```'
else
cat > $tofile
fi
}
execredirectfrom()
{
fromfile=$1
shift
enforcefile "$fromfile" exists
if [[ -n $defer ]]
then
echo '```'
autoquoteargs "$@"
echo ' < '"$fromfile"
echo '```'
else
"$@" < $fromfile
fi
}
execredirectto()
{
tofile=$1
shift
if [[ -n $defer ]]
then
echo '```'
autoquoteargs "$@"
echo ' > '"$tofile"
echo '```'
else
"$@" > $tofile
fi
}
execredirecttoroot()
{
tofile=$1
shift
if [[ -n $defer ]]
then
echo '```'
autoquoteargs "$@"
echo ' | sudo tee '"$tofile"' >/dev/null'
echo '```'
else
"$@" | sudo tee $tofile >/dev/null
fi
}
execredirectas_to()
{
while [[ $# > 0 ]]
do
case $1 in
user=*)
if [[ "$1" =~ ^user=([a-z]+[a-z0-9]*)$ ]]
then
asuser=${BASH_REMATCH[1]}
else
log_fatal "execredirecttouser missing user= in '$@'"
[[ -n $defer ]] || exit 1
fi
;;
chroot=*)
aschroot=${1/chroot=}
;;
*)
tofile=$1
shift
break
esac
shift
done
local command=()
if [[ -n $aschroot ]]
then
command=(sudo chroot)
if [[ -n $asuser ]]
then
# no group yet
command+=(--userspec=$asuser:$asuser)
fi
command+=($aschroot)
elif [[ -n $asuser ]]
then
command=(sudo -u $asuser)
fi
command+=(tee $tofile)
if [[ -n $defer ]]
then
echo '```'
autoquoteargs "$@"
echo ' | '"${command[@]}"' >/dev/null'
echo '```'
else
"$@" | "${command[@]}" >/dev/null
fi
}
pipeto()
{
if [[ -n $defer ]]
then
echo '```'
echo -n 'cat << EOF| '
autoquoteargs "$@"
echo
cat
echo "EOF"
echo '```'
else
cat | "$@"
fi
}
query_ext()
{
local prompt="$1"
local var=$2
if [[ -n $defer ]]
then
# uppercase it
eval $var=${var^^}
$defer query $prompt "$(eval echo \$$var)"
else
echo -ne $prompt
read $var
fi
}
# two arguments first prompt, second name of var
query_password()
{
local prompt="$1"
local var=$2
if [[ -n $defer ]]
then
# uppercase it
eval $var=${var^^}
$defer query_password "\"$prompt\"" "$(eval echo \$$var)"
else
read -sp "$prompt" $var
echo
fi
}
# echo yes if reply match ^[Yy]([eE][sS]|)$ or no if does not match.
query_yesno()
{
local prompt="$1"
local yesno=no
read -p "$prompt (Yes/No) " yesno
if [[ $yesno =~ ^[Yy]([eE][sS]|)$ ]]
then
echo yes
else
echo no
fi
}
# through hardcoded 'secret' variable
create_secret()
{
# global secret
# declare -g secret
# export -n secret
local -i length=$1
[[ -z $length ]] && length = 32
if (( length < 8 ))
then
log_warn "secret length $length < 8. very small"
fi
# secret=$(echo $RANDOM | md5sum | head -c $length)
secret=$(tr -dc A-Za-z0-9 </dev/urandom | head -c $length)
}
check_missing_dest_dir()
{
local dir=$1
if [[ -n $defer ]]
then
$defer "create $dir if it does not exist"
else
if [[ ! -d $dir ]]
then
echo "[ERROR] '$dir' does not exist please create it."
exit 1
fi
fi
}
sed_substitute_expr()
{
local from="$1"
shift
local to="$1"
shift
local s='/'
if [[ $from =~ [\\] ]]
then
# escape char \ should be doubled
from=${from//\\/\\\\}
fi
if [[ $from =~ $s ]]
then
# echo "[ERROR] character $s is prohibited due to sed usage" >&2
from=${from//$s/\\$s}
fi
if [[ $from =~ \[ ]]
then
from=${from//\[/\\\[}
fi
if [[ $from =~ \* ]]
then
from=${from//\*/\\\*}
fi
if [[ $from =~ ^(.*)\$$ ]]
then
from=${BASH_REMATCH[1]}'\$'
fi
if [[ $from =~ ^\^(.*)$ ]]
then
from='\^'${BASH_REMATCH[1]}
fi
if [[ $to =~ [\\] ]]
then
# escape char \ should be doubled
to=${to//\\/\\\\}
fi
if [[ $to =~ $s ]]
then
# echo "[ERROR] character $s is prohibited due to sed usage" >&2
# echo "This is a limitation of metascript.sh script, replaced by \$s" >&2
to=${to//$s/\\$s}
fi
if [[ $to =~ [\&] ]]
then
# echo "[ERROR] character & is prohibited due to sed usage" >&2
to=${to//\&/\\\&}
fi
# replace it globaly
echo "s$s$from$s$to${s}g"
}
sedreplacefromto()
{
local from="$1"
local to="$2"
shift 2
local sedexpr="$1"
execredirectto $to sed "$sedexpr" $from
shift
while [[ $# > 0 ]]
do
sedexpr="$1"
$defer sed -i "$sedexpr" $to
shift
done
}
replacefromto()
{
local from="$1"
local to="$2"
shift 2
if [[ -n $defer ]]
then
$defer "replace $@ from '$from' into '$to'"
else
local sedexpr=$(sed_substitute_expr "$1" "$2")
execredirectto $to sed "$sedexpr" $from
shift 2
while [[ $# > 0 ]]
do
sedexpr=$(sed_substitute_expr "$1" "$2")
$defer sed -i "$sedexpr" $to
shift 2
done
fi
}
sedreplacein()
{
local file=$1
shift
while [[ $# > 0 ]]
do
$defer sed -i "$1" $file
shift
done
}
replacein()
{
local infile=$1
shift
if [[ -n $defer ]]
then
$defer "replace $@ into '$infile'"
else
while [[ $# > 0 ]]
do
sedexpr=$(sed_substitute_expr "$1" "$2")
$defer sed -i "$sedexpr" $infile
shift 2
done
fi
}
parsemetaarg()
{
case $1 in
apply)
defer=
;;
defersource=*)
defersource=${1/defersource=/}
;;
defer=*)
defer=${1/defer=/}
;;
dryrun|show|showdoc)
defer=showdoc
;;
debug)
set -ex
;;
metasudo=*)
metasudo=${1/metasudo=}
;;
help|usage)
usage
exit 0
;;
toolsresourcesdir=*)
toolsresourcesdir=${1/toolsresourcesdir=/}
;;
scl_enable=*)
scl_args=(scl enable ${1/scl_enable=/} --)
;;
*)
log_error "unrecognized argument '$1'"
usage
exit 1
;;
esac
}
enforcearg()
{
local var="$1"
local default="$2"
eval value='$'"$var"
if [[ -z $value ]]
then
log_error "{$0} expect '$var' to be set ex $var=$default"
if [[ -n $defer ]]
then
[[ -z $default ]] && default="DEFAULT"
log_warn "in defer/dryrun force $var=$default"
eval "$var=$default"
else
usage
exit 1
fi
fi
}
enforce()
{
objecttype=$1
shift
case $objecttype in
file|dir)
object=$1
shift
constraint=$1
case $constraint in
exists|does_not_exist|create_if_needed)
enforce${objecttype} "$object" "$@"
;;
*)
log_error "enforce $objecttype '$object' $@"
log_fatal "constraint '$constraint' unsupported. Please fix the code."
exit 1
;;
esac
;;
var|arg)
enforcearg "$@"
;;
*)
log_error "enforce $objecttype $@"
log_fatal "objectttype $objecttype unsupported"
exit 1
;;
esac
}
enforcefile()
{
local file="$1"
local constraint="$2"
if [[ ! -f "$file" ]]
then
case $constraint in
exists)
log_error "Missing expected $file"
[[ -n $defer ]] || exit 1
;;
create_if_needed)
$metarun touch $file
;;
esac
else
if [[ $constraint = does_not_exist ]]
then
log_error "'$file' already exists. Move it away"
[[ -n $defer ]] || exit 1
fi
fi
}
enforcedir()
{
local dir="$1"
local constraint="$2"
if [[ -e $dir ]]
then
case $constraint in
does_not_exist)
if [[ -d "$dir" ]]
then
log_error "'$dir' already exists"
[[ -n $defer ]] || exit 1
else
log_error "'$dir' already exists and is not a directory as expected"
[[ -n $defer ]] || exit 1
fi
;;
create_if_needed|exists)
if [[ ! -d "$dir" ]]
then
log_error "'$dir' already exists and is not a directory as expected"
[[ -n $defer ]] || exit 1
fi
;;
esac
else
case $constraint in
exists)
log_error "Missing expected directory $dir"
[[ -n $defer ]] || exit 1
;;
create_if_needed)
if [[ ! -d "$dir" ]]
then
$metarun mkdir -p "$dir"
fi
;;
esac
fi
}
applymetaargs()
{
if [[ -n $defer ]]
then
if [[ -n $defersource ]]
then
if [[ -f $defersource ]]
then
log_any "source $defersource"
source $defersource
else
exit_fatal "defersource $defersource provided but not a file"
fi
fi
# $showinfo "generated with $0 $allparms"
export ENV_METASCRIPT_DEFER="$defer"
export ENV_METASCRIPT_RESOURCESDIR="$toolsresourcesdir"
fi
}
defaultmetainit()
{
while [[ $# > 0 ]]
do
parsemetaarg "$1"
shift
done
applymetaargs
}
read_organisation()
{
organisation_file=$(find organisation -name '*.conf')
if [[ -f $organisation_file ]]
then
while read line
do
case $line in
name=*)
organisation_name=${line/name=/}
;;
domain=*)
organisation_domain=${line/domain=/}
;;
ldap_base=*)
organisation_ldap_base=${line/ldap_base=/}
;;
image_keyword=*)
organisation_image_keyword=${line/image_keyword=/}
;;
*)
log_warn "'$line' not recognized as an organisation parameter"
;;
esac
done < $organisation_file
fi
}
check_variable_match()
{
local var="$1"
local match="$2"
local default="$3"
local value=""
eval value='$'"$var"
if [[ -z "$value" ]]
then
echo "set $var to default value $default"
eval "$var=$default"
eval value='$'"$var"
fi
if [[ ! $value =~ $match ]]
then
log_error "$var $value should match $match"
exit 1
fi
}
check_variable_in()
{
local var="$1"
local default="$2"
shift 2
local value=""
local values="$@"
eval value='$'"$var"
if [[ -z "$value" ]]
then
echo "set $var to default value $default"
eval "$var=$default"
eval value='$'"$var"
fi
while [[ $# > 0 ]]
do
if [[ "$value" = "$1" ]]
then
return
fi
shift
done
log_error "'$var' should be within $values it is '$value'"
exit 1
}
check_root()
{
if [[ -n $defer ]]
then
$defer "{$0} script to run run as root or with sudo"
else
[[ $EUID -eq 0 ]] || {
log_error "{$0} You have to be root or use sudo to run this script"
exit 1;
}
fi
}
get_timestamp_second()
{
echo "$(date +"%Y%m%d%H%M%S")"
}
todo()
{
log_any TODO "$@"
}
get_resource_var() {
local varname="$1"
local default_value="$2"
eval value='$'"$varname"
if [[ -z $value ]]
then
echo "# ($0:metascript.sh:$LINENO) $(date)" >>$collect_context
if [[ -z $default_value ]]
then
log_error "resource $varname does not exists and no non empty default provided"
echo "# $varname=<MISSING>" >>$collect_context
exit 1
fi
log_warn "($0) Using default value '$varname'='$default_value' HARDCODED in script : should be fixed with proper default file .resources.var, see traces in $collect_context"
read "$varname" <<<"$default_value"
echo "$varname=$default_value" >>$collect_context
fi
}
setup_resources_var()
{
local resource_var="$1"
enforcefile "$resource_var" exists
if [[ -f $resource_var ]]
then
while read line
do
if [[ $line =~ ^([a-zA-Z0-9_]+)=(.+)$ ]]
then
varname=${BASH_REMATCH[1]}
value=${BASH_REMATCH[2]}
read "$varname" <<<"$value"
elif [[ $line =~ ^# ]]
then
if [[ -n $defer ]]
then
$defer : "$line"
fi
else
log_warn "Invalid syntax in $resource_var '$line' does not match any expected expression"
fi
done <"$resource_var"
fi
}
# allow to check mounted points
mountpoint_get_device()
{
local mount_point="$1"
mount_point=$(readlink -f "$mount_point")
$defer awk "{ if (\$2 == \""$mount_point"\") print \$1 ;}" /proc/mounts
}
device_get_mountpoints()
{
local device="$1"
$defer awk "{ if (\$1 == \""$device"\") print \$2 ;}" /proc/mounts
}
mount_if_needed()
{
local mountdevice="$1"
local mountpoint="$2"
local param="$3"
if [[ -n $defer ]]
then
$defer 'device=$(mountpoint_get_device '"$mountpoint"')'
else
device=$(mountpoint_get_device "$mountpoint")
fi
enforcedir "$mountpoint" exists
# device is a device ...
# enforcefile "$mountdevice" exists
if [[ -z $device ]]
then
$metarun mount $param "$mountdevice" "$mountpoint"
elif [[ "$device" == "$mountdevice" ]]
then
log_info "$device already mounted on $mountdevice"
else
log_warn "Another device $device is mounted on $mountpoint, not $mountdevice"
fi
}
umount_if_needed()
{
local mountdevice="$1"
local mountpoint="$2"
local param="$3"
device=$(mountpoint_get_device "$mountpoint")
if [[ -n "$device" ]]
then
if [[ "$device" == "$mountdevice" ]]
then
$metarun umount "$mountpoint"
else
log_warn "Another device $device is mounted on $mountpoint, not $mountdevice"
if [[ $param == '--bind' ]]
then
log_warn "Unmouning ANYWAY ( mount --bind show root device, not mounted directory )"
$metarun umount "$mountpoint"
fi
fi
else
log_warn "no device found mounted for umount_if_needed $@"
fi
}
exec_bg()
{
if [[ -z $defer ]]
then
"$@" &
else
$defer "$@" '&'
fi
}
# collect all hardcoded values.
mkdir -p ~/.artlog
collect_context=~/.artlog/collect_context.var
if [[ -z $toolsresourcesdir ]]
then
# project directory
# from current $(pwd) will follow parent dir hierarchy to find .resources.var
dir="$(pwd)"
while [[ -n $dir ]] && [[ -d $dir ]] && [[ ! -f $dir/.resources.var ]]
do
new_dir=$(dirname "$dir")
if [[ $new_dir == $dir ]]
then
# protect against infinite loop
break
fi
dir="$new_dir"
done
if [[ -f $dir/.resources.var ]]
then
toolsresourcesdir=$dir
else
if [[ -z $ENV_METASCRIPT_RESOURCESDIR ]]
then
toolsresourcesdir=$toolsparentdir
else
toolsresourcesdir=$ENV_METASCRIPT_RESOURCESDIR
fi
fi
fi
resources_var=$toolsresourcesdir/.resources.var
if [[ -f $resources_var ]]
then
setup_resources_var "$resources_var"
else
log_warn "No $resources_var found"
fi
# quick way to give scl patches to fill scl_arg array
if [[ -f $toolsresourcesdir/.scl_env ]]
then
source $toolsresourcesdir/.scl_env
fi
# empty defer means doit
defer=$ENV_METASCRIPT_DEFER
showinfo=showinfo
allparms="$@"
applymetaargs=applymetaargs
metarun=$defer
# metascript included
fi

82
printclonesdep.sh Executable file
View File

@@ -0,0 +1,82 @@
#!/bin/bash
# SPDX-FileCopyrightText: 2025 artlog@l0g.eu
# SPDX-License-Identifier: AGPL-3.0-or-later
# header generated by lib/metascript.sh header
# metascript_version=v1.0.0
toolsdir=lib
pushd $toolsdir >/dev/null
toolsdir=$(pwd)
source metascript.sh
popd >/dev/null
usage () {
cat <<EOF
output list of clones and current git commit references
for this project and projects dependencies ( clones.dep )
EOF
}
metarun=metarun
# change default to sudo if needed
# metasudo=sudo
while [[ $# > 0 ]]
do
case "$1" in
*)
parsemetaarg "$1"
;;
esac
shift
done
get_git_info()
{
local clone=$1
echo "[$clone]"
echo "path=$(realpath --relative-to=$absolute $(pwd))"
echo "remote.origin.url=$(git config --get remote.origin.url)"
echo "head=$(< .git/$(git symbolic-ref HEAD))"
# echo "branch=$(git branch)"
}
absolute=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
pushd $absolute >/dev/null
echo "#"
echo "# root.absolute=$absolute"
echo "# date=$(date)"
project_name=.
if [[ -f project_params ]]
then
project_name=$(grep "project_name" project_params)
project_name=${project_name/project_name=/}
fi
# expect . to be in cube
get_git_info $project_name
if [[ -f clones.dep ]]
then
clones=$(< clones.dep)
for clone in $clones
do
directory=$clone
if [[ -d $directory ]]
then
pushd $directory >/dev/null
get_git_info $clone
popd >/dev/null
else
log_error "clone $clone not found in $directory"
fi
done
else
log_info "no clone.deps file"
fi
popd >/dev/null

View File

@@ -9,7 +9,3 @@ head=a22a2fd1b6eec74cd4a37f086ff01d46a50d8a9b
path=../sharedrawweb path=../sharedrawweb
remote.origin.url=ssh://philippe@www4.artisanlogiciel.net:2023/home/philippe/artisanlogiciel/code/sharedrawweb remote.origin.url=ssh://philippe@www4.artisanlogiciel.net:2023/home/philippe/artisanlogiciel/code/sharedrawweb
head=c217d96129b5f83c26c041f766718b6bdf93a2d6 head=c217d96129b5f83c26c041f766718b6bdf93a2d6
[artlog_toolbox]
path=../artlog_toolbox
remote.origin.url=ssh://philippe@www4.artisanlogiciel.net:2023/home/philippe/artisanlogiciel/code/artlog_toolbox
head=ea7e49c578d89ec4c7f41fd5b526e3ef4a8dbb37

View File

@@ -3,5 +3,5 @@ project_default=dist
project_basedir=$(pwd) project_basedir=$(pwd)
project_mainpackage=org.artisanlogiciel.games project_mainpackage=org.artisanlogiciel.games
project_mainclass=$project_mainpackage.maze.gui.Display project_mainclass=$project_mainpackage.maze.gui.Display
project_version=1.1 project_version=1.2
default_args='lab/lab30x30.raw' default_args='lab/lab30x30.raw'

View File

@@ -1 +0,0 @@
ARTLOG_TOOLBOX=../artlog_toolbox