From a22a2fd1b6eec74cd4a37f086ff01d46a50d8a9b Mon Sep 17 00:00:00 2001 From: philippe lhardy Date: Fri, 28 Jul 2023 10:27:18 +0200 Subject: [PATCH 1/6] better dependencies fetching - provide git url for sharedrawweb --- BUILD.md | 18 ++++++++++++++++++ README | 2 +- fetch_dependencies.sh | 19 ++++++++++++++++++- 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 BUILD.md diff --git a/BUILD.md b/BUILD.md new file mode 100644 index 0000000..56ffe6a --- /dev/null +++ b/BUILD.md @@ -0,0 +1,18 @@ + +===== How to build this project ? ===== + +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 + +within same directory as this BUILD.md : + +``` +./init.sh +# will create build scripts from artlog_toolbox +# ./doit.sh +# depends on sharedrawweb for stl export +./fetch_dependencies.sh +ant dist +``` + diff --git a/README b/README index b7e1822..7bb598b 100644 --- a/README +++ b/README @@ -9,7 +9,7 @@ After years i finaly printed one maze, find it at https://www.thingiverse.com/th 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. -there is a console gui menu base with ./doit.sh +There is a console gui menu based with ./doit.sh requirement : you need a java jdk environment installed ( java + javac ) and ant diff --git a/fetch_dependencies.sh b/fetch_dependencies.sh index c72584c..29694f7 100755 --- a/fetch_dependencies.sh +++ b/fetch_dependencies.sh @@ -1,5 +1,20 @@ #!/bin/bash +log_any() +{ + echo "$@" >&2 +} + +log_error() +{ + log_any "[ERROR] $@" +} + +log_info() +{ + log_any "[INFO] $@" +} + fetch_jackson_databind() { @@ -16,7 +31,9 @@ fetch_jackson_databind() if [[ ! -d ../sharedrawweb ]] then - echo "[ERROR] expected a sharedrawweb project parent ( for exports )" >&2 + log_error "expected a sharedrawweb project parent ( for exports ). Please clone related project." + sharedrawweb_git_url="ssh://philippe@www4.artisanlogiciel.net:2023/home/philippe/artisanlogiciel/code/sharedrawweb" + log_info "cd ..; git clone sharedrawweb_git_url" fi if [[ ! -d libs ]] From f76f9e17fb814e7a4963d9cef91a7ac611ef535d Mon Sep 17 00:00:00 2001 From: philippe lhardy Date: Fri, 28 Jul 2023 12:04:15 +0200 Subject: [PATCH 2/6] move git url in project.gitref change init.sh - init.sh now parse project.gitref - generate project.gitref that contains git dependencies ./printclonesdep.sh >project.gitref - update fetch_dependencies --- fetch_dependencies.sh | 20 +++++++++++----- init.sh | 53 +++++++++++++++++++++++++++++++++++-------- project.gitref | 15 ++++++++++++ 3 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 project.gitref diff --git a/fetch_dependencies.sh b/fetch_dependencies.sh index 29694f7..b7cf21d 100755 --- a/fetch_dependencies.sh +++ b/fetch_dependencies.sh @@ -18,7 +18,6 @@ log_info() fetch_jackson_databind() { - libversion_jackson_databind=2.12.0 lib_jackson_databind=jackson-databind-${libversion_jackson_databind}.jar if [[ ! -e libs/$lib_jackson_databind ]] then @@ -29,11 +28,16 @@ fetch_jackson_databind() fi } + +libversion_jackson_databind=2.12.0 +sharedrawweb_git_url="ssh://philippe@www4.artisanlogiciel.net:2023/home/philippe/artisanlogiciel/code/sharedrawweb" +libversion_artgaphic=0.2.0 +lib_artgaphic=artgaphics-${libversion_artgaphic}.jar + if [[ ! -d ../sharedrawweb ]] then log_error "expected a sharedrawweb project parent ( for exports ). Please clone related project." - sharedrawweb_git_url="ssh://philippe@www4.artisanlogiciel.net:2023/home/philippe/artisanlogiciel/code/sharedrawweb" - log_info "cd ..; git clone sharedrawweb_git_url" + log_info "cd ..; git clone $sharedrawweb_git_url" fi if [[ ! -d libs ]] @@ -41,11 +45,15 @@ then mkdir libs fi -libversion_artgaphic=0.2.0 -lib_artgaphic=artgaphics-${libversion_artgaphic}.jar if [[ ! -e libs/$lib_artgaphic ]] then - ln -s ../../sharedrawweb/dist/lib/$lib_artgaphic libs/ + lib_artgaphic_source_file=../../sharedrawweb/dist/lib/$lib_artgaphic + if [[ -f $lib_artgaphic_source_file ]] + then + ln -s $lib_artgaphic_source_file libs/ + else + log_error "Missing $lib_artgaphic_source_file. It is require to build it sharedrawweb project first" + fi fi if [[ -n $use_jackson ]] diff --git a/init.sh b/init.sh index 099a116..a7fb5e2 100755 --- a/init.sh +++ b/init.sh @@ -1,11 +1,46 @@ #!/bin/bash -if [[ ! -d artlog_toolbox ]] -then - git clone https://github.com/artlog/artlog_toolbox.git artlog_toolbox -fi -pushd artlog_toolbox -git checkout master -popd -artlog_toolbox/deploy.sh -./doit.sh +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 +project= +gitref=project.gitref + +while read line +do + if [[ $line =~ \[([_a-z]*)\] ]] + then + project=${BASH_REMATCH[1]} + elif [[ $line =~ remote.origin.url=(.*) ]] + then + remote_origin_url=${BASH_REMATCH[1]} + echo "$project $remote_origin_url" + case $project in + sharedrawweb) + sharedrawweb_remote_origin_url=$remote_origin_url + ;; + artloglaby) + artloglaby_remote_origin_url=$remote_origin_url + ;; + artlog_toolbox) + artlog_toolbox_remote_origin_url=$remote_origin_url + ;; + *) + echo "ERROR unrecognized project='$project' line='$line'" + ;; + esac + fi +done <$gitref + +setup diff --git a/project.gitref b/project.gitref new file mode 100644 index 0000000..3256b03 --- /dev/null +++ b/project.gitref @@ -0,0 +1,15 @@ +# +# root.absolute=/home/plhardy/artisanlogiciel/testbed/laby +# date=ven. 28 juil. 2023 11:59:40 CEST +[artloglaby] +path=. +remote.origin.url=ssh://philippe@www4.artisanlogiciel.net:2023/home/philippe/artisanlogiciel/code/laby +head=a22a2fd1b6eec74cd4a37f086ff01d46a50d8a9b +[sharedrawweb] +path=../sharedrawweb +remote.origin.url=ssh://philippe@www4.artisanlogiciel.net:2023/home/philippe/artisanlogiciel/code/sharedrawweb +head=c217d96129b5f83c26c041f766718b6bdf93a2d6 +[artlog_toolbox] +path=../artlog_toolbox +remote.origin.url=ssh://philippe@www4.artisanlogiciel.net:2023/home/philippe/artisanlogiciel/code/artlog_toolbox +head=ea7e49c578d89ec4c7f41fd5b526e3ef4a8dbb37 From a8c11ad3d7b778eae3c8c9c750b42dd064bfb1d9 Mon Sep 17 00:00:00 2001 From: philippe lhardy Date: Fri, 28 Jul 2023 12:41:36 +0200 Subject: [PATCH 3/6] fix fetch_dependencies --- fetch_dependencies.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fetch_dependencies.sh b/fetch_dependencies.sh index b7cf21d..32173f9 100755 --- a/fetch_dependencies.sh +++ b/fetch_dependencies.sh @@ -47,10 +47,11 @@ fi if [[ ! -e libs/$lib_artgaphic ]] then - lib_artgaphic_source_file=../../sharedrawweb/dist/lib/$lib_artgaphic + lib_artgaphic_source_file=../sharedrawweb/dist/lib/$lib_artgaphic if [[ -f $lib_artgaphic_source_file ]] then - ln -s $lib_artgaphic_source_file libs/ + # ../ since libs is one level below current project + ln -s ../$lib_artgaphic_source_file libs/ else log_error "Missing $lib_artgaphic_source_file. It is require to build it sharedrawweb project first" fi From 3f24daed24754901f05d35f3cb090da1fa059232 Mon Sep 17 00:00:00 2001 From: philippe lhardy Date: Fri, 28 Jul 2023 12:42:36 +0200 Subject: [PATCH 4/6] fix '\n' in jar name - add ignorebalk and striplinebreaks to avoid additional wrong '\n' in dist jar --- build.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build.xml b/build.xml index c214aa5..c96e0e4 100644 --- a/build.xml +++ b/build.xml @@ -20,10 +20,12 @@ - + + + - + From d789870fbc304e54b2a9e4fcad88f7c7eba5217d Mon Sep 17 00:00:00 2001 From: philippe lhardy Date: Fri, 28 Jul 2023 18:22:44 +0200 Subject: [PATCH 5/6] README split BUILD INSTALL and RUN --- BUILD.md | 8 ++++++++ README | 36 ++++++++++++++++++++++-------------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/BUILD.md b/BUILD.md index 56ffe6a..6e73a06 100644 --- a/BUILD.md +++ b/BUILD.md @@ -16,3 +16,11 @@ within same directory as this BUILD.md : ant dist ``` + +Then create de .zip + +``` +source ./specificdoit.sh; create_zip_package +``` + +you ccan then provide and copy laby.zip to install it. \ No newline at end of file diff --git a/README b/README index 7bb598b..16975a9 100644 --- a/README +++ b/README @@ -15,22 +15,30 @@ requirement : you need a java jdk environment installed ( java + javac ) and ant ex ubuntu : sudo apt-get install default-jdk ant -run it by : +===== BUILD ===== -________Linux distribution_____________________ +See BUILD.md + + +===== INSTALL ===== + +obtain laby.zip directly build or from you own build ( see BUILD above ). + +``` +unzip laby.zip +``` + +it will create a artloglaby directory. + +===== RUN ===== + +run it on a Linux distribution with : + + +``` +cd artloglaby ; ./laby.sh +``` -mkdir github -cd github -git clone https://github.com/artlog/labystl.git -cd labystl -./init.sh -# will create build scripts from artlog_toolbox -# ./doit.sh -# depends on sharedrawweb for stl export -./fetch_dependencies.sh -ant dist -source ./specificdoit.sh; create_zip_package -unzip laby.zip; cd artloglaby ; ./laby.sh _______________________________________________ Save raw will actualy create a stl file From 9792b79c560d51eda23b565ad7a49ea9a9c49fb6 Mon Sep 17 00:00:00 2001 From: philippe lhardy Date: Sun, 30 Jul 2023 10:18:45 +0200 Subject: [PATCH 6/6] 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 --- .idea/ant.xml | 6 + .idea/laby.iml | 1 + .idea/libraries/artgaphics_0_1_0.xml | 9 - .idea/libraries/zstd_jni_1_5_2_2.xml | 9 + build.xml | 7 +- fetch_dependencies.sh | 17 ++ .../artisanlogiciel/games/maze/MainMim.java | 26 ++ .../games/maze/gui/Display.java | 3 + .../games/minetest/MapBlock.java | 97 ++++++ .../games/minetest/MapNode.java | 99 ++++++ .../artisanlogiciel/games/minetest/Node.java | 1 + .../games/minetest/core/Constant.java | 6 + .../games/minetest/core/PacketException.java | 10 + .../games/minetest/core/Serialize.java | 116 +++++++ .../games/minetest/core/v2s16.java | 13 + .../games/minetest/core/v3s16.java | 14 + .../games/minetest/net/Address.java | 4 + .../games/minetest/net/BufferedPacket.java | 28 ++ .../games/minetest/net/Channel.java | 9 + .../games/minetest/net/ConnectionEvent.java | 45 +++ .../minetest/net/ConnectionEventPtr.java | 4 + .../minetest/net/ConnectionEventType.java | 9 + .../minetest/net/IncomingSplitBuffer.java | 90 ++++++ .../games/minetest/net/MiM.java | 127 ++++++++ .../games/minetest/net/NetworkPacket.java | 70 +++++ .../games/minetest/net/PacketHandler.java | 287 ++++++++++++++++++ .../games/minetest/net/PacketType.java | 27 ++ .../minetest/net/ReliablePacketBuffer.java | 20 ++ project_params | 2 +- 29 files changed, 1144 insertions(+), 12 deletions(-) create mode 100644 .idea/ant.xml delete mode 100644 .idea/libraries/artgaphics_0_1_0.xml create mode 100644 .idea/libraries/zstd_jni_1_5_2_2.xml create mode 100644 java/org/artisanlogiciel/games/maze/MainMim.java create mode 100644 java/org/artisanlogiciel/games/minetest/MapBlock.java create mode 100644 java/org/artisanlogiciel/games/minetest/MapNode.java create mode 100644 java/org/artisanlogiciel/games/minetest/core/Constant.java create mode 100644 java/org/artisanlogiciel/games/minetest/core/PacketException.java create mode 100644 java/org/artisanlogiciel/games/minetest/core/Serialize.java create mode 100644 java/org/artisanlogiciel/games/minetest/core/v2s16.java create mode 100644 java/org/artisanlogiciel/games/minetest/core/v3s16.java create mode 100644 java/org/artisanlogiciel/games/minetest/net/Address.java create mode 100644 java/org/artisanlogiciel/games/minetest/net/BufferedPacket.java create mode 100644 java/org/artisanlogiciel/games/minetest/net/Channel.java create mode 100644 java/org/artisanlogiciel/games/minetest/net/ConnectionEvent.java create mode 100644 java/org/artisanlogiciel/games/minetest/net/ConnectionEventPtr.java create mode 100644 java/org/artisanlogiciel/games/minetest/net/ConnectionEventType.java create mode 100644 java/org/artisanlogiciel/games/minetest/net/IncomingSplitBuffer.java create mode 100644 java/org/artisanlogiciel/games/minetest/net/MiM.java create mode 100644 java/org/artisanlogiciel/games/minetest/net/NetworkPacket.java create mode 100644 java/org/artisanlogiciel/games/minetest/net/PacketHandler.java create mode 100644 java/org/artisanlogiciel/games/minetest/net/PacketType.java create mode 100644 java/org/artisanlogiciel/games/minetest/net/ReliablePacketBuffer.java diff --git a/.idea/ant.xml b/.idea/ant.xml new file mode 100644 index 0000000..a2a4769 --- /dev/null +++ b/.idea/ant.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/laby.iml b/.idea/laby.iml index 4b248d8..fd89b37 100644 --- a/.idea/laby.iml +++ b/.idea/laby.iml @@ -25,5 +25,6 @@ + \ No newline at end of file diff --git a/.idea/libraries/artgaphics_0_1_0.xml b/.idea/libraries/artgaphics_0_1_0.xml deleted file mode 100644 index f00ac9e..0000000 --- a/.idea/libraries/artgaphics_0_1_0.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/zstd_jni_1_5_2_2.xml b/.idea/libraries/zstd_jni_1_5_2_2.xml new file mode 100644 index 0000000..fadbd62 --- /dev/null +++ b/.idea/libraries/zstd_jni_1_5_2_2.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/build.xml b/build.xml index c96e0e4..9a0b638 100644 --- a/build.xml +++ b/build.xml @@ -10,8 +10,11 @@ - + + @@ -38,7 +41,7 @@ - + diff --git a/fetch_dependencies.sh b/fetch_dependencies.sh index 32173f9..f76e958 100755 --- a/fetch_dependencies.sh +++ b/fetch_dependencies.sh @@ -28,12 +28,24 @@ fetch_jackson_databind() 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 . + pushd libs + wget https://repo1.maven.org/maven2/com/github/luben/zstd-jni/${libversion_zstdjni}/zstd-jni-${libversion_zstdjni}.jar + popd +} + +libversion_zstdjni=1.5.2-2 libversion_jackson_databind=2.12.0 sharedrawweb_git_url="ssh://philippe@www4.artisanlogiciel.net:2023/home/philippe/artisanlogiciel/code/sharedrawweb" libversion_artgaphic=0.2.0 lib_artgaphic=artgaphics-${libversion_artgaphic}.jar + if [[ ! -d ../sharedrawweb ]] then log_error "expected a sharedrawweb project parent ( for exports ). Please clone related project." @@ -61,3 +73,8 @@ if [[ -n $use_jackson ]] then fetch_jackson_databind fi + +if [[ -n $use_zstd ]] +then + fetch_zstd-jni +fi diff --git a/java/org/artisanlogiciel/games/maze/MainMim.java b/java/org/artisanlogiciel/games/maze/MainMim.java new file mode 100644 index 0000000..936b7b9 --- /dev/null +++ b/java/org/artisanlogiciel/games/maze/MainMim.java @@ -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"); + } + } +} + diff --git a/java/org/artisanlogiciel/games/maze/gui/Display.java b/java/org/artisanlogiciel/games/maze/gui/Display.java index e070636..028ee7f 100644 --- a/java/org/artisanlogiciel/games/maze/gui/Display.java +++ b/java/org/artisanlogiciel/games/maze/gui/Display.java @@ -4,6 +4,7 @@ import org.artisanlogiciel.games.maze.*; import org.artisanlogiciel.games.maze.model.WidthHeightProvider; import org.artisanlogiciel.games.maze.persist.MazePersistRaw; import org.artisanlogiciel.games.maze.solve.SolvingModel; +import org.artisanlogiciel.games.minetest.net.MiM; import org.artisanlogiciel.graphics.Drawing; import org.artisanlogiciel.xpm.Xpm; @@ -14,6 +15,7 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.net.InetSocketAddress; import java.util.Locale; /** @@ -270,6 +272,7 @@ implements StatusListener } }; + System.out.println("Default Locale " + Locale.getDefault()); if ((pArgs.length > 0) && (pArgs[0].length() > 0)) { diff --git a/java/org/artisanlogiciel/games/minetest/MapBlock.java b/java/org/artisanlogiciel/games/minetest/MapBlock.java new file mode 100644 index 0000000..5d5b3b4 --- /dev/null +++ b/java/org/artisanlogiciel/games/minetest/MapBlock.java @@ -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 nodes; + + ArrayList 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()); + } +} diff --git a/java/org/artisanlogiciel/games/minetest/MapNode.java b/java/org/artisanlogiciel/games/minetest/MapNode.java new file mode 100644 index 0000000..1dbaf1d --- /dev/null +++ b/java/org/artisanlogiciel/games/minetest/MapNode.java @@ -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 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 0x7F){ + node.param0 <<= 4; + node.param0 |= (node.param2&0xF0)>>4; + node.param2 &= 0x0F; + } + } + } + else if(content_width == 2) + { + for(int i=0; i {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) + { + // + } + + } + + +} diff --git a/java/org/artisanlogiciel/games/minetest/net/NetworkPacket.java b/java/org/artisanlogiciel/games/minetest/net/NetworkPacket.java new file mode 100644 index 0000000..d1c92f8 --- /dev/null +++ b/java/org/artisanlogiciel/games/minetest/net/NetworkPacket.java @@ -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; + } +} diff --git a/java/org/artisanlogiciel/games/minetest/net/PacketHandler.java b/java/org/artisanlogiciel/games/minetest/net/PacketHandler.java new file mode 100644 index 0000000..ddf815d --- /dev/null +++ b/java/org/artisanlogiciel/games/minetest/net/PacketHandler.java @@ -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); + } + +} diff --git a/java/org/artisanlogiciel/games/minetest/net/PacketType.java b/java/org/artisanlogiciel/games/minetest/net/PacketType.java new file mode 100644 index 0000000..6286991 --- /dev/null +++ b/java/org/artisanlogiciel/games/minetest/net/PacketType.java @@ -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; + } + } + +} diff --git a/java/org/artisanlogiciel/games/minetest/net/ReliablePacketBuffer.java b/java/org/artisanlogiciel/games/minetest/net/ReliablePacketBuffer.java new file mode 100644 index 0000000..fe939da --- /dev/null +++ b/java/org/artisanlogiciel/games/minetest/net/ReliablePacketBuffer.java @@ -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 m_list = new LinkedList<>(); + + void insert(BufferedPacket packet, int nextExpected) + throws PacketException + { + // + int seqNum = packet.getSeqNum(); + m_list.add(packet); + } + +} diff --git a/project_params b/project_params index 8041926..9f9f00e 100644 --- a/project_params +++ b/project_params @@ -3,5 +3,5 @@ project_default=dist project_basedir=$(pwd) project_mainpackage=org.artisanlogiciel.games project_mainclass=$project_mainpackage.maze.gui.Display -project_version=1.1 +project_version=1.2 default_args='lab/lab30x30.raw'