1
0
Эх сурвалжийг харах

Merge branch 'master' of https://repo.nplusc.de/masterX244/iZinked

LH 1 жил өмнө
parent
commit
40598fc34f
100 өөрчлөгдсөн 4466 нэмэгдсэн , 1389 устгасан
  1. 5 0
      .gitignore
  2. 6 0
      EatShitWürgaround/QuickHaxx/App.config
  3. 233 0
      EatShitWürgaround/QuickHaxx/Program.cs
  4. 36 0
      EatShitWürgaround/QuickHaxx/Properties/AssemblyInfo.cs
  5. 53 0
      EatShitWürgaround/QuickHaxx/QuickHaxx.csproj
  6. 25 0
      EatShitWürgaround/QuickHaxx/QuickHaxx.sln
  7. 0 9
      F3Enabler/build.gradle
  8. 2 3
      F3Enabler/src/main/resources/fabric.mod.json
  9. 6 6
      IZPL-A/IZPL/app/build.gradle
  10. 30 30
      IZPL-A/IZPL/filechooser/build.gradle
  11. 11 11
      IZSetup/build.gradle
  12. 3 2
      LogBlockHeatMapper/build.gradle
  13. 45 6
      LogBlockHeatMapper/src/main/java/de/nplusc/izc/logblockheatmapper/LogBlockHeatmapper.java
  14. 89 9
      LogBlockHeatMapper/src/main/java/de/nplusc/izc/logblockheatmapper/LogBlockHeatmapperRegionTrimmer.java
  15. 6 6
      MazeViewer/build.gradle
  16. 10 7
      QuickStuff/build.gradle
  17. 3 3
      QuickStuff/src/main/java/PV/UI.java
  18. 46 0
      QuickStuff/src/main/java/QuickVerifyCrap/FilenameLogUnfucker.java
  19. 49 0
      QuickStuff/src/main/java/QuickVerifyCrap/FlashTitsSucker.java
  20. 15 0
      QuickStuff/src/main/java/QuickVerifyCrap/HexxIt.java
  21. 37 0
      QuickStuff/src/main/java/QuickVerifyCrap/Lazy.java
  22. 27 0
      QuickStuff/src/main/java/QuickVerifyCrap/LazynessGreets.java
  23. 53 0
      QuickStuff/src/main/java/QuickVerifyCrap/Litemergica.java
  24. 72 0
      QuickStuff/src/main/java/QuickVerifyCrap/MajorityOfThreeReader.java
  25. 44 0
      QuickStuff/src/main/java/QuickVerifyCrap/MickeyBinSplitter.java
  26. 16 0
      QuickStuff/src/main/java/QuickVerifyCrap/PWNACradleGrabber.java
  27. 121 0
      QuickStuff/src/main/java/QuickVerifyCrap/PWNaFirmwareGrabScriptGenerator.java
  28. 60 0
      QuickStuff/src/main/java/QuickVerifyCrap/SonyUnXml.java
  29. 155 0
      QuickStuff/src/main/java/QuickVerifyCrap/SplitSecondArkSplitter.java
  30. 87 0
      QuickStuff/src/main/java/QuickVerifyCrap/SplitSecondChecksumCheck.java
  31. 29 0
      QuickStuff/src/main/java/QuickVerifyCrap/SuperToothPuller.java
  32. 86 0
      QuickStuff/src/main/java/QuickVerifyCrap/UTPackMangler.java
  33. BIN
      SenaBitWiggler/Adapter-Details/PWNa-Adapter-Pinout.png
  34. 15 4
      SenaBitWiggler/build.gradle
  35. 2 1
      SenaBitWiggler/src/dist/devices/10S.device.yml
  36. 2 0
      SenaBitWiggler/src/dist/devices/50S.device.yml
  37. 5 0
      SenaBitWiggler/src/dist/devices/SRL2.device.yml
  38. 50 0
      SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/Configuration.java
  39. 41 0
      SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/DataStructures/QualCommHeaderRecord.java
  40. 33 0
      SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/DataStructures/QualCommWrapper.java
  41. 50 9
      SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/EntryPoint.java
  42. 81 0
      SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/Firmware.java
  43. 731 0
      SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/FirmwareAutoDumper.java
  44. 141 0
      SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/FirmwareVersion.java
  45. 5 1
      SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/FirmwareWrapperExtraction.java
  46. 287 10
      SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/FlashFSUnWiggler.java
  47. 11 0
      SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/Jailbreaker.java
  48. 20 0
      SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/MatrixState.java
  49. 26 36
      SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/PromptHandlerSuite.java
  50. 37 0
      SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/Statefile.java
  51. 4 1
      SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/Utils.java
  52. 7 4
      SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/VmAppFIleExtraction.java
  53. 18 16
      SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/XAPDisAsm.java
  54. 0 3
      SenaBitWiggler/src/main/resources/PromptConfigs/SRL2.prompts.yml
  55. 2 2
      SenaBitWiggler/src/main/resources/log4j2.xml
  56. 9 9
      TWPUtil/build.gradle
  57. 17 17
      ToolKit/build.gradle
  58. 19 0
      ToolKit/src/main/java/de/nplusc/izc/tools/baseTools/Detectors.java
  59. 487 687
      ToolKit/src/main/java/de/nplusc/izc/tools/baseTools/Tools.java
  60. 10 10
      UpidTK/build.gradle
  61. 18 17
      WPCMGr/build.gradle
  62. 2 1
      build.gradle
  63. 3 11
      external/java-progressbar/build.gradle
  64. 1 1
      gradle/wrapper/gradle-wrapper.properties
  65. 9 9
      iZStreamer/build.gradle
  66. 6 6
      iZlaunch/build.gradle
  67. 1 1
      iZpaqSFX/build.gradle
  68. 9 9
      iZpl-server/build.gradle
  69. 122 107
      iZpl/build.gradle
  70. 6 0
      iZpl/src/main/java/de/nplusc/izc/iZpl/API/IZPLApi.java
  71. 8 22
      iZpl/src/main/java/de/nplusc/izc/iZpl/API/PlayListEditAPI.java
  72. 3 1
      iZpl/src/main/java/de/nplusc/izc/iZpl/API/UIPlugin.java
  73. 13 2
      iZpl/src/main/java/de/nplusc/izc/iZpl/CommandLineParsing.java
  74. 4 3
      iZpl/src/main/java/de/nplusc/izc/iZpl/CommandLineStatus.java
  75. 6 0
      iZpl/src/main/java/de/nplusc/izc/iZpl/GUI/IZplGUIDefault.java
  76. 6 0
      iZpl/src/main/java/de/nplusc/izc/iZpl/GUI/IZplGUISkinnable.java
  77. 60 30
      iZpl/src/main/java/de/nplusc/izc/iZpl/Main.java
  78. 171 8
      iZpl/src/main/java/de/nplusc/izc/iZpl/PlProcessorV2.java
  79. 5 0
      iZpl/src/main/java/de/nplusc/izc/iZpl/RCUI/RemoteUI.java
  80. 71 0
      iZpl/src/main/java/de/nplusc/izc/iZpl/Utils/QuitterFakePlaylistItem.java
  81. 6 8
      iZpl/src/main/java/de/nplusc/izc/iZpl/Utils/VlcInterface.java
  82. BIN
      iZpl/src/main/resources/vlc/vlc-3.0.3-linux-x64.zip
  83. 19 19
      iZplPlugins/Editor/build.gradle
  84. 8 3
      iZplPlugins/Extractor/build.gradle
  85. 12 12
      iZplPlugins/GameRadio/build.gradle
  86. 24 24
      iZplPlugins/ITunes/build.gradle
  87. 31 15
      iZplPlugins/JukeBox/build.gradle
  88. 8 10
      iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/JukeBox.java
  89. 7 1
      iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/JukeBoxPlugin.java
  90. 2 93
      iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/JukeboxClientHandler.java
  91. 175 4
      iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/JukeboxServer.java
  92. 3 0
      iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/LocalBackend.java
  93. 2 0
      iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/PlaybackStatusUpdater.java
  94. 19 19
      iZplPlugins/Smartphonizer/build.gradle
  95. 24 24
      iZplPlugins/WMP/build.gradle
  96. 3 3
      iZplPlugins/discordjukebox/build.gradle
  97. 13 13
      iZplPlugins/foobar2000_others/build.gradle
  98. 3 3
      iZplPlugins/rtsslink/build.gradle
  99. 8 8
      izpl-shared/build.gradle
  100. 5 0
      izpl-shared/src/main/java/de/nplusc/izc/iZpl/API/shared/ActionPlayListItem.java

+ 5 - 0
.gitignore

@@ -116,3 +116,8 @@ fabric.properties
 .idea/
 *.iml
 IZsetup/distPackagerBase
+
+**/bin/
+.idea.x
+**/obj
+**/.vs

+ 6 - 0
EatShitWürgaround/QuickHaxx/App.config

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
+    </startup>
+</configuration>

+ 233 - 0
EatShitWürgaround/QuickHaxx/Program.cs

@@ -0,0 +1,233 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.IO.Ports;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace QuickHaxx
+{
+    class Program
+    {
+        static void Main(string[] args)
+        {
+            int[] repull_lines = {
+                0,
+                48,
+                64,
+                80,
+                96,
+                112,
+                128,
+                144,
+                160,
+                176,
+                192,
+                224,
+                240,
+                256,
+                272,
+                288,
+                304,
+                320,
+                336,
+                352,
+                368,
+                384,
+                400,
+                416,
+                432,
+                448,
+                464,
+                480,
+                496,
+                800,
+                1216,
+                1232,
+                1584,
+                2208,
+                2960,
+                3408,
+                3600,
+                4144,
+                4480,
+                4704,
+                5296,
+                5328,
+                5440,
+                5472,
+                5840,
+                6512,
+                6560,
+                6592,
+                6736,
+                6752,
+                7120,
+                7968,
+                8096,
+                8160,
+                9968,
+                10464,
+                10672,
+                10912,
+                11712,
+                12128,
+                12576,
+                14064,
+                14176,
+                14464,
+                14960,
+                16048,
+                16912,
+                17968,
+                18160,
+                18816,
+                18928,
+                19488,
+                19536,
+                20528,
+                20704,
+                20880,
+                21216,
+                21280,
+                21376,
+                21728,
+                21808,
+                21856,
+                21888,
+                21936,
+                22032,
+                23472,
+                23728,
+                24240,
+                24400,
+                24976,
+                26656,
+                26672,
+                26816,
+                27120,
+                27280,
+                27488,
+                28352,
+                28816,
+                28960,
+                29264,
+                30400,
+                30864,
+                31056,
+                31216,
+                31280,
+                34288,
+                35744,
+                36160,
+                37520,
+                39072,
+                39552,
+                39664,
+                39920,
+                39984,
+                40000,
+                40512,
+                40960,
+                41184,
+                41536,
+                41632,
+                41920,
+                42320,
+                43584,
+                44192,
+                44944,
+                44960,
+                44992,
+                45424,
+                45584,
+                46064,
+                46224,
+                46544,
+                46976,
+                48016,
+                48176,
+                48432,
+                48736,
+                50864,
+                51216,
+                52096,
+                52896,
+                53376,
+                54352,
+                54672,
+                55376,
+                55536,
+                55568,
+                57968,
+                58672,
+                59504,
+                59552,
+                59568,
+                59664,
+                59840,
+                60464,
+                60912,
+                62704,
+                62992,
+                64192,
+            };
+
+
+            SerialPort _serialPort = new SerialPort("COM8", 115200, Parity.None, 8, StopBits.One);
+            StreamWriter w = new StreamWriter("C:\\LMAA\\085-flash\\flashhaxx-rehaxx"+(DateTime.Now.ToBinary())+".txt");
+            _serialPort.Handshake = Handshake.None;
+            _serialPort.DataReceived += new SerialDataReceivedEventHandler((sender,e)=> 
+            {
+                string data = _serialPort.ReadExisting();
+                w.WriteLine(data);
+                Console.WriteLine("R:"+data);
+            });
+            _serialPort.WriteTimeout = 500;
+            _serialPort.Open();
+            
+            _serialPort.WriteLine("m");
+            Thread.Sleep(100);
+            _serialPort.WriteLine("5");
+            Thread.Sleep(100);
+            _serialPort.WriteLine("1"); //1 =30khz, 4=1M;
+            Thread.Sleep(100);
+            _serialPort.WriteLine("1");
+            Thread.Sleep(100);
+            _serialPort.WriteLine("2");
+            Thread.Sleep(100);
+            _serialPort.WriteLine("1");
+            Thread.Sleep(100);
+            _serialPort.WriteLine("2"); //Chipselect
+            Thread.Sleep(100);
+            _serialPort.WriteLine("2"); //normal
+            Thread.Sleep(100);
+            _serialPort.WriteLine("W"); //normal
+            Thread.Sleep(100);
+            //*/
+            for(int i=0;i<0x010000;i+=16)
+            {
+                if (repull_lines.Contains(i))
+                {
+                    String hexed = i.ToString("x6");
+                    Console.WriteLine(hexed);
+                    String a1 = hexed.Substring(0, 2);
+                    String a2 = hexed.Substring(2, 2);
+                    String a3 = hexed.Substring(4, 2);
+                    _serialPort.WriteLine("[0x03 0x" + a1 + " 0x" + a2 + " 0x" + a3 + " r:16]"); //normal
+                    Thread.Sleep(100);
+                }
+
+            }
+
+            //_serialPort.WriteLine("[0x03 0x00 0x00 0x00 r:16]"); //normal
+            //Thread.Sleep(1000);
+            _serialPort.Close();
+            Console.WriteLine("DONE");
+            Console.ReadKey();
+            w.Close();
+        }
+    }
+}

+ 36 - 0
EatShitWürgaround/QuickHaxx/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die einer Assembly zugeordnet sind.
+[assembly: AssemblyTitle("QuickHaxx")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("QuickHaxx")]
+[assembly: AssemblyCopyright("Copyright ©  2023")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
+// für COM-Komponenten unsichtbar.  Wenn Sie auf einen Typ in dieser Assembly von
+// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("fc161e64-cdd1-4c05-b6b4-6e900f7a8e75")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+//      Hauptversion
+//      Nebenversion
+//      Buildnummer
+//      Revision
+//
+// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
+// indem Sie "*" wie unten gezeigt eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 53 - 0
EatShitWürgaround/QuickHaxx/QuickHaxx.csproj

@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{FC161E64-CDD1-4C05-B6B4-6E900F7A8E75}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>QuickHaxx</RootNamespace>
+    <AssemblyName>QuickHaxx</AssemblyName>
+    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+    <Deterministic>true</Deterministic>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 25 - 0
EatShitWürgaround/QuickHaxx/QuickHaxx.sln

@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31321.278
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuickHaxx", "QuickHaxx.csproj", "{FC161E64-CDD1-4C05-B6B4-6E900F7A8E75}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{FC161E64-CDD1-4C05-B6B4-6E900F7A8E75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{FC161E64-CDD1-4C05-B6B4-6E900F7A8E75}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{FC161E64-CDD1-4C05-B6B4-6E900F7A8E75}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{FC161E64-CDD1-4C05-B6B4-6E900F7A8E75}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {D259CD62-CBAA-48B8-8480-61C9D86DC19C}
+	EndGlobalSection
+EndGlobal

+ 0 - 9
F3Enabler/build.gradle

@@ -25,15 +25,6 @@ dependencies {
 
 processResources {
     inputs.property "version", project.version
-
-    from(sourceSets.main.resources.srcDirs) {
-        include "fabric.mod.json"
-        expand "version": project.version
-    }
-
-    from(sourceSets.main.resources.srcDirs) {
-        exclude "fabric.mod.json"
-    }
 }
 
 // ensure that the encoding is set to UTF-8, no matter what the system default is

+ 2 - 3
F3Enabler/src/main/resources/fabric.mod.json

@@ -1,7 +1,7 @@
 {
   "schemaVersion": 1,
   "id": "fthreenabler",
-  "version": "${version}",
+  "version": "1.0.0",
   "name": "FThreeNabler",
   "description": "",
   "authors": [],
@@ -20,7 +20,6 @@
     "FThreeNabler.mixins.json"
   ],
   "depends": {
-    "fabricloader": ">=0.10.8",
-    "minecraft": ">=1.16"
+    "fabricloader": ">=0.10.8"
   }
 }

+ 6 - 6
IZPL-A/IZPL/app/build.gradle

@@ -25,10 +25,10 @@ android {
 }
 
 dependencies {
-    compile fileTree(dir: 'libs', include: '*.jar')
-    compile files('libs/izpl-shared.jar')
-    compile 'com.android.support:appcompat-v7:22.1.1'
-    compile project(':filechooser')
-    compile 'org.apache.logging.log4j:log4j-api:2.+'
-    compile project(':exoplayer')
+    api fileTree(dir: 'libs', include: '*.jar')
+    api files('libs/izpl-shared.jar')
+    api 'com.android.support:appcompat-v7:22.1.1'
+    api project(':filechooser')
+    api 'org.apache.logging.log4j:log4j-api:2.+'
+    api project(':exoplayer')
 }

+ 30 - 30
IZPL-A/IZPL/filechooser/build.gradle

@@ -1,30 +1,30 @@
-apply plugin: 'com.android.library'
-
-
-android {
-    compileSdkVersion 21
-    buildToolsVersion "21.0.2"
-
-    defaultConfig {
-        minSdkVersion 19
-        targetSdkVersion 21
-        versionCode 1
-        versionName "1.0"
-    }
-
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
-    }
-    buildTypes {
-        release {
-            minifyEnabled false
-            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
-        }
-    }
-}
-
-dependencies {
-    compile fileTree(dir: 'libs', include: ['*.jar'])
-    compile 'com.android.support:appcompat-v7:22.1.1'
-}
+apply plugin: 'com.android.library'
+
+
+android {
+    compileSdkVersion 21
+    buildToolsVersion "21.0.2"
+
+    defaultConfig {
+        minSdkVersion 19
+        targetSdkVersion 21
+        versionCode 1
+        versionName "1.0"
+    }
+
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_7
+        targetCompatibility JavaVersion.VERSION_1_7
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+}
+
+dependencies {
+    api fileTree(dir: 'libs', include: ['*.jar'])
+    api 'com.android.support:appcompat-v7:22.1.1'
+}

+ 11 - 11
IZSetup/build.gradle

@@ -1,6 +1,6 @@
 defaultTasks 'distZip'
 
-apply plugin: 'java'
+apply plugin: 'java-library'
 apply plugin: 'application'
 
 sourceCompatibility = 1.8
@@ -78,16 +78,16 @@ jar{
 }
 
 dependencies{
-	compile fileTree(dir: 'lib', include: '*.jar')
-	compile "commons-io:commons-io:2.+"
-	compile 'org.apache.commons:commons-exec:1.3'
-	compile "org.yaml:snakeyaml:1.14"
-	compile "commons-net:commons-net:3.3"
-    compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+'
-	compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+'
-	compile group: 'org.apache.logging.log4j', name: 'log4j-iostreams', version: '2.+'
-	 compile	'org.xerial:sqlite-jdbc:3.8.7'
-			compile(project(':ToolKit')) {
+	api fileTree(dir: 'lib', include: '*.jar')
+	api "commons-io:commons-io:2.+"
+	api 'org.apache.commons:commons-exec:1.3'
+	api "org.yaml:snakeyaml:1.14"
+	api "commons-net:commons-net:3.3"
+    api group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-iostreams', version: '2.+'
+	 api	'org.xerial:sqlite-jdbc:3.8.7'
+			api(project(':ToolKit')) {
         transitive = false
     }
 

+ 3 - 2
LogBlockHeatMapper/build.gradle

@@ -1,6 +1,6 @@
 defaultTasks 'distZip'
 
-apply plugin: 'java'
+apply plugin: 'java-library'
 apply plugin: 'application'
 
 
@@ -23,5 +23,6 @@ repositories{
 }
 
 dependencies{
-    compile group: 'com.alexdupre', name: 'pngj', version: '2+'
+    api group: 'com.alexdupre', name: 'pngj', version: '2+'
+	api "org.yaml:snakeyaml:1.14"
 }

+ 45 - 6
LogBlockHeatMapper/src/main/java/de/nplusc/izc/logblockheatmapper/LogBlockHeatmapper.java

@@ -45,6 +45,7 @@ public class LogBlockHeatmapper
     static int maxy=0;
     static int targetBlockID=-1;
     static boolean removalsOnly=false;
+    static boolean placemode = false;
     static BufferedImage gradient = new BufferedImage(1024,1,BufferedImage.TYPE_4BYTE_ABGR);
     /**
      * @param args the command line arguments
@@ -58,10 +59,17 @@ public class LogBlockHeatmapper
         }
         if(args.length>2)
         {
-            targetBlockID = Integer.valueOf(args[2]);
-            if(args.length>3)
+            if(args[2].equals("place"))
             {
-                removalsOnly = Boolean.valueOf(args[3]);
+                placemode=true;
+            }
+            else
+            {
+                targetBlockID = Integer.valueOf(args[2]);
+                if(args.length>3)
+                {
+                    removalsOnly = Boolean.valueOf(args[3]);
+                }
             }
         }
         int size = Integer.valueOf(args[1]);
@@ -92,8 +100,8 @@ public class LogBlockHeatmapper
             String[] xes = xx.split("\\t");
             int l = Integer.parseInt(xes[0]);
             boolean register=false;
-            int f = Integer.parseInt(xes[1]);
-            int t = Integer.parseInt(xes[2]);
+            int f = 0;//Integer.parseInt(xes[1]);
+            int t = 1;//Integer.parseInt(xes[2]);
             if((targetBlockID<0||targetBlockID==f||targetBlockID==t))
             {
                 register=true;
@@ -164,7 +172,38 @@ public class LogBlockHeatmapper
                 }
                 else
                 {
-                    if(max>1050)
+                    if(placemode)
+                    {
+                        k=k/10;
+                        //k/=steps;
+                        if(k<50)
+                        {
+                            color= gradient.getRGB(k*16, 0);
+
+                        }
+                        else
+                        {
+                            if(k<1050)
+                            {
+                                k-=50;
+                                color= gradient.getRGB(800+k/10, 0);
+                            }
+                            else
+                            {
+                                k-=1050;
+                                int stepWidth = (max-1050)/(123);
+                                if(stepWidth==0)
+                                    stepWidth++;
+                                color= gradient.getRGB(Math.min(1023,900+k/stepWidth), 0);
+                            }
+                            int r=(color&0xFF0000)>>16;
+                            int g=(color&0xff00)>>8;
+                            int b=color&0xff;
+                            //bw.write(r);bw.write(g);bw.write(b);
+                            //writeBy(r+" "+g+" "+b);
+                        }
+                    }
+                    else if(max>1050)
                     {
                         //k/=steps;
                         if(k<50)

+ 89 - 9
LogBlockHeatMapper/src/main/java/de/nplusc/izc/logblockheatmapper/LogBlockHeatmapperRegionTrimmer.java

@@ -23,6 +23,7 @@ import ar.com.hjg.pngj.ImageLineHelper;
 import ar.com.hjg.pngj.ImageLineInt;
 import ar.com.hjg.pngj.PngWriter;
 import ar.com.hjg.pngj.chunks.PngChunkTextVar;
+import org.yaml.snakeyaml.Yaml;
 
 import java.awt.Color;
 import java.awt.GradientPaint;
@@ -54,7 +55,9 @@ enum RegionState
     CORE,
     KEEP,
     WATERIZE,
-    DROPPED
+    DROPPED,
+    PREVIOUS,
+    PREVIOUS_BUFFER
 }
 
 class CoordHolder
@@ -140,7 +143,13 @@ public class LogBlockHeatmapperRegionTrimmer
 
     static final Color keepCoreA = new Color(0, 64, 0);
     static final Color keepCoreB = new Color(0, 106, 0);
-    
+
+    static final Color previousA = new Color(4, 68, 66);
+    static final Color previousB = new Color(8, 128, 123);
+
+    static final Color previousBufferA = new Color(8, 128, 96);
+    static final Color previousBufferB = new Color(11, 218, 160);
+
     static final Color activity = new Color(87, 87, 87);
     static final Color activityBuffer = new Color(157, 157, 157);
 
@@ -547,6 +556,66 @@ public class LogBlockHeatmapperRegionTrimmer
             }
         }
 
+        // propagating previous buffers out by one...
+
+        File keepers = new File("keepregions.yml");
+        if(keepers.exists())
+        {
+            System.out.println("LOAD KEEPERS");
+            FileReader loader = new FileReader(keepers);
+            Map<String,RegionState> oldkeepers = (Map<String,RegionState>)new Yaml().load(loader);
+            loader.close();
+
+            for(int i=-regionBase;i<=regionBase;i++)
+            {
+                for(int j=-regionBase;j<=regionBase;j++)
+                {
+                    String regionref = "r."+(i)+"."+(j)+".mca";
+                    RegionState oldstate = oldkeepers.getOrDefault(regionref,RegionState.REMOVE);
+                    if (
+                            oldstate==RegionState.CORE||
+                            oldstate==RegionState.KEEP||
+                            oldstate==RegionState.PREVIOUS||
+                            oldstate==RegionState.PREVIOUS_BUFFER||
+                            oldstate==RegionState.WATERIZE //just for safety even though its not needed
+                    )
+                    {
+                        for(int di=-1;di<=1;di++)
+                        {
+                            for(int dj=-1;dj<=1;dj++)
+                            {
+                                int ri=i+di;
+                                int rj=j+dj;
+                                if(ri<-regionBase||ri>regionBase)
+                                {
+                                    break; //out of bounds;
+                                }
+
+                                if(rj<-regionBase||rj>regionBase)
+                                {
+                                    break; //out of bounds;
+                                }
+
+                                String regionref_u = "r."+(ri)+"."+(rj)+".mca";
+                                RegionState newstate = keepRegions.getOrDefault(regionref_u,RegionState.REMOVE);
+                                if (
+                                        newstate==RegionState.REMOVE||
+                                        newstate==RegionState.DROPPED||
+                                        newstate==RegionState.PREVIOUS_BUFFER
+                                )
+                                {
+                                    keepRegions.put(regionref_u,(di==0&&dj==0)?RegionState.PREVIOUS:RegionState.PREVIOUS_BUFFER);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        // else nothing to do, no previous run data found as "baseline"
+
+
+
         //max=Math.min(max, 1000);
         //int steps=max/256;
         //BufferedWriter bw = new BufferedWriter(new FileWriter(new File("D:/emc2/arca_slash/database/crunched.pgm")));
@@ -560,6 +629,10 @@ public class LogBlockHeatmapperRegionTrimmer
         //FROM `lb-surv`
         //INTO OUTFILE 'D:/emc2/arca_slash/database/lbcrunchsurvival.csv';
 
+
+
+        new Yaml().dump(keepRegions,new FileWriter("keepregions.yml"));
+
         ImageInfo imi = new ImageInfo(dataField.length, dataField.length, 8, false); // 8 bits per channel, no alpha
         // open image for writing to a output stream
         PngWriter png = new PngWriter(new FileOutputStream("map_rg.png"), imi);
@@ -608,6 +681,12 @@ public class LogBlockHeatmapperRegionTrimmer
                                 case DROPPED:
                                     color = (grid ? removeA_Dropped : removeB_Dropped).getRGB();
                                     break;
+                                case PREVIOUS:
+                                    color = (grid ? previousA : previousB).getRGB();
+                                    break;
+                                case PREVIOUS_BUFFER:
+                                    color = (grid ? previousBufferA : previousBufferB).getRGB();
+                                    break;
                             }
                         }
                         break;
@@ -643,10 +722,10 @@ public class LogBlockHeatmapperRegionTrimmer
         try {
             fileActions = new PrintStream(new FileOutputStream("mergeMap.sh"));
             fileActions.println("mkdir oldChunks");
-            System.out.println("mkdir oldChunks");
+            //System.out.println("mkdir oldChunks");
 
             fileActions.println("mkdir oldChunksWaterize");
-            System.out.println("mkdir oldChunksWaterize");
+            //System.out.println("mkdir oldChunksWaterize");
             keepRegions.forEach((k,v)->
             {
                 switch(v)
@@ -655,25 +734,26 @@ public class LogBlockHeatmapperRegionTrimmer
                     case REMOVE:
                     case DROPPED:
                         fileActions.println("mv "+k+" oldChunks/");
-                        System.out.println("mv "+k+" oldChunks/");
+                        //System.out.println("mv "+k+" oldChunks/");
                         break;
                     case CORE:
                         fileActions.println("echo "+k+" is keepCore");
-                        System.out.println("echo "+k+" is keepCore");
+                        //System.out.println("echo "+k+" is keepCore");
                         break;
                     case KEEP:
                         fileActions.println("echo "+k+" is keep");
-                        System.out.println("echo "+k+" is keep");
+                        //System.out.println("echo "+k+" is keep");
                         break;
                     case WATERIZE:
                         fileActions.println("mv "+k+" oldChunksWaterize/");
-                        System.out.println("mv "+k+" oldChunksWaterize/");
+                        //System.out.println("mv "+k+" oldChunksWaterize/");
                         fileActions.println("mv waterize/"+k+" ./");
-                        System.out.println("mv waterize/"+k+" ./");
+                        //System.out.println("mv waterize/"+k+" ./");
                         break;
                 }
             });
             fileActions.close();
+            //dumping a statefile for adding a new buffer on the next run
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         }

+ 6 - 6
MazeViewer/build.gradle

@@ -1,6 +1,6 @@
 defaultTasks 'distZip'
 
-apply plugin: 'java'
+apply plugin: 'java-library'
 apply plugin: 'application'
 
 
@@ -24,11 +24,11 @@ repositories{
 
 
 dependencies{
-	compile fileTree(dir: 'lib', include: '*.jar')
-	compile "commons-io:commons-io:2.+"
-	compile 'org.apache.commons:commons-exec:1.3'
-	compile "org.yaml:snakeyaml:1.14"
-	compile(project(':ToolKit')) {
+	api fileTree(dir: 'lib', include: '*.jar')
+	api "commons-io:commons-io:2.+"
+	api 'org.apache.commons:commons-exec:1.3'
+	api "org.yaml:snakeyaml:1.14"
+	api(project(':ToolKit')) {
         transitive = false
     }
 

+ 10 - 7
QuickStuff/build.gradle

@@ -1,7 +1,10 @@
-defaultTasks 'distZip'
-
-apply plugin: 'java'
-dependencies{
-    compile(project(':ToolKit')) {
-    }
-}
+defaultTasks 'distZip'
+
+apply plugin: 'java-library'
+sourceCompatibility = 1.17
+dependencies{
+    api(project(':ToolKit')) {
+    }
+    implementation 'org.bouncycastle:bcprov-ext-jdk18on:1.71'
+    implementation 'com.fazecast:jSerialComm:[2.0.0,3.0.0)'
+}

+ 3 - 3
QuickStuff/src/main/java/PV/UI.java

@@ -22,8 +22,8 @@ public class UI extends javax.swing.JFrame
     {
         initComponents();
         
-        String fp = "D:\\loa\\000010\\in.sqlite";
-        String fp2="D:\\loa\\000010\\out.txt";
+        String fp = "C:\\Users\\LH\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\wb5ap89r.default\\places-2207.sqlite";
+        String fp2="C:\\lmaa\\grepme.txt";
         DBWriter dbw = new DBWriter("", fp, "", "", DBWriter.DBTYPE_SQLite);
         //String[][] items = dbw.queryTable("SELECT url , id FROM moz_places");
         String[][] idmap = dbw.queryTable("SELECT place_id , visit_date from moz_historyvisits  ORDER BY visit_date");
@@ -41,7 +41,7 @@ public class UI extends javax.swing.JFrame
             String date = (new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new java.util.Date (Long.valueOf(ue[1])/1000)));
             String datafield=dbw.querySingleCell("SELECT url FROM moz_places where id = "+ue[0]);
             
-            if(datafield.contains("mail.google.com"))
+            //if(datafield.contains("mail.google.com"))
             {
             
             ((DefaultTableModel)tblT.getModel()).setValueAt(datafield, i, 0);

+ 46 - 0
QuickStuff/src/main/java/QuickVerifyCrap/FilenameLogUnfucker.java

@@ -0,0 +1,46 @@
+package QuickVerifyCrap;
+
+import java.io.*;
+
+public class FilenameLogUnfucker
+{
+    // grep "^[0-9a-f]* " filterforfilenames1.log >filenames_multilinecrap.txt
+    public static void main(String[] args){
+        BufferedReader r = null;
+        try {
+            r = new BufferedReader(new FileReader("D:\\LOA\\000014\\filenames_multilinecrap.txt"));
+            String line = "";
+            PrintWriter w = new PrintWriter("D:\\LOA\\000014\\filenames_preprocessed.txt");
+            String newline = r.readLine();
+            while(newline != null)
+            {
+                System.out.println(newline);
+                if(newline.contains("|"))
+                {
+                    String[] writeline = line.split("\\|");
+                    if(writeline.length==2)
+                    {
+                        w.println(writeline[1]);
+                    }
+                    line = newline.split("\"")[1];
+                }
+                else
+                {
+                    String[] linesplitted = newline.split("\"");
+                    if(linesplitted.length == 2)
+                    {
+                        line += linesplitted[1];
+                    }
+                }
+                newline = r.readLine();
+            }
+            w.println(line);
+            w.close();
+            r.close();
+        } catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+
+    }
+}

+ 49 - 0
QuickStuff/src/main/java/QuickVerifyCrap/FlashTitsSucker.java

@@ -0,0 +1,49 @@
+package QuickVerifyCrap;
+
+import com.fazecast.jSerialComm.SerialPort;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+
+public class FlashTitsSucker {
+    public static void main(String[] args) {
+        try (RandomAccessFile file = new RandomAccessFile("C:\\lmaa\\085-flash\\flashhaxx-merged.bin","r")) {
+            File out = new File("C:\\lmaa\\085-flash\\out-rerun");
+            out.mkdirs();
+            //file.seek(0x6b);
+            //guessed from file reading
+            byte[] swapMe = new byte[4];
+            file.read(swapMe); //skipping 4, lazy
+            for(int i=0; i < 13;i++)
+            {
+                //byte[] swapMe = new byte[4];
+                file.read(swapMe);
+                ByteBuffer wrapped = ByteBuffer.wrap(new byte[]{swapMe[3],swapMe[2],swapMe[1],swapMe[0]}); // big-endian by default
+                int offsetFile = wrapped.getInt();
+                System.out.println(offsetFile);
+                long retval = file.getFilePointer();
+
+                file.seek(offsetFile);
+
+                file.read(swapMe);
+                wrapped = ByteBuffer.wrap(new byte[]{swapMe[3],swapMe[2],swapMe[1],swapMe[0]}); // big-endian by default
+                int lenFile = wrapped.getInt();
+                System.out.println(lenFile);
+                byte[] innerFile = new byte[lenFile];
+                file.read(innerFile);
+                file.seek(retval);
+                try (RandomAccessFile outRandom = new RandomAccessFile(new File(out, i + ".bin"), "rw")) {
+                    outRandom.write(innerFile);
+                }
+            }
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException(e);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

+ 15 - 0
QuickStuff/src/main/java/QuickVerifyCrap/HexxIt.java

@@ -0,0 +1,15 @@
+package QuickVerifyCrap;
+
+public class HexxIt {
+    public static void main(String[] args) {
+        char[] hex="0123456789abcdef".toCharArray();
+        for(int i=0;i<hex.length;i++)
+        {
+            for(int j=0;j<hex.length;j++)
+            {
+                String hexed = new String(new char[]{hex[i],hex[j]});
+                System.out.println("sort -S 1G --batch-size=24000 -m "+hexed+"*.lst|pv -crb >"+hexed+".int");
+            }
+        }
+    }
+}

+ 37 - 0
QuickStuff/src/main/java/QuickVerifyCrap/Lazy.java

@@ -0,0 +1,37 @@
+package QuickVerifyCrap;
+
+import java.io.File;
+
+public class Lazy {
+    public static void main(String[] args) {
+        /*for(int i=1;i<256;i++)
+        {
+            System.out.print("0x");
+            System.out.print(Long.toHexString(i));
+            System.out.print(" ");
+        }*/
+        SplitSecondArkSplitter.HACK=true;
+        SplitSecondArkSplitter.main(null);
+        SplitSecondArkSplitter.HACK=false;
+        sweep("O:\\SplitSecond\\data");
+
+    }
+
+
+
+    public static void sweep(String path)
+    {
+        File f = new File(path);
+        for (File file : f.listFiles()) {
+            if(file.getName().endsWith(".ark"))
+            {
+                //System.out.println(file.getAbsolutePath());
+                SplitSecondArkSplitter.main(new String[]{file.getAbsolutePath()});
+            }
+            if(file.isDirectory())
+            {
+                sweep(file.getAbsolutePath());
+            }
+        }
+    }
+}

+ 27 - 0
QuickStuff/src/main/java/QuickVerifyCrap/LazynessGreets.java

@@ -0,0 +1,27 @@
+package QuickVerifyCrap;
+
+public class LazynessGreets {
+    public static void main(String[] args) {
+        for(int i=0;i<100;i++)
+        {
+            if(i==0)
+            {
+                //noop, nothing to rename
+            }
+            else
+            {
+                System.out.println("mv snm.xml."+i+" snm.xml");
+            }
+            System.out.println("git add snm.xml");
+            if(i==99)
+            {
+                System.out.println("git commit -m \"Autoxml dump\"");
+            }
+            else
+            {
+                System.out.println("git commit --date=\""+(99-i) +" day ago\" -m \"Autoxml dump\"");
+            }
+            System.out.println("rm snm.xml");
+        }
+    }
+}

+ 53 - 0
QuickStuff/src/main/java/QuickVerifyCrap/Litemergica.java

@@ -0,0 +1,53 @@
+package QuickVerifyCrap;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.stream.Collectors;
+
+public class Litemergica {
+    public static void main(String[] args) throws IOException {
+        String[] files = {"R1C1.txt","R1C2.txt","R1C3.txt","R2C1.txt","R2C2.txt","R2C3.txt","R3C1.txt","R3C2.txt","R3C3.txt"};
+        HashMap<String,Integer> counts = new HashMap<>();
+        for(String file:files)
+        {
+            String path = "C:\\dotMCMain\\MultiMC\\instances\\.19-DUP\\.minecraft\\config\\litematica\\"+file;
+            BufferedReader r = new BufferedReader(new FileReader(path));
+            String line = "";
+            for(int i=0;i<6;i++,line=r.readLine());
+            while(line !=null)
+            {
+                String[] splitt = line.split("\\|");
+                if(splitt.length<2)
+                {
+                    break;
+                }
+                String key = splitt[1];
+                System.out.println(line);
+                System.out.println(splitt[1]);
+                System.out.println(splitt[2]);
+                int amount = Integer.valueOf(splitt[2].trim());
+                int count = counts.getOrDefault(key,0);
+                if(amount>count)
+                {
+                    counts.put(key,amount);
+                }
+                line = r.readLine();
+            }
+
+        }
+
+
+
+        var list = counts.entrySet().stream().collect(Collectors.toList());
+        list.sort((e1,e2)->
+        {
+            return e2.getValue().compareTo(e1.getValue());
+        });
+        list.forEach((o->{
+            System.out.println(o.getKey()+"|"+o.getValue());
+        }));
+    }
+}

+ 72 - 0
QuickStuff/src/main/java/QuickVerifyCrap/MajorityOfThreeReader.java

@@ -0,0 +1,72 @@
+package QuickVerifyCrap;
+
+import de.nplusc.izc.tools.IOtools.FileTK;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.PrintStream;
+
+public class MajorityOfThreeReader {
+    public static void main(String[] args) throws FileNotFoundException {
+        String[] file1 = FileTK.fileload("C:\\LMAA\\085-flash\\filtered1.txt");
+        String[] file2 = FileTK.fileload("C:\\LMAA\\085-flash\\filtered2.txt");
+        String[] file3 = FileTK.fileload("C:\\LMAA\\085-flash\\filtered3.txt");
+        String[] patchfile = FileTK.fileload("C:\\LMAA\\085-flash\\filtered-rehaxx1.txt");
+        PrintStream s = new PrintStream(new FileOutputStream("C:\\LMAA\\085-flash\\filteredMerged.txt"));
+        PrintStream s_desussed = new PrintStream(new FileOutputStream("C:\\LMAA\\085-flash\\filteredMerged-patched.txt"));
+        String susline = "00000000000000000000000000000000 ";
+        String sus1 = "00000";
+        String sus2 = "FFFFF";
+        int desus_idx=0;
+        for(int i=0;i<file1.length;i++)
+        {
+            String line1 = file1[i];
+            String line2 = file3[i];
+            String line3 = file3[i];
+            boolean eq12= line1.equals(line2);
+            boolean eq13= line1.equals(line3);
+            boolean eq23= line2.equals(line3);
+            boolean eqall = eq12&&eq13&&eq23;
+            if(eqall||eq12||eq13)
+            {
+                boolean susitharder = line1.contains(sus1)||line1.contains(sus2);
+                boolean sus = line1.equals(susline);
+                String suffix = sus?" SUS":(susitharder?"PART":"");
+                s.println(line1+suffix);
+                if(sus||susitharder)
+                {
+                    System.out.println(i*16+",");
+                    s_desussed.println(patchfile[desus_idx]);
+                    desus_idx++;
+                }
+                else
+                {
+                    s_desussed.println(line1);
+                }
+            }
+            else if(eq23)
+            {
+                boolean susitharder = line1.contains(sus1)||line1.contains(sus2);
+                boolean sus = line1.equals(susline);
+                String suffix = sus?" SUS":(susitharder?"PART":"");
+                s.println(line1+suffix);
+                if(sus||susitharder)
+                {
+                    System.out.println(i*16+",");
+                    s_desussed.println(patchfile[desus_idx]);
+                    desus_idx++;
+                }
+                else
+                {
+                    s_desussed.println(line1);
+                }
+            }
+            else
+            {
+                s.println(line1+"SUS NO CONSENT");
+                System.out.println(i*16+",");
+            }
+        }
+    }
+}

+ 44 - 0
QuickStuff/src/main/java/QuickVerifyCrap/MickeyBinSplitter.java

@@ -0,0 +1,44 @@
+package QuickVerifyCrap;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+
+public class MickeyBinSplitter {
+    public static void main(String[] args) {
+        try (RandomAccessFile file = new RandomAccessFile(args[0],"r")) {
+            File out = new File(args[0]+"out");
+            out.mkdirs();
+            file.seek(0x6b);
+                            //guessed from file reading
+            for(int i=0; i < 0x29;i++)
+            {
+                byte[] swapMe = new byte[4];
+                file.read(swapMe);
+                ByteBuffer wrapped = ByteBuffer.wrap(new byte[]{swapMe[3],swapMe[2],swapMe[1],swapMe[0]}); // big-endian by default
+                int offsetFile = wrapped.getInt();
+                System.out.println(offsetFile);
+                long retval = file.getFilePointer();
+
+                file.seek(offsetFile);
+
+                file.read(swapMe);
+                wrapped = ByteBuffer.wrap(new byte[]{swapMe[3],swapMe[2],swapMe[1],swapMe[0]}); // big-endian by default
+                int lenFile = wrapped.getInt();
+                System.out.println(lenFile);
+                byte[] innerFile = new byte[lenFile];
+                file.read(innerFile);
+                file.seek(retval);
+                try (RandomAccessFile outRandom = new RandomAccessFile(new File(out, i + ".bin"), "rw")) {
+                    outRandom.write(innerFile);
+                }
+            }
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException(e);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

+ 16 - 0
QuickStuff/src/main/java/QuickVerifyCrap/PWNACradleGrabber.java

@@ -0,0 +1,16 @@
+package QuickVerifyCrap;
+
+public class PWNACradleGrabber {
+    public static void main(String[] args) {
+        String sqfs = "wget -O XXX.rootfs.squashfs.sign http://firmware.sena.com/senabluetoothmanager/WiFiCradle/wifi_adapter/XXX/rootfs.squashfs.sign";
+        String krnl = "wget -O XXX.xImage.sign http://firmware.sena.com/senabluetoothmanager/WiFiCradle/wifi_adapter/XXX/xImage.sign";
+
+
+        for(int i=0;i<=12;i++)
+        {
+            String version = "v1."+i;
+            System.out.println(sqfs.replace("XXX",version));
+            System.out.println(krnl.replace("XXX",version));
+        }
+    }
+}

+ 121 - 0
QuickStuff/src/main/java/QuickVerifyCrap/PWNaFirmwareGrabScriptGenerator.java

@@ -0,0 +1,121 @@
+package QuickVerifyCrap;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+public class PWNaFirmwareGrabScriptGenerator {
+    public static void main(String[] args){
+        try{
+        BufferedReader br = new BufferedReader(new FileReader("Q:\\LOA\\000013\\S30-FW\\firmware2.dat"));
+        String fwline = br.readLine();
+        BufferedWriter w = new BufferedWriter(new FileWriter("Q:\\LOA\\000013\\S30-FW\\firmwarehunt-reloaded.txt"));
+        w.write("#!/bin/bash\n");
+        HashSet<String> linesAdded = new HashSet<>();
+        while(fwline!=null)
+        {
+            System.out.println(fwline);
+            if(fwline.contains(":"))
+            {
+                if(fwline.contains(".img"))
+                {
+                    var line = fwline.split(":");
+                    String filename = line[line.length-1];
+                    String[] magic = filename.split("-v");
+                    boolean fuckingoddity = false;
+                    if(magic.length==1)
+                    {
+                        fuckingoddity = true;
+                        magic = filename.split("_v");
+                    }
+                    String version = magic[1];
+                    String[] vsplit = version.split("\\.");
+
+                    String suffix = "";
+                    int major=0,minor=0,patch=0;
+                    major=Integer.valueOf(vsplit[0]);
+                    if(vsplit.length==4)
+                    {
+                        minor = Integer.valueOf(vsplit[1]);
+                        patch = Integer.valueOf(vsplit[2].substring(0,1));
+                        if(vsplit[2].length()>1)
+                        {
+                            suffix = vsplit[2].substring(1)+"."+vsplit[3];
+                        }
+                        else
+                        {
+                            suffix = "."+vsplit[3];
+                        }
+                    }
+                    else
+                    {
+                        if(vsplit[1].length()>1)
+                        {
+                            minor = Integer.valueOf(vsplit[1].substring(0,1));
+                            suffix = vsplit[1].substring(1)+"."+vsplit[2];
+                        }
+                        else
+                        {
+                            minor = Integer.valueOf(vsplit[1].substring(0,1));
+                            suffix = "."+vsplit[2];
+                        }
+                    }
+                    String[] synthesized = synthesizeVersionNumbers(major,minor,patch,fuckingoddity?"_v":"-v");
+                    for (String innerline:synthesized)
+                    {
+                        String newline = "wget -nc  https://firmware.sena.com/senabluetoothmanager/"+magic[0]+innerline+suffix;
+                        if(!linesAdded.contains(newline))
+                        {
+                            w.write(newline+"\n");
+                            linesAdded.add(newline);
+                        }
+
+                    }
+                }
+            }
+            fwline = br.readLine();
+        }
+        w.close();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+
+
+
+    private static String[] synthesizeVersionNumbers(int major,int minor, int patch,String prefix)
+    {
+        System.out.println(major+"--"+minor+"--"+patch);
+        List<String> temp = new ArrayList<>();
+        //temp.add(prefix+(major+1)+".0.0"); // poking for next major
+        //temp.add(prefix+(major+1)+".0"); // poking for next major
+        //temp.add(prefix+(major)+"."+(minor+1)+".0"); // poking for next minor
+        temp.add(prefix+(major)+"."+(minor+1)); // poking for next minor
+        //temp.add(prefix+(major)+"."+minor+"."+(patch+1)); // poking for next patch
+        System.out.println(major+"--"+minor+"--"+patch);
+        /*
+        while(major>0&&minor>=0&&patch>=0)
+        {
+            temp.add(prefix+(major)+"."+minor+"."+(patch));
+            if(patch==0)
+            {
+                temp.add(prefix+(major)+"."+minor); // specialcase to probe for unset patch version versions
+            }
+            patch--;
+            if(patch<0)
+            {
+                patch=9;
+                minor--;
+            }
+            if(minor<0)
+            {
+                minor=9;
+                major--;
+            }
+        }/**/
+        return temp.toArray(new String[]{});
+    }
+}

+ 60 - 0
QuickStuff/src/main/java/QuickVerifyCrap/SonyUnXml.java

@@ -0,0 +1,60 @@
+package QuickVerifyCrap;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.*;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.Security;
+import java.util.Locale;
+
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+public class SonyUnXml {
+    public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IOException, IllegalBlockSizeException, BadPaddingException {
+
+        Security.addProvider(new BouncyCastleProvider());
+
+        byte[] c = new byte[] {
+                79, -94, 121, -103, -1, -48, -117, 31, -28, -46,
+                96, -43, 123, 109, 60, 23 };
+        SecretKeySpec secretKeySpec = new SecretKeySpec(c, "AES");
+        Cipher cipher = Cipher.getInstance("AES/ECB/ZeroBytePadding");
+        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
+        File f = new File("/home/tgoerner/Downloads/sony-FWH/info3/info.xml");
+        RandomAccessFile f2 = new RandomAccessFile(f,"r");
+        //f2.seek(0x4A);
+        int fl = (int)f.length();
+        byte[] file = new byte[fl];
+
+        int read = f2.read(file);
+        System.out.println(bytesToHex(MessageDigest.getInstance("SHA-1").digest(file)));
+        if(read<fl)
+        {
+            System.err.println("ZARF");
+        }
+
+        byte[] out = cipher.doFinal(file);
+        System.out.println(bytesToHex(MessageDigest.getInstance("SHA-1").digest(out)));
+        FileOutputStream os = new FileOutputStream(new File("/home/tgoerner/Downloads/sony-FWH/info3/info.xml.dec"));
+        os.write(out);
+    }
+
+
+    public static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
+    public static String bytesToHex(byte[] bytes) {
+        char[] hexChars = new char[bytes.length * 2];
+        for (int j = 0; j < bytes.length; j++) {
+            int v = bytes[j] & 0xFF;
+            hexChars[j * 2] = HEX_ARRAY[v >>> 4];
+            hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
+        }
+
+        String hexxit = new String(hexChars).toLowerCase(Locale.ROOT);
+        //hexxit = hexxit.replaceAll("^0+", "");
+        return hexxit;
+    }
+}

+ 155 - 0
QuickStuff/src/main/java/QuickVerifyCrap/SplitSecondArkSplitter.java

@@ -0,0 +1,155 @@
+package QuickVerifyCrap;
+
+import java.io.*;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+public class SplitSecondArkSplitter {
+    public static boolean HACK = true;
+
+    public static void main(String[] args) {
+        HashMap<String, String> filehashes = new HashMap<>();
+        try (PrintWriter bw = new PrintWriter(new FileWriter("D:\\LOA\\000014\\filenames_debugdump.txt",true))) {
+
+            try (BufferedReader br = new BufferedReader(new FileReader("D:\\LOA\\000014\\filenames_preprocessed.txt"))) {
+                br.lines().forEach((line) ->
+                {
+                    long wiggled = SplitSecondChecksumCheck.wiggleChecksum(line);
+                    filehashes.put(wiggled + "", line);
+                    if(HACK)
+                        bw.println(Long.toHexString(wiggled) + "|" + line);
+                });
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            if (HACK)
+                return;
+            String[] levelbases = {"airport_test_03", "docks", "downtown", "end_sequence",
+                    "graveyard", "nem_downtown", "nem_graveyard", "nem_storm", "nem_training", "nem_warehouse", "powerplant"};
+
+            //synthesizing a few patterned names
+            for (int i = 0; i < 1000; i++) {
+                String prefix = String.format("%03d", i);
+                ;
+                for (int j = 0; j < 5; j++) {
+                    filehashes.put(SplitSecondChecksumCheck.wiggleChecksum("q" + prefix + "_rig" + j + "MD.model.stream") + "", "q" + prefix + "_rig" + j + "MD.model.stream");
+                    filehashes.put(SplitSecondChecksumCheck.wiggleChecksum("q" + prefix + "_rig" + j + "L.model.stream") + "", "q" + prefix + "_rig" + j + "L.model.stream");
+                }
+
+                for (String base : levelbases) {
+                    filehashes.put(SplitSecondChecksumCheck.wiggleChecksum(base + ".streamtex." + prefix) + "", base + ".streamtex." + prefix);
+                }
+            }
+
+            try {
+                RandomAccessFile f = new RandomAccessFile(args[0], "r");
+                f.readInt();
+                f.readInt();
+                int files = Integer.reverseBytes(f.readInt());
+                System.out.println(files);
+                f.readInt();
+                f.readInt();
+                f.readInt(); //some bullshit;
+                List<FileMetaData> fileslst = new LinkedList<>();
+                for (int i = 0; i < files; i++) {
+                    FileMetaData fmd = new FileMetaData();
+                    fmd.zipped = f.readInt() != 0;
+                    fmd.offset = Integer.reverseBytes(f.readInt());
+                    fmd.zsize = Integer.reverseBytes(f.readInt());
+                    fmd.size = Integer.reverseBytes(f.readInt());
+                    byte[] csum = new byte[4];
+                    f.read(csum);
+                    long csum2 =
+                            (((long) csum[0]) & 0xFFL)
+                                    + ((((long) csum[1]) & 0xFFL) << 8)
+                                    + ((((long) csum[2]) & 0xFFL) << 16)
+                                    + ((((long) csum[3]) & 0xFFL) << 24);
+                    csum2 = csum2 & 0xFFFFFFFFL;
+                    String filename = filehashes.get("" + csum2);
+                    System.out.println(filename);
+                    System.out.println(Long.toHexString(csum2));
+                    fmd.filename = filename != null ? filename : "UNKNOWN_" + csum2;
+                    fmd.checksum = csum2;
+                    fileslst.add(fmd);
+                }
+                for (FileMetaData fmd : fileslst) {
+                    String arkbasename = new File(args[0]).getName();
+                    String realresult = "Q:\\LOA\\000014\\result\\" + arkbasename + "\\" + fmd.filename;
+                    File dst = new File(realresult);
+                    dst.getParentFile().mkdirs();
+                    bw.println(">>"+arkbasename+"||"+Long.toHexString(fmd.checksum)+"||"+fmd.filename);
+                    if (fmd.zipped) {
+
+                        String outfile = "Q:\\LOA\\000014\\scratch\\out.dat";
+                        File of = new File(outfile);
+                        of.getParentFile().mkdirs();
+                        of.delete(); //zapping old file leftovers
+                        byte[] compressed = new byte[fmd.zsize - 4];
+                        f.seek(fmd.offset);
+                        int size = Integer.reverseBytes(f.readInt());
+                        f.read(compressed);
+                        RandomAccessFile rof = new RandomAccessFile(of, "rw");
+                        rof.writeInt(fmd.zsize - 4);
+                        rof.writeInt(size);
+                        rof.write(compressed);
+                        rof.close();
+                        File workdir = new File("D:\\LOA\\000014\\scratch");
+                        runTool(workdir, "D:\\LOA\\000014\\quickbms.exe", "-R", "D:\\LOA\\000014\\helper.bms", outfile);
+                        String transferfile = "D:\\LOA\\000014\\scratch\\result.dat";
+                        new File(transferfile).renameTo(dst);
+                    } else {
+                        byte[] compressed = new byte[fmd.zsize];
+                        f.seek(fmd.offset);
+                        f.read(compressed);
+                        RandomAccessFile rof = new RandomAccessFile(dst, "rw");
+                        rof.write(compressed);
+                        rof.close();
+                    }
+                }
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    static class FileMetaData {
+        int size;
+        int zsize;
+        int offset;
+        boolean zipped;
+        String filename;
+        long checksum;
+    }
+
+
+    public static void runTool(String... args) throws IOException {
+
+        runTool(null, args);
+    }
+
+
+    public static void runTool(File workdir, String... args) throws IOException {
+        ProcessBuilder pb = new ProcessBuilder();
+        pb.command(args);
+        if (workdir != null && workdir.isDirectory()) {
+            pb.directory(workdir);
+        }
+        pb.redirectOutput(new File("D:\\LOA\\000014\\scratch\\out.txt"));
+        pb.redirectError(new File("D:\\LOA\\000014\\scratch\\err.txt"));
+        Process runme = pb.start();
+        try {
+            runme.waitFor();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 87 - 0
QuickStuff/src/main/java/QuickVerifyCrap/SplitSecondChecksumCheck.java

@@ -0,0 +1,87 @@
+package QuickVerifyCrap;
+
+import de.nplusc.izc.tools.baseTools.Tools;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Locale;
+
+public class SplitSecondChecksumCheck {
+    public static void main(String[] args) {
+        String checkthis = "Environments\\Levels\\nem_training\\Cameras\\TakedownSequences\\TakeDownSequences.xml";
+        long cs = wiggleChecksum(checkthis);
+        System.out.println(cs);
+        //1183085413 = 0x46847365
+    }
+
+    static long wiggleChecksum(String checksumtarget)
+    {
+        byte[] raw = checksumtarget.toLowerCase(Locale.ROOT).getBytes(StandardCharsets.UTF_8);
+        long csum = 0;
+        for(byte c:raw)
+        {
+            //long massagedChar = massage_character(c&0xFF);
+            //System.out.println(c);
+            csum =csum*0x1f+c;
+            csum = csum&0xFFFFFFFFL;
+        }
+        //System.out.println(Long.toHexString(csum));
+        return csum;
+    }
+
+
+    static long massage_character(int param_1)
+
+    {
+        //System.out.println(param_1);
+        if (0x19 < param_1 - 0x41)
+        {
+            if (0xbf < (int)param_1)
+            {
+                if (param_1 == 0xd7)
+                {
+                    return 0xd7;
+                }
+                if ((int)param_1 < 0xdf)
+                {
+                    return param_1 + 0x20; //was LAB_005312fc:
+                }
+                if (0xff < (int)param_1)
+                {
+                    if (0x137 < (int)param_1)
+                    {
+                        if (param_1 == 0x138)
+                        {
+                            return 0x138;
+                        }
+                        if (0x148 < (int)param_1)
+                        {
+                            if (param_1 == 0x149)
+                            {
+                                return 0x149;
+                            }
+                            if ((int)param_1 < 0x178)
+                            {
+                                return param_1 | 1; //was goto:LAB_0053132b:
+                            }
+                            if (param_1 == 0x178)
+                            {
+                                return 0xff;
+                            }
+                            if (0x17e < (int)param_1)
+                            {
+                                return param_1;
+                            }
+                        }
+                        return (param_1 & 1) + param_1;
+                    }
+                    //LAB_0053132b:
+                    return param_1 | 1;
+                }
+            }
+            return param_1;
+        }
+        //LAB_005312fc:
+        return param_1 + 0x20;
+    }
+
+}

+ 29 - 0
QuickStuff/src/main/java/QuickVerifyCrap/SuperToothPuller.java

@@ -0,0 +1,29 @@
+package QuickVerifyCrap;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+
+public class SuperToothPuller {
+    public static void main(String[] args) throws FileNotFoundException {
+        try(PrintStream puller = new PrintStream(new FileOutputStream("Q:\\LOA\\000013\\supertoothpuller.missingIDs.txt")))
+        {
+            char[] hexer = "0123456789ABCDEF".toCharArray();
+            for(int i=0;i<16;i++)
+            {
+                for(int j=0;j<16;j++)
+                {
+                    for(int k=0;k<16;k++)
+                    {
+                        for(int l=0;l<16;l++)
+                        {
+                            String id = new String(new char[]{hexer[i],hexer[j],hexer[k],hexer[l]});
+                            puller.println("wget www.supertooth.net/Download/Firmwares/"+id+".txt");
+                            puller.println("wget www.supertooth.net/Download/Firmwares/"+id.toLowerCase()+".txt");
+                        }
+                    }
+                }
+            }
+        }
+    }
+}

+ 86 - 0
QuickStuff/src/main/java/QuickVerifyCrap/UTPackMangler.java

@@ -0,0 +1,86 @@
+package QuickVerifyCrap;
+
+import java.io.*;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+public class UTPackMangler {
+    public static void main(String[] args) throws Exception{
+        try{
+        BufferedReader r = new BufferedReader(new FileReader("C:\\LMAA\\packs.dedup.txt.UE"));
+        String line = r.readLine();
+        long totalBytes = 0;
+        long totalCompressedbytes = 0;
+        long linesMangled = 0;
+        Set<String> remotepaths = new HashSet<>();
+        System.out.println("Mangling File...");
+        List<PackData> packs = new LinkedList<>();
+        while(line !=null)
+        {
+            String[] splitted = line.split("\"");
+            if(splitted.length<2)
+            {
+                System.out.println(line);
+            }
+            else
+            {
+            PackData p = new PackData();
+            p.hash = splitted[1];
+            p.remotepath = splitted[7];
+            int size = Integer.valueOf(splitted[3]);
+            int comppressedSize = Integer.valueOf(splitted[5]);
+            totalBytes += size;
+            totalCompressedbytes += comppressedSize;
+            p.size = size;
+            p.compressedSize= comppressedSize;
+
+            remotepaths.add(p.remotepath);
+            linesMangled++;
+            if(linesMangled%1000==0)
+            {
+                System.out.println("Mangled:"+linesMangled);
+            }
+            packs.add(p);
+            }
+            line = r.readLine();
+        }
+        PrintStream w = new PrintStream(new FileOutputStream("C:\\LMAA\\downloader.sh"));
+        w.println("#!/bin/bash");
+        w.println("echo Generating directories");
+        remotepaths.forEach((s)->
+        {
+            w.println("mkdir -p "+s);
+        });
+        w.println("echo Downloading....");
+        long totalMb = totalBytes/1024/1024;
+        long totalMbComp = totalCompressedbytes/1024/1024;
+
+        w.println("echo Total Size: "+ totalMb+ "Total Compressed Size" +totalMbComp);
+        System.out.println("echo Total Size: "+ totalMb+ "Total Compressed Size" +totalMbComp);
+        long progress = 0;
+        for(PackData p:packs)
+        {
+            String serverPath = "http://cdn.unrealengine.com/dependencies/"+p.remotepath+"/"+p.hash;
+            String downloadcmd = "wget -nc -qO ./"+p.remotepath+"/"+p.hash+" "+serverPath;
+            w.println(downloadcmd);
+            progress += p.compressedSize;
+            w.println("echo -ne \"Downloaded "+(progress/1024/1024)+" of" +totalMbComp+" MB\\r\"");
+
+        }
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+}
+
+class PackData
+{
+    int size;
+    int compressedSize;
+    String hash;
+    String remotepath;
+}

BIN
SenaBitWiggler/Adapter-Details/PWNa-Adapter-Pinout.png


+ 15 - 4
SenaBitWiggler/build.gradle

@@ -1,6 +1,6 @@
 defaultTasks 'distZip'
 
-apply plugin: 'java'
+apply plugin: 'java-library'
 apply plugin: 'application'
 
 
@@ -23,7 +23,18 @@ repositories{
 }
 
 dependencies{
-    compile "org.yaml:snakeyaml:1.14"
-    compile("com.google.guava:guava:31.0.1-jre")
-	compile( 'info.picocli:picocli:4.6.2')
+    api "org.yaml:snakeyaml:1.14"
+    api("com.google.guava:guava:31.0.1-jre")
+	api( 'info.picocli:picocli:4.6.2')
+	api('io.github.ma1uta.matrix:client-impl:+')
+	api group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-iostreams', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '2.+'
+
+
+	api('org.jboss.resteasy:resteasy-client-microprofile:4.6+')
+	api('org.jboss.resteasy:resteasy-jackson2-provider:4.6+')
+	api('javax.enterprise:cdi-api:1.2')
 }

+ 2 - 1
SenaBitWiggler/src/main/resources/PromptConfigs/10S.prompts.yml → SenaBitWiggler/src/dist/devices/10S.device.yml

@@ -18,4 +18,5 @@ ALL: "PCM"
 "52": "IMA"
 "53": "IMA"
 "58": "IMA"
-maincpu: "10S.img"
+maincpu: "10S.img"
+manufacturer: "Sena"

+ 2 - 0
SenaBitWiggler/src/main/resources/PromptConfigs/50S.prompts.yml → SenaBitWiggler/src/dist/devices/50S.device.yml

@@ -1,3 +1,5 @@
 file: "vp.bin"
 ALL: "PCM"
 maincpu: "Sena_50S_BT.dfu"
+experimental: true
+manufacturer: "Sena"

+ 5 - 0
SenaBitWiggler/src/dist/devices/SRL2.device.yml

@@ -0,0 +1,5 @@
+ALL: "PCM"
+file: "vp.bin"
+maincpu: "SRL2_M0.img"
+auxcpu: "SRL2_M1.img"
+manufacturer: "Sena"

+ 50 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/Configuration.java

@@ -4,6 +4,48 @@ public class Configuration {
     private String BlueLabPath;
     private String SoxPath;
 
+    private boolean MatrixEnabled = false;
+
+    private String MatrixUser;
+
+    private String MatrixPassword;
+
+    private String MatrixDomain;
+
+    private String ArchiveOrgCollection;
+
+    public String getMatrixDomain() {
+        return MatrixDomain;
+    }
+
+    public void setMatrixDomain(String matrixDomain) {
+        MatrixDomain = matrixDomain;
+    }
+
+    public boolean isMatrixEnabled() {
+        return MatrixEnabled;
+    }
+
+    public String getMatrixPassword() {
+        return MatrixPassword;
+    }
+
+    public String getMatrixUser() {
+        return MatrixUser;
+    }
+
+    public void setMatrixEnabled(boolean matrixEnabled) {
+        MatrixEnabled = matrixEnabled;
+    }
+
+    public void setMatrixPassword(String matrixPassword) {
+        MatrixPassword = matrixPassword;
+    }
+
+    public void setMatrixUser(String matrixUser) {
+        MatrixUser = matrixUser;
+    }
+
     public String getBlueLabPath() {
         return BlueLabPath;
     }
@@ -19,4 +61,12 @@ public class Configuration {
     public void setSoxPath(String soxPath) {
         SoxPath = soxPath;
     }
+
+    public String getArchiveOrgCollection() {
+        return ArchiveOrgCollection;
+    }
+
+    public void setArchiveOrgCollection(String archiveOrgCollection) {
+        ArchiveOrgCollection = archiveOrgCollection;
+    }
 }

+ 41 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/DataStructures/QualCommHeaderRecord.java

@@ -0,0 +1,41 @@
+package de.nplusc.izc.senabitwiggler.DataStructures;
+
+public class QualCommHeaderRecord {
+    public int size;
+    public String filename;
+
+    public short location;
+    public short sublocation;
+
+    public short getLocation() {
+        return location;
+    }
+
+    public void setLocation(short location) {
+        this.location = location;
+    }
+
+    public short getSublocation() {
+        return sublocation;
+    }
+
+    public void setSublocation(short sublocation) {
+        this.sublocation = sublocation;
+    }
+
+    public int getSize() {
+        return size;
+    }
+
+    public void setSize(int size) {
+        this.size = size;
+    }
+
+    public String getFilename() {
+        return filename;
+    }
+
+    public void setFilename(String filename) {
+        this.filename = filename;
+    }
+}

+ 33 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/DataStructures/QualCommWrapper.java

@@ -0,0 +1,33 @@
+package de.nplusc.izc.senabitwiggler.DataStructures;
+
+public class QualCommWrapper {
+    public byte[] header;
+    public byte[] footer;
+    public QualCommHeaderRecord[] files;
+
+    public byte[] getHeader() {
+        return header;
+    }
+
+    public void setHeader(byte[] header) {
+        this.header = header;
+    }
+
+    public byte[] getFooter() {
+        return footer;
+    }
+
+    public void setFooter(byte[] footer) {
+        this.footer = footer;
+    }
+
+    public QualCommHeaderRecord[] getFiles() {
+        return files;
+    }
+
+    public void setFiles(QualCommHeaderRecord[] files) {
+        this.files = files;
+    }
+
+
+}

+ 50 - 9
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/EntryPoint.java

@@ -2,6 +2,11 @@ package de.nplusc.izc.senabitwiggler;
 
 import java.io.*;
 
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.LoggerConfig;
 import org.yaml.snakeyaml.Yaml;
 import picocli.CommandLine;
 import picocli.CommandLine.Command;
@@ -11,6 +16,8 @@ import picocli.CommandLine.Parameters;
 @Command(mixinStandardHelpOptions = true, version = "Sena Firmware Hacking Utiility")
 public class EntryPoint implements Runnable
 {
+    private static final Logger l = LogManager.getLogger();
+
     @Parameters(index = "0", description = "Mode for the Program. Valid values: ${COMPLETION-CANDIDATES}")
     private Modes mode;
 
@@ -21,7 +28,7 @@ public class EntryPoint implements Runnable
     @Parameters(index = "2", description = "Disassembled Data Folder")
     private File output;
 
-    @Parameters(index = "3", arity = "0..1", description = "Headset ID. Any value if not in the Prompt unpacking mode")
+    @Parameters(index = "3", arity = "0..1", description = "Headset ID. Any value if not in the Prompt unpacking mode.")
     private String headset;
 
     @Option(names = { "-d", "--deep" }, description = "Deep Dissect. Splits everything down and reassembles from those low-level modules. Also yields a partial disassembly.")
@@ -34,6 +41,8 @@ public class EntryPoint implements Runnable
     public static String SoxPath = "";
     public static String BlueLabPath = "";
 
+    public static Configuration c;
+
     public static final String APPDIR = new File(EntryPoint.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getParentFile().getParent();
 
     public static void main(String[] args)
@@ -46,9 +55,10 @@ public class EntryPoint implements Runnable
                 Configuration config = y.loadAs(new FileReader(cfg),Configuration.class);
                 SoxPath=config.getSoxPath();
                 BlueLabPath=config.getBlueLabPath();
-            } catch (FileNotFoundException e) {
-                System.err.println("Hurz");
-                e.printStackTrace();
+                c=config;
+                y.dump(config, new FileWriter(cfg));
+            } catch (IOException e) {
+                l.catching(e);
             }
         }
         else
@@ -58,9 +68,9 @@ public class EntryPoint implements Runnable
             config.setSoxPath("sox");
             try {
                 y.dump(config, new FileWriter(cfg));
-                System.err.println("Configuration needed. Check the generated config.yml");
+                l.error("Configuration needed. Check the generated config.yml");
             } catch (IOException e) {
-                System.err.println("Failed to initialize config");
+                l.error("Failed to initialize config");
                 e.printStackTrace();
             }
             System.exit(0);
@@ -73,7 +83,22 @@ public class EntryPoint implements Runnable
 
     @Override
     public void run() {
-        //TODO check and init config file
+        System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager"); //HACK to catch java.util.logging loggers
+        LoggerContext cx = (LoggerContext) LogManager.getContext(false);
+        org.apache.logging.log4j.core.config.Configuration config = cx.getConfiguration();
+
+        LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
+
+        if (verbose)
+        {
+            loggerConfig.setLevel(Level.TRACE);
+        }
+        else
+        {
+            loggerConfig.setLevel(Level.INFO);
+        }
+
+
         switch(mode)
         {
             case ExtractSenaBin:
@@ -81,7 +106,7 @@ public class EntryPoint implements Runnable
                     Utils.makeSureThatOutFolderIsCreated(output.getPath());
                     FirmwareWrapperExtraction.extractFirmwareLong(input,output.getPath());
                 } catch (InputInvalidException e) {
-                    System.out.println("Zarf! File was bad");
+                    l.error("Zarf! File was bad");
                     e.printStackTrace();
                 }
                 break;
@@ -123,6 +148,18 @@ public class EntryPoint implements Runnable
             case FlashFS512x:
                 FlashFSUnWiggler.unpackFSQCC512x(input,output);
                 break;
+            case FlashFSCSR86xx:
+                FlashFSUnWiggler.unpackCSRFS(input,output);
+                break;
+            case DfuS512x:
+                FlashFSUnWiggler.unpackQCC512DFU(input,output);
+                break;
+            case WriteDfuS512x:
+                FlashFSUnWiggler.repackQualcommWrapper(input,output);
+                break;
+            case ScanForSenaFirmware:
+                FirmwareAutoDumper.pullFirmwares(input,output,weNeedToGoDeeper);
+                break;
         }
     }
 }
@@ -139,7 +176,11 @@ enum Modes
     Jailbreak,
     DumpFlashes,
     ResignDFU,
-    FlashFS512x
+    FlashFS512x,
+    FlashFSCSR86xx,
+    DfuS512x,
+    WriteDfuS512x,
+    ScanForSenaFirmware
 }
 
 // http://www.tinyosshop.com/download/ADK_CSR867x.WIN4.3.1.5.zip für die tools

+ 81 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/Firmware.java

@@ -0,0 +1,81 @@
+package de.nplusc.izc.senabitwiggler;
+
+import java.util.HashMap;
+
+public class Firmware {
+    private String DeviceId;
+    private HashMap<String, FirmwareVersion> versions;
+    private boolean InitialDLDone;
+
+    private boolean IAItemCreated = false;
+
+    private int major;
+    private int minor;
+    private int patch;
+
+    private String roomid;
+
+    public String getRoomid() {
+        return roomid;
+    }
+
+    public void setRoomid(String roomid) {
+        this.roomid = roomid;
+    }
+
+    public int getMajor() {
+        return major;
+    }
+
+    public void setMajor(int major) {
+        this.major = major;
+    }
+
+    public int getMinor() {
+        return minor;
+    }
+
+    public void setMinor(int minor) {
+        this.minor = minor;
+    }
+
+    public int getPatch() {
+        return patch;
+    }
+
+    public void setPatch(int patch) {
+        this.patch = patch;
+    }
+
+    public HashMap<String, FirmwareVersion> getVersions() {
+        return versions;
+    }
+
+    public void setVersions(HashMap<String, FirmwareVersion> versions) {
+        this.versions = versions;
+    }
+
+    public boolean isInitialDLDone() {
+        return InitialDLDone;
+    }
+
+    public void setInitialDLDone(boolean initialDLDone) {
+        InitialDLDone = initialDLDone;
+    }
+
+    public String getDeviceId() {
+        return DeviceId;
+    }
+
+    public void setDeviceId(String deviceId) {
+        DeviceId = deviceId;
+    }
+
+    public boolean isIAItemCreated() {
+        return IAItemCreated;
+    }
+
+    public void setIAItemCreated(boolean IAItemCreated) {
+        this.IAItemCreated = IAItemCreated;
+    }
+}

+ 731 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/FirmwareAutoDumper.java

@@ -0,0 +1,731 @@
+package de.nplusc.izc.senabitwiggler;
+
+import io.github.ma1uta.matrix.client.StandaloneClient;
+import io.github.ma1uta.matrix.client.model.room.CreateRoomRequest;
+import io.github.ma1uta.matrix.event.content.RoomPowerLevelsContent;
+import io.github.ma1uta.matrix.impl.exception.MatrixException;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.yaml.snakeyaml.DumperOptions;
+import org.yaml.snakeyaml.TypeDescription;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+import org.yaml.snakeyaml.nodes.Tag;
+import org.yaml.snakeyaml.representer.Representer;
+
+import javax.swing.plaf.nimbus.State;
+import java.io.*;
+import java.nio.file.CopyOption;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.function.Consumer;
+
+public class FirmwareAutoDumper
+{
+    private static final Logger l = LogManager.getLogger();
+    static Statefile state = null;
+    static File outfolder_base;
+    public static final boolean IA_UPLOAD_ENABLED = false;
+    public static final boolean DUMMY_MODE = false;
+    public static PrintStream dummydownloadfake = null;
+    public static HashMap<String,FirmwareVersion> supprCache = new HashMap<>();
+
+    private static final String[] hackfixsuffixes = new String[]
+            {"-rc","rc","-build","build"};
+
+    private static final String[] fileextensionfuckyous = new String[]
+            {"Pro.img"};
+
+    private static final Map<String,List<String>> forceVersionsForCheck = new HashMap<>();
+
+    private static final String[][] indexes = new String[][]
+            {{
+        "main","http://firmware.sena.com/senabluetoothmanager/Firmware"},{
+        "harley","http://firmware.sena.com/senabluetoothmanager/harleyFirmware"},{
+        "cradlemain","http://firmware.sena.com/senabluetoothmanager/WiFiCradle/bt_img/Firmware"},{
+        "cradleharley","http://firmware.sena.com/senabluetoothmanager/WiFiCradle/bt_img/harleyFirmware"}};
+
+
+    public static void pullFirmwares(File statefile, File outfolder, boolean deepmode)
+    {
+        outfolder_base=outfolder;
+        try {
+            if (DUMMY_MODE) {
+                dummydownloadfake = new PrintStream(new FileOutputStream(new File(outfolder, "dummy.log")));
+            }
+
+
+
+            Representer representer = new Representer();
+            representer.addClassTag(Firmware.class, new Tag("!FW"));
+            representer.addClassTag(FirmwareVersion.class, new Tag("!FWV"));
+
+
+            Yaml y = new Yaml(representer, new DumperOptions());
+
+            if (statefile.exists()) {
+                try {
+                    Constructor constructor = new Constructor();
+                    constructor.addTypeDescription(new TypeDescription(Firmware.class, "!FW"));
+                    constructor.addTypeDescription(new TypeDescription(FirmwareVersion.class, "!FWV"));
+
+                    Yaml internal = new Yaml(constructor);
+                    state = (Statefile) internal.load(new FileReader(statefile));
+                } catch (FileNotFoundException e) {
+                    l.catching(e);
+                }
+            } else {
+                state = new Statefile();
+                state.setFirmwares(new LinkedHashMap<>());
+            }
+
+            BufferedReader fakerfile = new BufferedReader(new FileReader(statefile.toString()+".forced"));
+            fakerfile.lines().forEach((line)->
+            {
+                String[] linesplitted = line.split("::");
+                if(linesplitted.length!=2)
+                {
+                    l.warn("Malformed Line at forcefile: "+line);
+                }
+                else
+                {
+                    forceVersionsForCheck.putIfAbsent(linesplitted[0],new ArrayList<>());
+                    List<String> fakeindex = forceVersionsForCheck.get(linesplitted[0]);
+                    fakeindex.add(linesplitted[1]);
+                }
+            });
+
+            state.getFirmwares().forEach((k,v)->
+            {
+                v.getVersions().entrySet().removeIf((e)->{
+                    if(
+                            (!e.getValue().isFiller())
+                            && e.getValue().getServerCreationDate().equals(new Date(0)) // suspicious crap versions from a bugged run. nuking them
+                            )
+                    {
+                        l.info("Removed a suspicious version: "+e.getKey());
+                        return true;
+                    };
+
+                    return false;
+                });
+            });
+
+
+            File outfolder_tmp = new File(outfolder, "tmp");
+
+            File outfolder_archivarius = new File(outfolder, "archivarius");
+            outfolder_archivarius.mkdirs();
+
+            File archiveorgCSV = new File(outfolder_archivarius,"upload.csv");
+
+            for(String[] index:indexes)
+            {
+                if (!DUMMY_MODE) {
+                    new File(outfolder_tmp, "Firmware").delete();
+                }
+                File downloadFolderBase = new File(outfolder_base, "downloadstage");
+                downloadFolderBase.mkdirs();
+                File fw = new File(outfolder_tmp, "Firmware");
+                outfolder_tmp.mkdirs();
+                if (!fw.exists()) // should only happen in dummy mode or if something zarfed out while dev
+                {
+                    Utils.runTool(outfolder_tmp,
+                            "wget",
+                            index[1],
+                            "-O",
+                            "Firmware"
+                    );
+                }
+
+                BufferedReader br = new BufferedReader(new FileReader(fw));
+                final HashMap<String, String> basenamelookup = new LinkedHashMap<>();
+                // filename --> real basename
+
+                Consumer<String> linehandler = (line_raw) ->
+                {
+                    String realExt = null;
+                    String line = line_raw;
+                    for(String suffixcheck:fileextensionfuckyous)
+                    {
+                        if(line_raw.endsWith(suffixcheck))
+                        {
+                            realExt = suffixcheck;
+                        }
+                    }
+
+
+
+                    String[] linesplitted = line.split(":");
+
+                    String FWFileName;
+                    String FWBAsename = "ZÖINKS!";
+                    if (linesplitted.length == 4) {
+                        FWBAsename = linesplitted[0] + "-" + linesplitted[2];
+                        FWFileName = linesplitted[3];
+                    } else if (linesplitted.length == 3) {
+                        FWBAsename = linesplitted[0] + "-NOLNG";
+                        FWFileName = linesplitted[2];
+                    } else {
+                        return;
+                    }
+
+                    if (basenamelookup.containsKey(FWFileName)) {
+                        return; //languageless file, no need to handle multiple times.
+                    } else {
+                        basenamelookup.put(FWFileName, FWBAsename);
+                    }
+
+
+                    if (!state.getFirmwares().containsKey(FWBAsename)) {
+                        Firmware tmp = new Firmware();
+                        tmp.setDeviceId(FWBAsename);
+                        tmp.setInitialDLDone(false);
+                        tmp.setVersions(new LinkedHashMap<>());
+                        state.getFirmwares().put(FWBAsename, tmp);
+                    }
+
+                    Firmware f = state.getFirmwares().get(FWBAsename);
+
+                    try {
+                        l.info("Processing line:" + line + "\n Basename:" + FWBAsename + "of index "+index[0]);
+                        int[] fwnumber = splitVersionAndPullFW(
+                                FWFileName,
+                                f.getVersions(),
+                                deepmode,
+                                index[0], "Sus Version with File line: "+line,
+                                realExt);
+                        f.setMajor(fwnumber[0]);
+                        f.setMinor(fwnumber[1]);
+                        f.setPatch(fwnumber[2]);
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                };
+
+                br.lines().forEach(linehandler);
+
+                //forcelist entires = index entries with index name prepended with a ::, prefix already removed at this point
+                var forceToCheck = forceVersionsForCheck.getOrDefault(index[0],new ArrayList<String>()); //empty for no forcelist entries
+                forceToCheck.forEach(linehandler);
+                br.close();
+                y.dump(state, new FileWriter(statefile));
+                if (!DUMMY_MODE) {
+                    new File(outfolder_tmp, "Firmware").delete();
+                    pushToMatrix();
+
+                }
+
+            }
+
+
+            if(DUMMY_MODE)
+            {
+                dummydownloadfake.close();
+            }
+            generateIACSV(archiveorgCSV,outfolder);
+            y.dump(state,new FileWriter(statefile));
+        }
+        catch (IOException ex)
+        {
+            ex.printStackTrace();
+        }
+    }
+
+    private static void generateIACSV(File destination, File outbase)
+    {
+        if(EntryPoint.c.getArchiveOrgCollection()==null)
+        {
+            return; //kein archive.org file da nicht configuriert
+        }
+        HashSet<String> csvlines = new HashSet<>();
+        state.getFirmwares().forEach((k,v)->
+        {
+
+            String[] keysplitted = k.split("-");
+
+            String key_delanguaged = keysplitted[0];
+            if(keysplitted.length>=2)
+            {
+                for(int i=1;i<keysplitted.length-1;i++)
+                {
+                    key_delanguaged = key_delanguaged+"-"+keysplitted[i];
+                }
+            }
+            //key_delanguaged.replace(".","_");
+            final String itemname = "sena_firmware_files_"+key_delanguaged;
+            v.getVersions().forEach((k2,v2)->
+            {
+                if((!v2.isIAUploaded()&&(!v2.isFiller())))
+                {
+                    v2.setIAUploaded(true);
+                    String filename = new File(outbase,v2.getFilename()).getAbsoluteFile().toString();
+                    csvlines.add(itemname+","+filename+",firmware,"+EntryPoint.c.getArchiveOrgCollection()+",software");
+                }
+            });
+        });
+        try (FileOutputStream w = new FileOutputStream(destination);PrintStream p = new PrintStream(w);)
+        {
+            p.println("identifier,file,subject,collection,mediatype");
+            String[] lines = csvlines.toArray(new String[csvlines.size()]);
+            for(String line :lines)
+            {
+                p.println(line);
+            }
+        } catch (IOException e) {
+            l.warn("IO Error on generateIACSV");
+        }
+    }
+
+    private static void pushToMatrix()
+    {
+        if(!EntryPoint.c.isMatrixEnabled())
+        {
+            //skip all if matrix is off.
+            return;
+        }
+        StandaloneClient mxClient = new StandaloneClient.Builder().domain(EntryPoint.c.getMatrixDomain()).build();
+        mxClient.auth().login(EntryPoint.c.getMatrixUser(), EntryPoint.c.getMatrixPassword().toCharArray());
+        if(state.getGeneralRoomId()==null)
+        {
+            l.info("Create Matrix Room General");
+            CreateRoomRequest r = new CreateRoomRequest();
+            r.setName("Sena Full Logstream");
+            r.setRoomAliasName("SenaFirmwareAll");
+            RoomPowerLevelsContent lvls = new RoomPowerLevelsContent();
+            lvls.setEventsDefault((byte)1); //readonly except for the BitWiggler
+            r.setPowerLevelContentOverride(lvls);
+            r.setVisibility("public");
+            state.setGeneralRoomId(mxClient.room().create(r).getRoomId());
+        }
+
+        if(state.getOtherRoomId()==null)
+        {
+            l.info("Create Matrix Room Catchall");
+            CreateRoomRequest r = new CreateRoomRequest();
+            r.setName("Sena Other Logstream");
+            r.setRoomAliasName("SenaFirmwareOther");
+            RoomPowerLevelsContent lvls = new RoomPowerLevelsContent();
+            lvls.setEventsDefault((byte)1); //readonly except for the BitWiggler
+            r.setPowerLevelContentOverride(lvls);
+            r.setVisibility("public");
+            state.setOtherRoomId(mxClient.room().create(r).getRoomId());
+        }
+
+        state.getFirmwares().forEach((k,v)->
+        {
+            if(v.getRoomid()==null)
+            {
+                l.info("Create Matrix Room for:"+k);
+                CreateRoomRequest r = new CreateRoomRequest();
+                r.setName("Sena Logstream: "+v.getDeviceId());
+                r.setRoomAliasName("SenaStream"+k);
+                RoomPowerLevelsContent lvls = new RoomPowerLevelsContent();
+                lvls.setEventsDefault((byte)1); //readonly except for the BitWiggler
+                r.setPowerLevelContentOverride(lvls);
+                r.setVisibility("public");
+                while(v.getRoomid()==null)
+                {
+                    try {
+
+                        v.setRoomid(mxClient.room().create(r).getRoomId());
+                    }
+                    catch(MatrixException e)
+                    {
+
+                    }
+                    if(v.getRoomid()==null)
+                    {
+                        try {
+                            Thread.sleep(2000);
+                        } catch (InterruptedException e) {
+                            e.printStackTrace();
+                        }
+                    }
+                }
+            }
+
+            List<String> keys = new ArrayList<>(v.getVersions().keySet());
+            keys.sort((x,y)->
+            {
+                var vr = v.getVersions();
+                var version1 = vr.get(x);
+                var version2 = vr.get(y);
+                if(version1.getMajor()< version2.getMajor()) {
+                    return -1;
+                }
+                if(version1.getMajor()> version2.getMajor()) {
+                    return 1;
+                }
+                if(version1.getMinor()< version2.getMinor()) {
+                    return -1;
+                }
+                if(version1.getMinor()> version2.getMinor()) {
+                    return 1;
+                }
+                if(version1.getPatch()< version2.getPatch()) {
+                    return -1;
+                }
+                if(version1.getPatch()> version2.getPatch()) {
+                    return 1;
+                }
+                return 0;
+            });
+            for (var v2p : keys) {
+                final var v2 = v.getVersions().get(v2p); //HAXX
+                LinkedList<Runnable> messageActions = new LinkedList<>();
+
+                if(!v2.isFiller())
+                {
+                    String lastSuffix = v2.isRc_hackfix()?v2.getHackfix():".";
+                    String version = v2.getMajor()+"."+v2.getMinor()+lastSuffix+v2.getPatch();
+                    String index = v2.getFirmwareLocation();
+                    Date ts = v2.getServerCreationDate();
+                    TimeZone tz = TimeZone.getTimeZone("UTC");
+                    DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'"); // Quoted "Z" to indicate UTC, no timezone offset
+                    df.setTimeZone(tz);
+                    String date = df.format(ts);
+                    String msg = "Detected new Version: "+version+" for "+k+" uploaded at: "+date+ "on index "+index;
+
+                    if(v2.isHidden())
+                    {
+                        msg = "Guessed new hidden Version: "+version+" for "+k+" uploaded at: "+date+ "on index "+index;
+                    }
+                    if(v2.getSusVersion()!=null)
+                    {
+                        msg = msg +"\n"+v2.getSusVersion();
+                    }
+                    if((!v2.isHidden()&&v2.getNotificationState()==MatrixState.SENT_PRELIM)||v2.getNotificationState()==MatrixState.TODO)
+                    {
+                        final String msg2 = msg;
+                        messageActions.add(()->
+                        {
+                            l.info("Push: "+msg2);
+                            mxClient.event().sendMessage(v.getRoomid(), msg2);
+                            mxClient.event().sendMessage(state.getGeneralRoomId(), msg2);
+                            v2.setNotificationState(v2.isHidden()?MatrixState.SENT_PRELIM:MatrixState.SENT);
+                        });
+                    }
+                }
+                messageActions.iterator().forEachRemaining(runnable -> runnable.run());
+            }
+        });
+        mxClient.auth().logout();
+    }
+
+
+
+    private static int[] splitVersionAndPullFW(
+            String filename,
+            HashMap<String,
+            FirmwareVersion> knownVersions,
+            boolean deepmode,String indexUsed,
+            String useForSusVersion,
+            String realext) throws IOException {
+        String[] magic = filename.split("-v");
+        boolean fuckingoddity = false;
+        boolean hackfix50R_SR = false;
+        if(magic.length==1)
+        {
+            fuckingoddity = true;
+            magic = filename.split("_v");
+            if(magic.length==1)
+            {
+                hackfix50R_SR = true;
+                magic = filename.split("SRv");
+
+            }
+        }
+
+        String version = magic[1];
+        boolean rchackfix = false;
+        String hackfixsuffix = ".";
+        for(String suffixcheck:hackfixsuffixes)
+        {
+            if(version.contains(suffixcheck))
+            {
+                rchackfix=true;
+                version = version.replace(suffixcheck,".");
+                hackfixsuffix = suffixcheck;
+            }
+        }
+
+        String[] vsplit = version.split("\\.");
+
+        if(realext != null) //Hackfix again since Sena got no consistency in the file naming scheme... ,,|,,
+        {
+            int suffixlen = realext.split("\\.").length;
+            ArrayList tmp = new ArrayList<String>(vsplit.length);
+            tmp.addAll(Arrays.asList(vsplit));
+            vsplit = (String[])(tmp.subList(0,vsplit.length-(suffixlen-1)).toArray(new String[1]));
+            vsplit[vsplit.length-1]=realext;
+        }
+
+        String suffix = "";
+        int major=0,minor=0,patch=0;
+        major=Integer.valueOf(vsplit[0]);
+        if(vsplit.length==5&&rchackfix)  // another hackfix since sena tries to trololol me..., ,,|,,
+        {
+            minor = Integer.valueOf(vsplit[1]);
+            patch = Integer.valueOf(vsplit[2]);
+            suffix = suffix = hackfixsuffix+vsplit[3]+"."+vsplit[4];
+            rchackfix=false;
+        }
+        else
+        {
+            if(vsplit.length==4)
+            {
+
+                minor = Integer.valueOf(vsplit[1]);
+                try
+                {
+                    patch = Integer.valueOf(vsplit[2]);
+                    suffix = "."+vsplit[3];
+                }
+                catch(NumberFormatException ex)
+                {
+                    patch = Integer.valueOf(vsplit[2].substring(0,1));
+                    if(vsplit[2].length()>1)
+                    {
+                        suffix = vsplit[2].substring(1)+"."+vsplit[3];
+                    }
+                    else
+                    {
+                        suffix = "."+vsplit[3];
+                    }
+                }
+
+            }
+            else
+            {
+                if(vsplit[1].length()>1)
+                {
+                    minor = Integer.valueOf(vsplit[1].substring(0,1));
+                    suffix = vsplit[1].substring(1)+"."+vsplit[2];
+                }
+                else
+                {
+                    minor = Integer.valueOf(vsplit[1].substring(0,1));
+                    suffix = "."+vsplit[2];
+                }
+            }
+        }
+
+        String prefix = magic[0]+(fuckingoddity?"_":"-")+"v";
+        if(hackfix50R_SR)
+        {
+            prefix = magic[0]+"SRv";
+        }
+        //suffix = suffix+".img";
+
+        scanDownwards(major,minor,patch,prefix,suffix,knownVersions,rchackfix,hackfixsuffix,indexUsed, useForSusVersion);
+
+        //scanning upwards for "poking" for undocumented stuff
+        if(deepmode)
+        {
+            //String synthesizedFileName = prefix+(major)+"."+minor+"."+(patch)+suffix;
+            String synthesizedFileName = prefix+(major+1)+"."+0+"."+(0)+suffix;
+            String synthesizedFileNameShort = prefix+(major+1)+"."+0+suffix;
+            peekNext(synthesizedFileName,synthesizedFileNameShort,major+1,0,0,knownVersions,indexUsed);
+
+            synthesizedFileName = prefix+(major)+"."+(minor+1)+"."+(0)+suffix;
+            synthesizedFileNameShort = prefix+(major)+"."+(minor+1)+suffix;
+            peekNext(synthesizedFileName,synthesizedFileNameShort,major,minor+1,0,knownVersions,indexUsed);
+
+            synthesizedFileName = prefix+(major)+"."+minor+"."+(patch+1)+suffix;
+            peekNext(synthesizedFileName,null,major,minor,patch+1,knownVersions,indexUsed);
+        }
+
+        return new int[]{major,minor,patch};
+    }
+
+    private static void scanDownwards(
+            int major,
+            int minor,
+            int patch,
+            String prefix,
+            String suffix,
+            HashMap<String,FirmwareVersion> knownVersions,
+            boolean rchackfix,
+            String hackfixsuffix,
+            String indexUsed,
+            String useForSusVersion
+            ) throws IOException {
+        l.info(major+"--"+minor+"--"+patch);
+        List<FirmwareVersion> temp = new ArrayList<>();
+        l.info(prefix+"."+major+"."+minor+"."+patch+"."+suffix);
+
+        if(major==0) //sus version, FUCK YOU AGAIN SENA, XREF: https://repo.nplusc.de/SenaBitWiggler/AutoXml/commit/f17a35d283871ec9357ae94fe561e8a998993b8f
+        {
+            String lastSuffix = rchackfix?hackfixsuffix:".";
+            String synthesizedFileName = prefix+(major)+"."+minor+lastSuffix+(patch)+suffix;
+            boolean nopeOutVersion = false;
+            var fwVersion = knownVersions.getOrDefault(synthesizedFileName,null);
+            if(fwVersion!=null&&fwVersion.isFiller())
+            {
+                nopeOutVersion=true;
+            }
+            if(!knownVersions.containsKey(synthesizedFileName)||nopeOutVersion)
+            {
+                FirmwareVersion f = getFirmware(major,minor,patch,false,synthesizedFileName,rchackfix,hackfixsuffix,indexUsed);
+                f.setSusVersion(useForSusVersion);
+                knownVersions.put(synthesizedFileName,f);
+            }
+        }
+
+        while(major>=1&&minor>=0&&patch>=0) //older versions won't be bruteforced, check for existence in the index prevents a redownload.
+        {
+            String lastSuffix = rchackfix?hackfixsuffix:".";
+            String synthesizedFileName = prefix+(major)+"."+minor+lastSuffix+(patch)+suffix;
+
+            if(knownVersions.containsKey(synthesizedFileName)) //skipping redownload and setting it as "not hidden" if it was a hidden version
+            {
+                knownVersions.get(synthesizedFileName).setHidden(false);
+            }
+            else
+            {
+                FirmwareVersion f = getFirmware(major,minor,patch,false,synthesizedFileName,rchackfix,hackfixsuffix,indexUsed);
+                knownVersions.put(synthesizedFileName,f);
+            }
+            if(patch==0)
+            {
+                if(!rchackfix)
+                {
+                    synthesizedFileName = prefix+(major)+"."+minor+suffix;
+                }
+                if(knownVersions.containsKey(synthesizedFileName)) //skipping redownload and setting it as "not hidden" if it was a hidden version
+                {
+                    knownVersions.get(synthesizedFileName).setHidden(false);
+                }
+                else
+                {
+                    FirmwareVersion f2 = getFirmware(major,minor,patch,false,synthesizedFileName,rchackfix,hackfixsuffix,indexUsed);
+                    knownVersions.put(synthesizedFileName,f2);
+                }
+                if(rchackfix)
+                {
+                    break; //rc-versions need different fudgery...
+                }
+            }
+            patch--;
+            if(patch<0)
+            {
+                patch=9;
+                minor--;
+            }
+            if(minor<0)
+            {
+                minor=9;
+                major--;
+            }
+        }/**/
+    }
+
+
+    private static FirmwareVersion getFirmware(int major, int minor, int patch, boolean hidden, String fwname,boolean rchackfix,String hackfixsuffix,String indexUsed) throws IOException {
+        FirmwareVersion f = new FirmwareVersion();
+        f.setFilename(fwname);
+        f.setHidden(hidden);
+        f.setMajor(major);
+        f.setMinor(minor);
+        f.setPatch(patch);
+        f.setRc_hackfix(rchackfix);
+        f.setFirmwareLocation(indexUsed);
+        f.setHackfix(hackfixsuffix);
+        File downloadFolderBase = new File(outfolder_base,"downloadstage");
+        if(supprCache.containsKey(fwname)) //leaves a "fake entry" when 2 different deviceIDs would lead to the same filename
+        {
+            l.info("Fakerfuck");
+            FirmwareVersion f2 =  supprCache.get(fwname);
+            f.setFiller(f2.isFiller());
+            f.setServerCreationDate(f2.getServerCreationDate());
+            return f;
+        }
+        supprCache.put(fwname,f); // banning a filename from rescan/redownload
+        //if(true) return f;
+        boolean originalLocationSuccessful = false;
+        if(!DUMMY_MODE)
+        {
+            Utils.runTool(downloadFolderBase,
+                    "wget",
+                    "http://firmware.sena.com/senabluetoothmanager/"+fwname
+            );
+            originalLocationSuccessful = new File(downloadFolderBase,fwname).exists();
+            if(!originalLocationSuccessful)
+            {
+                // new alternative location for additional images used by the WiFi cradle. Checking there if something does not exist at original
+                Utils.runTool(downloadFolderBase,
+                        "wget",
+                        "http://firmware.sena.com/senabluetoothmanager/WiFiCradle/bt_img/"+fwname
+                );
+            }
+        }
+        else
+        {
+            dummydownloadfake.println("http://firmware.sena.com/senabluetoothmanager/"+fwname);
+        }
+        l.info("New Version spotted:"+fwname);
+        File dlf = new File(downloadFolderBase,fwname);
+        File dst = new File(outfolder_base,fwname);
+        if(dlf.exists())
+        {
+            if(dlf.lastModified() <100000) // suspicious undefined date
+            {
+                f.setFiller(true);
+                f.setServerCreationDate(new Date(0));
+            }
+            else
+            {
+                f.setAlternativeLocation(!originalLocationSuccessful);
+                f.setFiller(false);
+                f.setServerCreationDate(new Date(dlf.lastModified()));
+                if(!dst.exists())
+                {
+                    Files.copy(dlf.toPath(),dst.toPath());
+                }
+            }
+        }
+        else
+        {
+            f.setFiller(true);
+            f.setServerCreationDate(new Date(0));
+        }
+        return f;
+    }
+
+    private static void peekNext(
+            String synthesizedFileName,
+            String synthesizedFileNameShort,
+            int major,
+            int minor,
+            int patch,
+            HashMap<String,FirmwareVersion> knownVersions,
+            String indexUsed
+    ) throws IOException {
+        l.info("peekstate:");
+        l.info(knownVersions.containsKey(synthesizedFileName));
+        l.info(knownVersions.containsKey(synthesizedFileNameShort));
+        if(!(knownVersions.containsKey(synthesizedFileName)||knownVersions.containsKey(synthesizedFileNameShort))) // only re-poking if nothing was there yet.
+        {
+            FirmwareVersion nextMajor = getFirmware(major,minor,patch,true,synthesizedFileName,false,".",indexUsed);
+            if(nextMajor.isFiller())
+            {
+                if(synthesizedFileNameShort != null)
+                {
+                    nextMajor = getFirmware(major,minor,patch,true,synthesizedFileNameShort,false,".",indexUsed);
+                    synthesizedFileName = synthesizedFileNameShort;
+                }
+            }
+            l.info("peekstate:"+nextMajor.isFiller());
+            if(!nextMajor.isFiller())
+            {
+                l.info("SUCCESS for:"+synthesizedFileName);
+                knownVersions.put(synthesizedFileName,nextMajor);
+            }
+        }
+    }
+
+}

+ 141 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/FirmwareVersion.java

@@ -0,0 +1,141 @@
+package de.nplusc.izc.senabitwiggler;
+
+import java.util.Date;
+
+public class FirmwareVersion {
+    private Date ServerCreationDate;
+    private String Filename;
+    private int major;
+    private int minor;
+    private int patch;
+    private boolean hidden;
+
+    private boolean rc_hackfix;
+
+    private boolean alternativeLocation;
+
+    private String FirmwareLocation = "main";
+
+    private String hackfix = "";
+
+    private String susVersion = "";
+
+    private boolean IAUploaded = false;
+
+    public String getSusVersion() {
+        return susVersion;
+    }
+
+    public void setSusVersion(String susVersion) {
+        this.susVersion = susVersion;
+    }
+
+    private MatrixState NotificationState = MatrixState.TODO;
+
+    public MatrixState getNotificationState() {
+        return NotificationState;
+    }
+
+    public void setNotificationState(MatrixState notificationState) {
+        NotificationState = notificationState;
+    }
+
+    // signifies that a version is not a valid one and only "inserted" due to the guesser going over it. prevents re-guessing;
+    private boolean filler;
+
+    public boolean isFiller() {
+        return filler;
+    }
+
+    public void setFiller(boolean filler) {
+        this.filler = filler;
+    }
+
+    public Date getServerCreationDate() {
+        return ServerCreationDate;
+    }
+
+    public void setServerCreationDate(Date serverCreationDate) {
+        ServerCreationDate = serverCreationDate;
+    }
+
+    public String getFilename() {
+        return Filename;
+    }
+
+    public void setFilename(String filename) {
+        Filename = filename;
+    }
+
+    public int getMajor() {
+        return major;
+    }
+
+    public void setMajor(int major) {
+        this.major = major;
+    }
+
+    public int getMinor() {
+        return minor;
+    }
+
+    public void setMinor(int minor) {
+        this.minor = minor;
+    }
+
+    public int getPatch() {
+        return patch;
+    }
+
+    public void setPatch(int patch) {
+        this.patch = patch;
+    }
+
+    public boolean isHidden() {
+        return hidden;
+    }
+
+    public void setHidden(boolean hidden) {
+        this.hidden = hidden;
+    }
+
+    public String getHackfix() {
+        return hackfix;
+    }
+
+    public void setHackfix(String hackfix) {
+        this.hackfix = hackfix;
+    }
+
+    public boolean isRc_hackfix() {
+        return rc_hackfix;
+    }
+
+    public void setRc_hackfix(boolean rc_hackfix) {
+        this.rc_hackfix = rc_hackfix;
+    }
+
+    public boolean isAlternativeLocation() {
+        return alternativeLocation;
+    }
+
+    public void setAlternativeLocation(boolean alternativeLocation) {
+        this.alternativeLocation = alternativeLocation;
+    }
+
+    public String getFirmwareLocation() {
+        return FirmwareLocation;
+    }
+
+    public void setFirmwareLocation(String firmwareLocation) {
+        FirmwareLocation = firmwareLocation;
+    }
+
+    public boolean isIAUploaded() {
+        return IAUploaded;
+    }
+
+    public void setIAUploaded(boolean IAUploaded) {
+        this.IAUploaded = IAUploaded;
+    }
+}

+ 5 - 1
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/FirmwareWrapperExtraction.java

@@ -2,6 +2,8 @@ package de.nplusc.izc.senabitwiggler;
 
 import com.google.common.base.Charsets;
 import com.google.common.primitives.Longs;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.yaml.snakeyaml.Yaml;
 
 import java.io.*;
@@ -9,6 +11,7 @@ import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 
 public class FirmwareWrapperExtraction {
+    private static final Logger l = LogManager.getLogger();
     public static void assembleFirmware(File output, String inputfolder)
     {
         Yaml y = new Yaml();
@@ -116,10 +119,11 @@ public class FirmwareWrapperExtraction {
             f.read(magic);
 
             hdr.setMagicShit(Longs.fromBytes(filler,filler,filler,filler,magic[3],magic[2],magic[1],magic[0]));
+            // magic[] = {0x19,0x28,0xc5,0xe6}
 
             byte[] unknown_id = new byte[4];
 
-            f.read(unknown_id);
+            f.read(unknown_id); //product id
 
             hdr.setRandom_id(Longs.fromBytes(filler,filler,filler,filler,unknown_id[3],unknown_id[2],unknown_id[1],unknown_id[0]));
 

+ 287 - 10
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/FlashFSUnWiggler.java

@@ -2,13 +2,19 @@ package de.nplusc.izc.senabitwiggler;
 
 import com.google.common.primitives.Ints;
 import com.google.common.primitives.Shorts;
+import de.nplusc.izc.senabitwiggler.DataStructures.QualCommHeaderRecord;
+import de.nplusc.izc.senabitwiggler.DataStructures.QualCommWrapper;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.yaml.snakeyaml.Yaml;
 
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.RandomAccessFile;
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
 
 public class FlashFSUnWiggler {
+    private static final Logger l = LogManager.getLogger();
     private static class FileMetadata
     {
         private int offset;
@@ -29,8 +35,8 @@ public class FlashFSUnWiggler {
             if(sizeFile>f.length())
             {
 
-                System.out.println(sizeFile);
-                System.err.println("ZOINKS!!!, mismatch");
+                l.info(sizeFile);
+                l.info("ZOINKS!!!, mismatch");
                 return;
             }
             f.read(javaisDipshit);
@@ -42,13 +48,13 @@ public class FlashFSUnWiggler {
                 f.read(javaisDipshit);
                 int sizeAndFlags = Ints.fromBytes(javaisDipshit[3],javaisDipshit[2],javaisDipshit[1],javaisDipshit[0]);
                 int size = sizeAndFlags&0x00FFFFFF;
-                System.out.println(sizeAndFlags);
-                System.out.println(size);
+                l.info(sizeAndFlags);
+                l.info(size);
 
                 fmd.offset_fname=size;
                 if((sizeAndFlags&0xFF000000)<0)
                 {
-                    System.out.println("dir");
+                    l.info("dir");
                     fmd.is_dir=true;
                 }
                 f.read(javaisDipshit);
@@ -88,7 +94,7 @@ public class FlashFSUnWiggler {
                 else
                 {
 
-                    System.out.println("Reading:"+fmd.parentpath+fmd.filename+"("+fmd.length+")@"+fmd.offset);
+                    l.info("Reading:"+fmd.parentpath+fmd.filename+"("+fmd.length+")@"+fmd.offset);
                     byte[] filecontent = new byte[fmd.length];
                     if(fmd.length>0)
                     {
@@ -107,4 +113,275 @@ public class FlashFSUnWiggler {
         }
 
     }
+
+    public static void unpackCSRFS(File firmware, File outfolder)
+    {
+        try (RandomAccessFile f = new RandomAccessFile(firmware,"r")) {
+            int filler = -1;
+            byte[] fillershort = new byte[]{(byte)0xff,(byte)0xff};
+            RandomAccessFile boobs = new RandomAccessFile(new File(outfolder,"debug.dat"),"rw");
+
+            byte[] javaisDipshit = new byte[4];
+            byte[] javaShorty = new byte[2];
+            int magic = f.readInt(); //ignored
+
+
+            f.read(javaisDipshit);
+            boobs.write(filler);
+            int sizeFile = Ints.fromBytes(javaisDipshit[0],javaisDipshit[1],javaisDipshit[2],javaisDipshit[3]);
+            //old shit calculates in words and not in bytes on sizes
+            if((sizeFile*2)>f.length())
+            {
+
+                l.info(sizeFile);
+                l.info("ZOINKS!!!, mismatch");
+                return;
+            }
+            byte[] background = new byte[(int)f.length()];
+            for(int i=0;i<background.length;i++)
+            {
+                background[i]=0;
+            }
+            boobs.seek(0);
+            boobs.write(background);
+            boobs.seek(0);
+            boobs.write(filler);
+            boobs.write(filler);
+
+
+
+            f.read(javaisDipshit);
+            int countFileRecords = (Ints.fromBytes(javaisDipshit[2],javaisDipshit[3],javaisDipshit[0],javaisDipshit[1]) &0x00FFFFFF);
+            l.info(countFileRecords);
+            int countFileRecordsXXX = (Ints.fromBytes(javaisDipshit[1],javaisDipshit[0],javaisDipshit[3],javaisDipshit[2])&0x00FFFFFF);
+            l.info(countFileRecordsXXX);
+            boobs.write(fillershort);
+            boobs.seek(10);
+            f.seek(10);
+            byte[] fakeFileRecord = new byte[12];
+            for(int i=0;i<12;i++)
+            {
+                fakeFileRecord[i]=(byte)0xee;
+            }
+            FileMetadata[] files = new FileMetadata[countFileRecords];
+            for(int i=0;i<countFileRecords;i++)
+            {
+                FileMetadata fmd = new FileMetadata();
+                f.read(javaisDipshit);
+                int sizeAndFlags = Ints.fromBytes(javaisDipshit[0],javaisDipshit[1],javaisDipshit[2],javaisDipshit[3]);
+                int size = sizeAndFlags&0x00FFFFFF;
+                l.info("SZFlg>>"+sizeAndFlags);
+                l.info("SZExtr>>"+size);
+
+                fmd.offset_fname=size;
+                if((sizeAndFlags&0xFF000000)<0)
+                {
+                    l.info("dir");
+                    fmd.is_dir=true;
+                }
+                f.read(javaisDipshit);
+                fmd.offset=Ints.fromBytes(javaisDipshit[0],javaisDipshit[1],javaisDipshit[2],javaisDipshit[3]);
+                f.read(javaisDipshit);
+                fmd.length=Ints.fromBytes(javaisDipshit[0],javaisDipshit[1],javaisDipshit[2],javaisDipshit[3]);
+                files[i]=fmd;
+                boobs.write(fakeFileRecord);
+            }
+            for(int i=0;i<countFileRecords;i++)
+            {
+                FileMetadata fmd = files[i];
+                if(fmd.offset_fname==0)
+                {
+                    fmd.filename="";
+                    fmd.parentpath="";
+                }
+                else
+                {
+                    f.seek(fmd.offset_fname*2); //words again...
+                    f.read(javaShorty);
+                    short fnlength = Shorts.fromBytes(javaShorty[0],javaShorty[1]);
+                    byte[] fname = new byte[fnlength*2];
+                    f.read(fname);
+                    byte[] fname_real = new byte[fnlength];
+                    for(int fi=0;fi<fname_real.length;fi++)
+                    {
+                        fname_real[fi]=fname[fi*2+1]; //zapping each upper bit...
+                    }
+                    for(int j=0;j<fname.length;j++)
+                    {
+                        fname[j]=(byte) 0xCC;
+                    }
+                    boobs.seek(fmd.offset_fname*2); //words again...
+                    boobs.write(new byte[]{(byte)0xDD,(byte)0xDD});
+                    boobs.write(fname);
+                    String s = File.separator+new String(fname_real);
+                    fmd.filename=s;
+                }
+                if(fmd.is_dir)
+                {
+                    new File(outfolder+fmd.parentpath+fmd.filename).mkdirs();
+
+                    for(int j= 0;j< fmd.length;j++)
+                    {
+                        int subfiles = fmd.offset+j-1;
+                        if(subfiles==-1)
+                        {
+                            l.info("WTF?");
+                        }
+                        files[subfiles].parentpath=fmd.parentpath+fmd.filename;
+                    }
+                }
+                else
+                {
+
+                    l.info("Reading:"+fmd.parentpath+fmd.filename+"("+fmd.length+")@"+fmd.offset);
+                    byte[] filecontent = new byte[fmd.length];
+                    if(fmd.length>0)
+                    {
+                        f.seek(fmd.offset*2);
+                        int readme = f.read(filecontent);
+                        RandomAccessFile out = new RandomAccessFile(outfolder+fmd.parentpath+fmd.filename,"rw");
+                        out.write(filecontent);
+                        if(readme<filecontent.length)
+                        {
+                            throw new IndexOutOfBoundsException("ZARF");
+                        }
+                        for(int k=0;k<filecontent.length;k++)
+                        {
+                            filecontent[k]=(byte)0xBB;
+                        }
+                        boobs.seek(fmd.offset*2);
+                        boobs.write(filecontent);
+                    }
+                }
+            }
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+
+
+
+    public static void unpackQCC512DFU(File firmware, File outfolder)
+    {
+        QualCommWrapper w = new QualCommWrapper();
+        l.info("0x00!");
+        try (RandomAccessFile f = new RandomAccessFile(firmware,"r"))
+        {
+            outfolder.mkdirs();
+            f.read(new byte[8]); //skip header
+            int hdrsize = f.readInt();
+            byte[] header = new byte[hdrsize];
+            f.read(header);
+            w.header=header;
+            // 1346458196
+            // 1145132097
+            int i = 0;
+            List<QualCommHeaderRecord> files = new ArrayList<>();
+            while(true)
+            {
+                QualCommHeaderRecord r = new QualCommHeaderRecord();
+                if(f.readInt() != 1346458196)
+                {
+                    l.info("Zarf!");
+                    break; //end of file
+                }
+                if(f.readInt() != 1145132097)
+                {
+                    l.info("Zarf2!");
+                    break; //end of file
+                }
+                int sizeData = f.readInt();
+                r.size = sizeData;
+                l.info("Reading" +sizeData);
+                short location = f.readShort();
+                short sublocation = f.readShort();
+                r.location=location;
+                r.sublocation=sublocation;
+                String filename = location+"_"+sublocation+".dat";
+                r.filename=filename;
+                byte[] innerFile = new byte[sizeData-4];
+
+                f.read(innerFile);
+                RandomAccessFile fo = new RandomAccessFile(new File(outfolder,filename),"rw");
+                fo.write(innerFile);
+                fo.close();
+                i++;
+                files.add(r);
+            }
+            int bytesLeft = 4+((int)(f.length()-f.getFilePointer()));
+            byte[] rest = new byte[bytesLeft];
+            f.seek(f.getFilePointer()-4);
+             f.read(rest);
+             w.footer=rest;
+
+            w.files = files.toArray(new QualCommHeaderRecord[files.size()]);
+            Yaml y = new Yaml();
+
+            y.dump(w, new FileWriter(new File(outfolder,"header.yml")));
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void repackQualcommWrapper(File newfirmware, File inputfolder)
+    {
+        QualCommWrapper header;
+        try {
+             header = new Yaml().loadAs(new FileReader(new File(inputfolder,File.separator+"header.yml")),QualCommWrapper.class);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+            return;
+        }
+        l.info("0x00!");
+
+        if(newfirmware.exists())
+        {
+            l.error("Refusing to overwrite a existing file!!!");
+            return;
+        }
+
+        try (RandomAccessFile f = new RandomAccessFile(newfirmware,"rw"))
+        {
+            f.writeInt(0x41505055);
+            f.writeInt(0x48445232);
+            f.writeInt(header.header.length);
+            f.write(header.header);
+
+            // 1346458196
+            // 1145132097
+
+            for(QualCommHeaderRecord r:header.files)
+            {
+                RandomAccessFile f2 = new RandomAccessFile(new File(inputfolder,r.filename),"r");
+                int size = (int) f2.length();
+                byte[] file = new byte[size];
+                f2.read(file);
+                f.writeInt(1346458196);
+                f.writeInt(1145132097);
+                f.writeInt(size+4);
+                f.writeShort(r.location);
+                f.writeShort(r.sublocation);
+                f.write(file);
+                f2.close();
+            }
+            f.write(header.footer);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+
+
+
+
+
 }

+ 11 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/Jailbreaker.java

@@ -1,10 +1,14 @@
 package de.nplusc.izc.senabitwiggler;
 
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
 import java.io.File;
 import java.io.IOException;
 
 public class Jailbreaker {
 
+    private static final Logger l = LogManager.getLogger();
     private static String nvscmd = EntryPoint.BlueLabPath+"nvscmd";
     private static String pscli = EntryPoint.BlueLabPath+"pscli";
 
@@ -48,10 +52,17 @@ public class Jailbreaker {
         try {
             Utils.runTool(scratch,dfuunbuild,"-v","-f",dfuinput,"-o","extracted");
             Utils.runTool(scratch,dfusign,"-v", "-o","extracted0000signed.fs","-h","extracted0000.fs", "-ka",EntryPoint.APPDIR+File.separator+"jailbreak"+File.separator+"jailbreak.private.key");
+            Utils.runTool(scratch,dfusign,"-v", "-o","extracted0000signed.psr","-pa","extracted0000.psr", "-ka",EntryPoint.APPDIR+File.separator+"jailbreak"+File.separator+"jailbreak.private.key");
             File oldfs = new File(scratch,"extracted0000.fs");
             oldfs.delete();
             File newfs = new File(scratch,"extracted0000signed.fs");
             newfs.renameTo(oldfs);
+
+            oldfs = new File(scratch,"extracted0000.psr");
+            oldfs.delete();
+            newfs = new File(scratch,"extracted0000signed.psr.app.psr");
+            newfs.renameTo(oldfs);
+
             Utils.runTool(scratch,dfubuild,"-c","extracted.cl","-f",dfuout);
         } catch (IOException e) {
             e.printStackTrace();

+ 20 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/MatrixState.java

@@ -0,0 +1,20 @@
+package de.nplusc.izc.senabitwiggler;
+
+public enum MatrixState {
+    /**
+     * used for guessed versions. Version will be renotified if its released
+     */
+    SENT_PRELIM,
+    /**
+     * released version, notified on matrix
+     */
+    SENT,
+    /**
+     * used for fake versions.
+     */
+    SKIPPED,
+    /**
+     * Not yet published
+     */
+    TODO
+}

+ 26 - 36
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/PromptHandlerSuite.java

@@ -1,5 +1,7 @@
 package de.nplusc.izc.senabitwiggler;
 
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.yaml.snakeyaml.Yaml;
 
 import javax.sound.midi.Patch;
@@ -15,27 +17,21 @@ import java.util.*;
 import static de.nplusc.izc.senabitwiggler.Utils.runTool;
 
 public class PromptHandlerSuite {
+
+    private static final Logger l = LogManager.getLogger();
     public static void handlePrompts(File firmware, File outfolder, String headsetid,boolean deep) throws InputInvalidException {
-        URL rsrc = EntryPoint.class.getResource("/PromptConfigs/"+headsetid+".prompts.yml");
-        if(rsrc==null)
+        String devicefile = EntryPoint.APPDIR+File.separator+"devices"+File.separator+headsetid+".device.yml";
+        if(!(new File(devicefile).exists()))
         {
-            URL url = EntryPoint.class.getResource("/PromptConfigs/");
-            // HAXX
-            EntryPoint.class.getResourceAsStream("/PromptConfigs/");
-            Path path = null;
+            File f =  new File(EntryPoint.APPDIR+File.separator+"devices");
+            l.error("Invalid Headset reference: Valid values are");
             try {
-                path = Paths.get(url.toURI());
-            } catch (URISyntaxException e) {
-                e.printStackTrace();
-            }
-            System.out.println("Invalid Headset reference: Valid values are");
-            try {
-                Files.walk(path, 1).forEach(p ->
+                Files.walk(f.toPath(), 1).forEach(p ->
                 {
                     String fn = p.getFileName().toString();
-                    if(fn.endsWith(".prompts.yml"))
+                    if(fn.endsWith(".device.yml"))
                     {
-                        System.out.println(fn.replace(".prompts.yml",""));
+                        l.error(fn.replace(".device.yml",""));
                     }
                 });
             } catch (IOException e) {
@@ -63,8 +59,8 @@ public class PromptHandlerSuite {
 
 
 
-        try (InputStream in = EntryPoint.class.getResourceAsStream("/PromptConfigs/"+headsetid+".prompts.yml");
-            BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
+        try (BufferedReader reader = new BufferedReader(new FileReader(devicefile)))
+        {
             HashMap<String,String> config = (HashMap<String, String>) new Yaml().load(reader);
             String file = config.get("file");
             File xuvin = new File(SenaUnwrap,file);
@@ -114,7 +110,7 @@ public class PromptHandlerSuite {
                         throw new InputInvalidException();
                 }
                 List<String> cmd = new ArrayList<>();
-                cmd.add("sox");
+                cmd.add(EntryPoint.SoxPath);
                 cmd.addAll(soxIn);
                 cmd.add(f.getPath());
                 cmd.add("-e");
@@ -137,24 +133,18 @@ public class PromptHandlerSuite {
 
     public static void assembleWithNewPrompts(File firmware, File outfolder, String headsetid) throws InputInvalidException {
         {
-            URL rsrc = EntryPoint.class.getResource("/PromptConfigs/" + headsetid + ".prompts.yml");
-            if (rsrc == null) {
-                URL url = EntryPoint.class.getResource("/PromptConfigs/");
-                // HAXX
-                EntryPoint.class.getResourceAsStream("/PromptConfigs/");
-                Path path = null;
-                try {
-                    path = Paths.get(url.toURI());
-                } catch (URISyntaxException e) {
-                    e.printStackTrace();
-                }
-                System.out.println("Invalid Headset reference: Valid values are");
+            String devicefile = EntryPoint.APPDIR+File.separator+"devices"+File.separator+headsetid+".device.yml";
+            if(!(new File(devicefile).exists()))
+            {
+                File f =  new File(EntryPoint.APPDIR+File.separator+"devices");
+                l.error("Invalid Headset reference: Valid values are");
                 try {
-                    Files.walk(path, 1).forEach(p ->
+                    Files.walk(f.toPath(), 1).forEach(p ->
                     {
                         String fn = p.getFileName().toString();
-                        if (fn.endsWith(".prompts.yml")) {
-                            System.out.println(fn.replace(".prompts.yml", ""));
+                        if(fn.endsWith(".device.yml"))
+                        {
+                            l.error(fn.replace(".device.yml",""));
                         }
                     });
                 } catch (IOException e) {
@@ -179,8 +169,8 @@ public class PromptHandlerSuite {
 
 
 
-            try (InputStream in = EntryPoint.class.getResourceAsStream("/PromptConfigs/"+headsetid+".prompts.yml");
-                BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
+            try (
+                BufferedReader reader = new BufferedReader(new FileReader(devicefile))) {
                 HashMap<String,String> config = (HashMap<String, String>) new Yaml().load(reader);
                 String file = config.get("file");
                 File xuvin = new File(SenaUnwrap,file);
@@ -210,7 +200,7 @@ public class PromptHandlerSuite {
                             throw new InputInvalidException();
                     }
                     List<String> cmd = new ArrayList<>();
-                    cmd.add("sox");
+                    cmd.add(EntryPoint.SoxPath);
                     cmd.add(new File(prompts,fn+".wav").getPath());
                     cmd.addAll(soxIn);
                     cmd.add(f.getPath());

+ 37 - 0
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/Statefile.java

@@ -0,0 +1,37 @@
+package de.nplusc.izc.senabitwiggler;
+
+import java.util.HashMap;
+import java.util.Set;
+
+public class Statefile {
+
+    private HashMap<String, Firmware> firmwares;
+
+    public HashMap<String, Firmware> getFirmwares() {
+        return firmwares;
+    }
+
+    public void setFirmwares(HashMap<String, Firmware> firmwares) {
+        this.firmwares = firmwares;
+    }
+
+    private String generalRoomId;
+
+    private String otherRoomId;
+
+    public String getGeneralRoomId() {
+        return generalRoomId;
+    }
+
+    public void setGeneralRoomId(String generalRoomId) {
+        this.generalRoomId = generalRoomId;
+    }
+
+    public String getOtherRoomId() {
+        return otherRoomId;
+    }
+
+    public void setOtherRoomId(String otherRoomId) {
+        this.otherRoomId = otherRoomId;
+    }
+}

+ 4 - 1
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/Utils.java

@@ -1,6 +1,8 @@
 package de.nplusc.izc.senabitwiggler;
 
 import com.google.common.primitives.Longs;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 
 import javax.swing.*;
 import java.io.File;
@@ -10,6 +12,7 @@ import java.util.Arrays;
 import java.util.Locale;
 
 public class Utils {
+    private static final Logger l = LogManager.getLogger();
     public static byte[] LongToRawBytes(long l)
     {
         byte[] tmp = Longs.toByteArray(l);
@@ -37,7 +40,7 @@ public class Utils {
         {
             if(!od.mkdirs())
             {
-                System.err.println("WTF! somethint ate shit");
+                l.error("WTF! somethint ate shit");
                 return;
             }
         }

+ 7 - 4
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/VmAppFIleExtraction.java

@@ -3,11 +3,14 @@ package de.nplusc.izc.senabitwiggler;
 import com.google.common.primitives.Ints;
 import com.google.common.primitives.Longs;
 import com.google.common.primitives.Shorts;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.yaml.snakeyaml.Yaml;
 
 import java.io.*;
 
 public class VmAppFIleExtraction {
+    private static final Logger l = LogManager.getLogger();
     public static void extractVmImage(File input, String output)
     {
         byte filler = 0x00;
@@ -17,7 +20,7 @@ public class VmAppFIleExtraction {
             long len = f.length()/2;
             if(len>Integer.MAX_VALUE)
             {
-                System.out.println("Ugggh, File too big");
+                l.error("Ugggh, File too big");
                 return;
             }
 
@@ -29,7 +32,7 @@ public class VmAppFIleExtraction {
             }
             if(Utils.xorsum(checksumarray)!=0)
             {
-                System.err.println("Smells like Dead Beef, the data seems to be corrupt");
+                l.error("Smells like Dead Beef, the data seems to be corrupt");
                 System.exit(1);
             }
             f.seek(0);
@@ -116,7 +119,7 @@ public class VmAppFIleExtraction {
             long len = f.length()/2;
             if(len>Integer.MAX_VALUE)
             {
-                System.out.println("Ugggh, File too big");
+                System.out.pri ntln("Ugggh, File too big");
                 return;
             }
 
@@ -128,7 +131,7 @@ public class VmAppFIleExtraction {
             }
             if(Utils.xorsum(checksumarray)!=0)
             {
-                System.err.println("Smells like Dead Beef, the data seems to be corrupt");
+                System.err.prin tln("Smells like Dead Beef, the data seems to be corrupt");
                 System.exit(1);
             }
             f.seek(0);

+ 18 - 16
SenaBitWiggler/src/main/java/de/nplusc/izc/senabitwiggler/XAPDisAsm.java

@@ -2,6 +2,8 @@ package de.nplusc.izc.senabitwiggler;
 
 import com.google.common.primitives.Ints;
 import com.google.common.primitives.Shorts;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 
 import java.io.*;
 import java.util.ArrayList;
@@ -14,7 +16,7 @@ interface OpCodeMangler
 }
 
 public class XAPDisAsm {
-
+    private static final Logger l = LogManager.getLogger();
     private static HashMap<String,String> labels = new HashMap<>();
 
     private static OpCodeMangler brxl = (modifier,opcode,address)->{
@@ -33,7 +35,7 @@ public class XAPDisAsm {
             badOpCode += (Utils.bytesToHex(Shorts.toByteArray(opcode[i])));
         }
         String invalidCode = OpcodeAddressRangeToString(address,opcode.length+(modified?1:0))+":Invalid OpCode: "+badOpCode;
-        System.err.println(invalidCode);
+        l.info(invalidCode);
         return invalidCode;
     };
     public static OpCodeMangler[] manglers = new OpCodeMangler[256];
@@ -51,12 +53,12 @@ public class XAPDisAsm {
                 for(int i=0;i<opcode.length;i++)
                 {
                     byte[] opcodeWord = Shorts.toByteArray(opcode[i]);
-                    if(EntryPoint.verbose)System.out.println(opcodeWord[0]);
+                    l.trace(opcodeWord[0]);
                     opcodeValues[i]=opcodeWord[0];
                     opcodeReal=(opcodeWord[1]); //stompy stomp, only keeps the last
                 }
                 String rawValue = Utils.bytesToHex(opcodeValues);
-                if(EntryPoint.verbose)System.out.println(rawValue);
+                l.trace(rawValue);
 
                 int valueUnsigned = XAPDisAsmGeneratedCode.unsignedCounts.get(rawValue);
                 int valueSigned =XAPDisAsmGeneratedCode.signedCounts.get(rawValue);
@@ -158,7 +160,7 @@ public class XAPDisAsm {
                     opcodeReal=(opcodeWord[1]); //stompy stomp, only keeps the last
                 }
                 String rawVal = Utils.bytesToHex(opcodeValues);
-                if(EntryPoint.verbose)System.out.println(rawVal);
+                l.trace(rawVal);
                 int valueUnsigned = XAPDisAsmGeneratedCode.unsignedCounts.get(rawVal);
                 int valueSigned =XAPDisAsmGeneratedCode.signedCounts.get(Utils.bytesToHex(opcodeValues));
                 String register = "";
@@ -834,15 +836,15 @@ public class XAPDisAsm {
     private static int untwiddleOpcodeParamBra(byte[] opcode,int opcodelocation)
     {
         int out = opcode[0];
-        if(EntryPoint.verbose)System.out.println(out);
-        if(EntryPoint.verbose)System.out.println(String.format("0x%08X", out));
+        l.trace(out);
+        l.trace(String.format("0x%08X", out));
         for(int i=1;i<opcode.length;i++)
         {
             out=out<<8;
             out+=opcode[i];
-            if(EntryPoint.verbose)System.out.println(out);
-            if(EntryPoint.verbose)System.out.println(opcode[i]);
-            if(EntryPoint.verbose)System.out.println(String.format("0x%08X", out));
+            l.trace(out);
+            l.trace(opcode[i]);
+            l.trace(String.format("0x%08X", out));
         }
         out=out+opcodelocation;
         out = out &0x00FFFFFF;
@@ -939,9 +941,9 @@ public class XAPDisAsm {
             for(int i=0;i<assemblyLength;i++)
             {
                 Short word = f.readShort();
-                if(EntryPoint.verbose)System.out.println("READ:"+ (word&0xff));
-                if(EntryPoint.verbose)System.out.println(addressToString(i));
-                if(EntryPoint.verbose)System.out.println(addressToString(baseAddressLastOpcode));
+                l.trace("READ:"+ (word&0xff));
+                l.trace(addressToString(i));
+                l.trace(addressToString(baseAddressLastOpcode));
                 opcodeHoldingBay.add(word);
                 if(word==(short)0xfe09) //specialcasing one specific opcode
                 {
@@ -972,13 +974,13 @@ public class XAPDisAsm {
                                 opcode[j]=opcodeHoldingBay.get(j);
                             }
                         }
-                        if(EntryPoint.verbose)System.out.println("Mangling Opcode with length"+opcode.length);
+                        l.trace("Mangling Opcode with length"+opcode.length);
                         try{
                             disassembled.println(manglers[word&0xff].mangleOpCode(modifier,opcode,baseAddressLastOpcode));
                         }
                         catch(Exception e)
                         {
-                            System.err.println(invalid.mangleOpCode(modifier,opcode,baseAddressLastOpcode));
+                            l.info(invalid.mangleOpCode(modifier,opcode,baseAddressLastOpcode));
                             disassembled.println(invalid.mangleOpCode(modifier,opcode,baseAddressLastOpcode));
                             //System.exit(-1);
                         }
@@ -995,7 +997,7 @@ public class XAPDisAsm {
                         opcodeHoldingBay.clear();
                         baseAddressLastOpcode++;
                     }
-                    if(EntryPoint.verbose)System.out.println("VALUE");
+                    l.trace("VALUE");
                     //opcodeHoldingBay.add(word);
                 }
 

+ 0 - 3
SenaBitWiggler/src/main/resources/PromptConfigs/SRL2.prompts.yml

@@ -1,3 +0,0 @@
-ALL: "PCM"
-file: "vp.bin"
-maincpu: "SRL2_M0.img"

+ 2 - 2
SenaBitWiggler/src/main/resources/log4j2.xml

@@ -10,7 +10,7 @@
         </Console>
         
         
-        <RollingFile name="logfile" fileName="izpl.log" filePattern="izpl-%i.log">
+        <RollingFile name="logfile" fileName="senabitwiggler.log" filePattern="senabitwiggler-%i.log">
         <Policies>
             <OnStartupTriggeringPolicy />
             </Policies>
@@ -18,7 +18,7 @@
             <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %l - %msg%n"/>
         </RollingFile>   
 
-        <RollingFile name="logfileExternal" fileName="izpl.log" filePattern="izpl-%i.log">
+        <RollingFile name="logfileExternal" fileName="senabitwiggler.log" filePattern="senabitwiggler-%i.log">
         <Policies>
             <OnStartupTriggeringPolicy />
             </Policies>

+ 9 - 9
TWPUtil/build.gradle

@@ -1,6 +1,6 @@
 defaultTasks 'distZip'
 
-apply plugin: 'java'
+apply plugin: 'java-library'
 apply plugin: 'application'
 
 
@@ -24,15 +24,15 @@ repositories{
 
 
 dependencies{
-	compile fileTree(dir: 'lib', include: '*.jar')
-	compile "commons-io:commons-io:2.+"
-	compile 'org.apache.commons:commons-exec:1.3'
-	compile "org.yaml:snakeyaml:1.14"
-    compile	'org.xerial:sqlite-jdbc:3.8.7'
-	compile 'mysql:mysql-connector-java:5.1.6'
+	api fileTree(dir: 'lib', include: '*.jar')
+	api "commons-io:commons-io:2.+"
+	api 'org.apache.commons:commons-exec:1.3'
+	api "org.yaml:snakeyaml:1.14"
+    api	'org.xerial:sqlite-jdbc:3.8.7'
+	api 'mysql:mysql-connector-java:5.1.6'
 	
-	compile 'org.im4java:im4java:1.4.0'
-	compile(project(':ToolKit')) {
+	api 'org.im4java:im4java:1.4.0'
+	api(project(':ToolKit')) {
         transitive = false
     }
 

+ 17 - 17
ToolKit/build.gradle

@@ -1,6 +1,6 @@
 defaultTasks 'distZip'
 
-apply plugin: 'java'
+apply plugin: 'java-library'
 
 sourceCompatibility = 1.8
 version = 'SNAPSHOT'
@@ -17,21 +17,21 @@ distZip.outputs.file file(tasks.jar.archivePath)
 
 dependencies{
 	
-	compile fileTree(dir: 'lib', include: '*.jar')
-	//compile "net.rubygrapefruit:native-platform:0.10"
-	compile "commons-io:commons-io:2.+"
-	compile 'org.apache.commons:commons-exec:1.3'
-	compile "org.yaml:snakeyaml:1.14"
-	compile "commons-net:commons-net:3.3"
-	compile 'org.ini4j:ini4j:0.5.2'
-	compile 'org.im4java:im4java:1.4.0'
-    compile 'net.java.dev.jna:jna:4.1.0'
-    compile 'net.java.dev.jna:jna-platform:4.1.0'
-	//compile 'uk.co.caprica:vlcj:3.0.1' //HACK! bezüglich JNA
-    compile	'org.xerial:sqlite-jdbc:3.8.7'
-    compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+'
-	compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+'
-	compile group: 'org.apache.logging.log4j', name: 'log4j-iostreams', version: '2.+'
-	compile 'mysql:mysql-connector-java:5.1.6'
+	api fileTree(dir: 'lib', include: '*.jar')
+	//api "net.rubygrapefruit:native-platform:0.10"
+	api "commons-io:commons-io:2.+"
+	api 'org.apache.commons:commons-exec:1.3'
+	api "org.yaml:snakeyaml:1.14"
+	api "commons-net:commons-net:3.3"
+	api 'org.ini4j:ini4j:0.5.2'
+	api 'org.im4java:im4java:1.4.0'
+    api 'net.java.dev.jna:jna:4.1.0'
+    api 'net.java.dev.jna:jna-platform:4.1.0'
+	//api 'uk.co.caprica:vlcj:3.0.1' //HACK! bezüglich JNA
+    api	'org.xerial:sqlite-jdbc:3.8.7'
+    api group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-iostreams', version: '2.+'
+	api 'mysql:mysql-connector-java:5.1.6'
 
 }

+ 19 - 0
ToolKit/src/main/java/de/nplusc/izc/tools/baseTools/Detectors.java

@@ -115,6 +115,25 @@ public class Detectors
         // return ret;
 
     }
+
+    /**
+     * Detects if SteamOS. returns false on other OSes
+     * @return True if SteamOS got detected
+     */
+    public static boolean detectIsSteamOS()
+    {
+        boolean ret = false;
+        if(!getSystemClassification()[0].equals("linux"))
+        {
+            return false;
+        }
+        try {
+            String osrelease = FileTK.fileAsString("/etc/os-release");
+            return osrelease.split("\n")[0].contains("SteamOS");
+        } catch (IOException e) {
+            return false;
+        }
+    }
     
     
     /**

+ 487 - 687
ToolKit/src/main/java/de/nplusc/izc/tools/baseTools/Tools.java

@@ -19,17 +19,14 @@ package de.nplusc.izc.tools.baseTools;
 
 import de.nplusc.izc.tools.IOtools.FileTK;
 import de.nplusc.izc.tools.IOtools.PrintStreamCapturer;
+
 import java.awt.Dimension;
 import java.awt.GraphicsEnvironment;
 import java.io.*;
 import java.lang.reflect.Field;
 import java.security.MessageDigest;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 import java.util.Map.Entry;
-import java.util.Objects;
-import java.util.Scanner;
 import java.util.prefs.Preferences;
 import javax.swing.*;
 //import net.rubygrapefruit.platform.Native;
@@ -42,120 +39,122 @@ import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
 /**
- *
  * @author LH
  */
- @SuppressWarnings( "deprecation" )
-public class Tools
-{
+@SuppressWarnings("deprecation")
+public class Tools {
     private static final Logger l = LogManager.getLogger();
     public static boolean execCrashed = false;
     private static boolean ContState;
     private static JDialog d;
-    private static boolean hl=false;
+    private static boolean hl = false;
     //private boolean ProcessReturn;
     private static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
     private static int logNumber;
 
-    protected Tools()
-    {
+    protected Tools() {
         //disabled Constructor
     }
-    static
-    {
-        GraphicsEnvironment ge = 
-        GraphicsEnvironment.getLocalGraphicsEnvironment(); 
+
+    static {
+        GraphicsEnvironment ge =
+                GraphicsEnvironment.getLocalGraphicsEnvironment();
         boolean hl = ge.isHeadless();
-        if(!hl){
-          //d   = new JDialog();
+        if (!hl) {
+            //d   = new JDialog();
         }
-        
+
     }
-    
+
     /**
      * Method to pad the left of a Sting with given character
-     * @param count Destination amount of data
-     * @param base String to pad up
+     *
+     * @param count  Destination amount of data
+     * @param base   String to pad up
      * @param filler Padding data
      * @return Padded String
      */
-    public static String padLeft(final int count, final String base, final char filler)
-    {
-        if (base == null)
-        {
+    public static String padLeft(final int count, final String base, final char filler) {
+        if (base == null) {
             throw new NullPointerException();
         }
-        if (base.length() >= count)
-        {
+        if (base.length() >= count) {
             return base;
         }
         char[] prefix = new char[count - base.length()];
         Arrays.fill(prefix, filler);
         return new StringBuilder(count).append(prefix).append(base).toString();
     }
-    
-    
+
+
     /**
      * Method rename and shorthand for Thread.sleep()
+     *
      * @param time Time to wait in ms
      */
-    public static void wait(int time)
-    {
+    public static void wait(int time) {
 
-        try
-        {
+        try {
             Thread.sleep(time);
-        }
-        catch (InterruptedException ex)
-        {
+        } catch (InterruptedException ex) {
             ex.printStackTrace();
         }
     }
-    
+
+
+
+    public static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
+    public static String bytesToHex(byte[] bytes) {
+        char[] hexChars = new char[bytes.length * 2];
+        for (int j = 0; j < bytes.length; j++) {
+            int v = bytes[j] & 0xFF;
+            hexChars[j * 2] = HEX_ARRAY[v >>> 4];
+            hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
+        }
+
+        String hexxit = new String(hexChars).toLowerCase(Locale.ROOT);
+        //hexxit = hexxit.replaceAll("^0+", "");
+        return hexxit;
+    }
+
     /**
      * SHA-Hashes a String
+     *
      * @param s String to hash
      * @return Hashed String
      */
-    public static String getSHAString(String s)
-    {
-        try
-        {
+    public static String getSHAString(String s) {
+        try {
             MessageDigest sha = MessageDigest.getInstance("SHA");
             @SuppressWarnings("StringBufferMayBeStringBuilder")
             StringBuffer t = new StringBuffer();
             byte[] digest = sha.digest(s.getBytes());
-            for (byte b : digest)
-            {
+            for (byte b : digest) {
                 l.trace(String.format("%02x", b));
                 int val = ((int) b) & 0xff;
-                if (val < 16)
-                {
+                if (val < 16) {
                     t.append("0");
                 }
                 t.append(Integer.toHexString(val));
             }
             return t.toString();
-        }
-        catch (Exception ex)
-        {
+        } catch (Exception ex) {
             return null;
         }
     }
-    
-    
+
+
     /**
      * Integerizes a String
+     *
      * @param ip String to integerize
      * @return Array of Integers where each int is a Character of the string
      */
-    public static int[] lettersToInt(String ip)
-    {
+    public static int[] lettersToInt(String ip) {
         ip = ip.toLowerCase();
         char[] it = ip.toCharArray();
         int[] ri = new int[it.length];
-        for (int i = 0; i < ri.length; i++)
-        {
+        for (int i = 0; i < ri.length; i++) {
             ri[i] = (int) it[i];
         }
         return ri;
@@ -163,20 +162,19 @@ public class Tools
 
     /**
      * Sum of the Elements of the Array
+     *
      * @param i Integer-array to sumup
      * @return Sum of the elements
      */
-    public static int addIntsTogether(int[] i)
-    {
+    public static int addIntsTogether(int[] i) {
         int t = 1;
-        for (int X : i)
-        {
+        for (int X : i) {
             t *= X;
         }
         return t;
     }
 
-    
+
     @Deprecated
     /**
      * HACK!!!
@@ -184,31 +182,24 @@ public class Tools
      * @param ints unknown
      * @return unknown
      */
-    public static int addIntsTogether(HashMap<String, String> m, boolean ints)
-    {
+    public static int addIntsTogether(HashMap<String, String> m, boolean ints) {
         //boolean ints = !noints;
         String[] mk;
         Object[] mk2 = m.keySet().toArray();
         mk = new String[mk2.length];
-        for (int i = 0; i < mk.length; i++)
-        {
+        for (int i = 0; i < mk.length; i++) {
             String s = "";
             //s.toString();
             mk[i] = mk2[i].toString();
         }
         int t = 1;
-        for (String s : mk)
-        {
-            if (ints == true)
-            {
+        for (String s : mk) {
+            if (ints == true) {
                 t *= Integer.valueOf(m.get(s));
-            }
-            else
-            {
+            } else {
                 int t2 = 0;
                 int[] itmp = lettersToInt(m.get(s));
-                for (int i : itmp)
-                {
+                for (int i : itmp) {
                     t2 += i;
                 }
                 t += t2;
@@ -224,66 +215,48 @@ public class Tools
      * @param s2 String 2
      * @return the merged Strings
      */
-    public static String stringAdd(String s1, String s2)
-    {
+    public static String stringAdd(String s1, String s2) {
         char[] ca1 = s1.toLowerCase().toCharArray();
         char[] ca2 = s2.toLowerCase().toCharArray();
         int[] ci1 = new int[ca1.length];
         int[] ci2 = new int[ca2.length];
 
         String t;
-        for (int i = 0; i < ca1.length; i++)
-        {
-            try
-            {
+        for (int i = 0; i < ca1.length; i++) {
+            try {
                 ci1[i] = Integer.valueOf(Character.toString(ca1[i]));
-            }
-            catch (Exception ex)
-            {
+            } catch (Exception ex) {
                 t = Character.toString(ca1[i]);
                 ci1[i] = ALPHABET.indexOf(t) + 1;
             }
         }
-        for (int i = 0; i < ca2.length; i++)
-        {
-            try
-            {
+        for (int i = 0; i < ca2.length; i++) {
+            try {
                 ci2[i] = Integer.valueOf(Character.toString(ca2[i]));
-            }
-            catch (Exception ex)
-            {
+            } catch (Exception ex) {
                 t = Character.toString(ca2[i]);
                 ci2[i] = ALPHABET.indexOf(t) + 1;
             }
         }
         int l = ci1.length;
-        if (ci1.length < ci2.length)
-        {
+        if (ci1.length < ci2.length) {
             l = ci2.length;
         }
         int[] op = new int[l];
         int i1, i2, i3;
-        for (int i = 0; i < l; i++)
-        {
-            try
-            {
+        for (int i = 0; i < l; i++) {
+            try {
                 i1 = ci1[i];
-            }
-            catch (Exception ex)
-            {
+            } catch (Exception ex) {
                 i1 = 0;
             }
-            try
-            {
+            try {
                 i2 = ci2[i];
-            }
-            catch (Exception ex)
-            {
+            } catch (Exception ex) {
                 i2 = 0;
             }
             i3 = i1 + i1;
-            if (i3 > 26)
-            {
+            if (i3 > 26) {
                 i3 -= 26;
             }
             op[i] = i3;
@@ -291,30 +264,27 @@ public class Tools
 
         return backString(op);
     }
+
     @Deprecated
-    public static String backString(int[] ia)
-    {
+    public static String backString(int[] ia) {
         int l = ia.length, i1;
         String[] r1 = new String[l];
         String rl = "";
-        for (int i = 0; i < l; i++)
-        {
+        for (int i = 0; i < l; i++) {
             i1 = ia[i] - 1;
-            if (i1 == -1)
-            {
+            if (i1 == -1) {
                 i1++;
             }
             r1[i] = Character.toString(ALPHABET.charAt(i1));
         }
-        for (String s : r1)
-        {
+        for (String s : r1) {
             rl += s;
         }
 
 
-
         return rl;
     }
+
     @Deprecated
     public static String stringFold(String s, int l, int rec)//halbiert Strings und addiert die Hälften
     {
@@ -322,15 +292,13 @@ public class Tools
         String sh1, sh2, so1;
         //int l2=l1+1-1;//Neuen Wet erzeugen!!
         //l2=l1*2
-        if ((l1 * 2) == s.length() - 1)
-        {
+        if ((l1 * 2) == s.length() - 1) {
             l1++;
         }
         sh1 = s.substring(0, l1++);
         sh2 = s.substring(l1++);
         so1 = stringAdd(sh1, sh2);
-        if (so1.length() > l && rec > 0)
-        {
+        if (so1.length() > l && rec > 0) {
             so1 = stringFold(so1, l, rec--);
         }
 
@@ -338,40 +306,38 @@ public class Tools
     }
 
     @Deprecated
-    public static String stringFold(String s, int l)
-    {
+    public static String stringFold(String s, int l) {
         return stringFold(s, l, 30);
     }
 
     /**
      * 2-Elemente-Meckermeldung
-     * @param mode ignored
+     *
+     * @param mode     ignored
      * @param MSGLine1 Zeile 1 der Meldung
      * @param MSGLine2 ZEile 2 der Meldung
      * @return true if left button got pressed, false on right one
      */
-    public static boolean dlg(boolean mode, String MSGLine1, String MSGLine2)
-    {
+    public static boolean dlg(boolean mode, String MSGLine1, String MSGLine2) {
         return dlg(mode, MSGLine1, MSGLine2, "Fortfahren", "Abbrechen");
     }
 
-    
+
     /**
      * 2-Elemente-Meckermeldung
-     * @param mode ignored
+     *
+     * @param mode     ignored
      * @param MSGLine1 Zeile 1 der Meldung
      * @param MSGLine2 ZEile 2 der Meldung
-     * @param btnLeft MEssage of left button
+     * @param btnLeft  MEssage of left button
      * @param btnRight MEssage of Right button
      * @return true if left button got pressed, false on right one
      */
-    public static boolean dlg(boolean mode, String MSGLine1, String MSGLine2, String btnLeft, String btnRight)
-    {
-        if(hl)
-        {
+    public static boolean dlg(boolean mode, String MSGLine1, String MSGLine2, String btnLeft, String btnRight) {
+        if (hl) {
             return false;
         }
-        d=new JDialog();
+        d = new JDialog();
         JPanel p = new JPanel();
         javax.swing.JButton btnYes = new javax.swing.JButton();
         javax.swing.JButton btnNo = new javax.swing.JButton();
@@ -379,27 +345,21 @@ public class Tools
         JLabel lblMSG2 = new JLabel();
 
 
-
         d.setModal(mode);
         mode = true;
-        if (mode == true)
-        {
+        if (mode == true) {
             //Ausgeblendet da nur Fenster-Layout
             // <editor-fold defaultstate="collapsed" desc="Layout-Code">
             btnNo.setText(btnRight);
-            btnNo.addActionListener(new java.awt.event.ActionListener()
-            {
-                public void actionPerformed(java.awt.event.ActionEvent evt)
-                {
+            btnNo.addActionListener(new java.awt.event.ActionListener() {
+                public void actionPerformed(java.awt.event.ActionEvent evt) {
                     btnNoActionPerformed(evt);
                 }
             });
 
             btnYes.setText(btnLeft);
-            btnYes.addActionListener(new java.awt.event.ActionListener()
-            {
-                public void actionPerformed(java.awt.event.ActionEvent evt)
-                {
+            btnYes.addActionListener(new java.awt.event.ActionListener() {
+                public void actionPerformed(java.awt.event.ActionEvent evt) {
                     btnYesActionPerformed(evt);
                 }
             });
@@ -412,30 +372,30 @@ public class Tools
             p.setLayout(layout);
             layout.setHorizontalGroup(
                     layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                    .addGroup(layout.createSequentialGroup()
-                    .addGap(36, 36, 36)
-                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                    .addComponent(lblMSG, javax.swing.GroupLayout.PREFERRED_SIZE, 258, javax.swing.GroupLayout.PREFERRED_SIZE)
-                    .addGroup(layout.createSequentialGroup()
-                    .addComponent(btnYes)
-                    .addGap(18, 18, 18)
-                    .addComponent(btnNo))
-                    .addGroup(layout.createSequentialGroup()
-                    .addGap(40, 40, 40)
-                    .addComponent(lblMSG2)))
-                    .addContainerGap(63, Short.MAX_VALUE)));
+                            .addGroup(layout.createSequentialGroup()
+                                    .addGap(36, 36, 36)
+                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                                            .addComponent(lblMSG, javax.swing.GroupLayout.PREFERRED_SIZE, 258, javax.swing.GroupLayout.PREFERRED_SIZE)
+                                            .addGroup(layout.createSequentialGroup()
+                                                    .addComponent(btnYes)
+                                                    .addGap(18, 18, 18)
+                                                    .addComponent(btnNo))
+                                            .addGroup(layout.createSequentialGroup()
+                                                    .addGap(40, 40, 40)
+                                                    .addComponent(lblMSG2)))
+                                    .addContainerGap(63, Short.MAX_VALUE)));
             layout.setVerticalGroup(
                     layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                    .addGroup(layout.createSequentialGroup()
-                    .addContainerGap()
-                    .addComponent(lblMSG, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)
-                    .addGap(18, 18, 18)
-                    .addComponent(lblMSG2)
-                    .addGap(18, 18, 18)
-                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
-                    .addComponent(btnYes)
-                    .addComponent(btnNo))
-                    .addContainerGap(71, Short.MAX_VALUE)));
+                            .addGroup(layout.createSequentialGroup()
+                                    .addContainerGap()
+                                    .addComponent(lblMSG, javax.swing.GroupLayout.PREFERRED_SIZE, 27, javax.swing.GroupLayout.PREFERRED_SIZE)
+                                    .addGap(18, 18, 18)
+                                    .addComponent(lblMSG2)
+                                    .addGap(18, 18, 18)
+                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                                            .addComponent(btnYes)
+                                            .addComponent(btnNo))
+                                    .addContainerGap(71, Short.MAX_VALUE)));
             // </editor-fold>
 
             //p.add(btnYes);
@@ -447,9 +407,7 @@ public class Tools
 
             //btnNo.setText(btnRight);
             //btnYes.setText(btnLeft);
-        }
-        else
-        {
+        } else {
             //TODO working.dialog
             return true;
         }
@@ -459,153 +417,126 @@ public class Tools
 
 
     //</editor-fold>
+
     /**
      * COmmand run wrapper
+     *
      * @param runnable Command elements
      */
-    public static void runSingleCmd(String... runnable)
-    {
+    public static void runSingleCmd(String... runnable) {
         runSingleCmd(true, runnable);
     }
 
-    public static void runSingleCmd(boolean logg, String... runnable)
-    {
+    public static void runSingleCmd(boolean logg, String... runnable) {
         runSingleCmd(true, false, runnable);
     }
 
-    public static void runSingleCmd(boolean logg, boolean legacy, String... runnable)
-    {
+    public static void runSingleCmd(boolean logg, boolean legacy, String... runnable) {
         runSingleCmd(logg, legacy, false, runnable);
     }
 
-    
 
-    
-    
-    public static String runSingleCmd(boolean logg, boolean legacy, boolean sret, String... runnable)
-    {
+    public static String runSingleCmd(boolean logg, boolean legacy, boolean sret, String... runnable) {
         return runSingleCmd(logg, legacy, sret, null, runnable);
     }
 
-    public static String runSingleCmd(boolean logg, boolean legacy, boolean sret,JTextArea tx, String... runnable)
-    {
-    return runSingleCmd(logg, legacy, sret, false, tx, runnable);
+    public static String runSingleCmd(boolean logg, boolean legacy, boolean sret, JTextArea tx, String... runnable) {
+        return runSingleCmd(logg, legacy, sret, false, tx, runnable);
     }
-    public static String runSingleCmd(boolean logg, boolean legacy, boolean sret,boolean asArray,JTextArea tx, String... runnable)
-    {
+
+    public static String runSingleCmd(boolean logg, boolean legacy, boolean sret, boolean asArray, JTextArea tx, String... runnable) {
         return runSingleCmd(logg, legacy, sret, asArray, tx, null, runnable);
     }
-    public static String runSingleCmd(boolean logg, boolean legacy, boolean sret,boolean asArray,JTextArea tx, final PrintStream pw,String... runnable)
-    {
-        return runSingleCmd(logg, legacy, sret, asArray, tx, null, null,false,runnable);
+
+    public static String runSingleCmd(boolean logg, boolean legacy, boolean sret, boolean asArray, JTextArea tx, final PrintStream pw, String... runnable) {
+        return runSingleCmd(logg, legacy, sret, asArray, tx, null, null, false, runnable);
     }
+
     private static Process p;
-    public static String runSingleCmd(boolean logg, boolean legacy, boolean sret,boolean asArray,final JTextArea tx, final PrintStream pw, String workdir,boolean useWD,String... runnable)
-    {
+
+    public static String runSingleCmd(boolean logg, boolean legacy, boolean sret, boolean asArray, final JTextArea tx, final PrintStream pw, String workdir, boolean useWD, String... runnable) {
         execCrashed = false;
-                String cret = "";
-        File wd=null;
-        if(workdir!=null&&useWD)
-        {
-            wd=new File(workdir);
-            if(!wd.isDirectory())
-                wd=null;
-        }        
+        String cret = "";
+        File wd = null;
+        if (workdir != null && useWD) {
+            wd = new File(workdir);
+            if (!wd.isDirectory())
+                wd = null;
+        }
         String cmd = "";
-        for (String string : runnable)
-        {
+        for (String string : runnable) {
             cmd += string + " ";
             cmd = cmd.trim();
 
         }//wird für ohne array verwended und bei mit array fürs debugging;
         l.trace(cmd);
-        try
-        {
-            ProcessBuilder p2=null;
-            if(wd!=null)
-            {
+        try {
+            ProcessBuilder p2 = null;
+            if (wd != null) {
                 p2 = new ProcessBuilder(runnable);
                 p2.directory(wd);
             }
-            
+
             Executor e = null;
             CommandLine c = null;
-            if (!legacy)
-            {
+            if (!legacy) {
                 c = new CommandLine("cmd.exe");
                 c.addArgument(cmd);
                 e = new DefaultExecutor();
-            }
-            else
-            {
-                if(wd==null)
-                {
+            } else {
+                if (wd == null) {
                     p = null;
-                    if(!asArray)
-                        p=Runtime.getRuntime().exec(cmd);
+                    if (!asArray)
+                        p = Runtime.getRuntime().exec(cmd);
                     else
-                        p=Runtime.getRuntime().exec(runnable);
-                }
-                else
-                {
-                    p=p2.start();
+                        p = Runtime.getRuntime().exec(runnable);
+                } else {
+                    p = p2.start();
                 }
-                if(tx!=null)
-                {
+                if (tx != null) {
                     new Thread(
-                    new Runnable()
-                    {
-
-                        @Override
-                        public void run()
-                        {
-                        Scanner scanner = new Scanner(p.getInputStream());
-                        Scanner scannerE = new Scanner(p.getErrorStream());
-                        while ((scanner.hasNextLine()||scannerE.hasNextLine()))
-                        {
-                            if(scanner.hasNextLine())
-                            {
-                                String l = scanner.nextLine();
-                                tx.append(l+"\n");
-                                if(pw!=null)
-                                    pw.println(l);
-                            }
-                            if(scannerE.hasNextLine())
-                            {
-                                String l = scannerE.next();
-                                tx.append(l+"\n");
-                                if(pw!=null)
-                                    pw.println(l);
+                            new Runnable() {
+
+                                @Override
+                                public void run() {
+                                    Scanner scanner = new Scanner(p.getInputStream());
+                                    Scanner scannerE = new Scanner(p.getErrorStream());
+                                    while ((scanner.hasNextLine() || scannerE.hasNextLine())) {
+                                        if (scanner.hasNextLine()) {
+                                            String l = scanner.nextLine();
+                                            tx.append(l + "\n");
+                                            if (pw != null)
+                                                pw.println(l);
+                                        }
+                                        if (scannerE.hasNextLine()) {
+                                            String l = scannerE.next();
+                                            tx.append(l + "\n");
+                                            if (pw != null)
+                                                pw.println(l);
+                                        }
+                                    }
+                                }
                             }
-                        }
-                    }
-                }
-            ).start();
+                    ).start();
                 }
-                if (sret)
-                {
+                if (sret) {
                     cret = new BufferedReader(new InputStreamReader(p.getInputStream())).readLine();
                 }
                 int rv = p.waitFor();
-                if(rv>0)
-                {
-                    execCrashed=true;
+                if (rv > 0) {
+                    execCrashed = true;
                 }
             }
             l.trace(cmd);
-            if (logg)
-            {
+            if (logg) {
                 l.trace("Logg");
                 logNumber++;
             }
-            if (!legacy)
-            {
+            if (!legacy) {
                 e.execute(c);
             }
-        }
-        catch (Exception ex)
-        {
-            l.error("Error@"+cmd);
+        } catch (Exception ex) {
+            l.error("Error@" + cmd);
             l.error(ex.toString());
             l.error(ex.getMessage());
             //TODO:SetupError_Here
@@ -613,43 +544,41 @@ public class Tools
         }
         return cret;
     }
-    private static void btnYesActionPerformed(java.awt.event.ActionEvent evt)
-    {
+
+    private static void btnYesActionPerformed(java.awt.event.ActionEvent evt) {
         ContState = true;
         hideDialog();
         d = null;
         d = new JDialog();
     }
 
-  private static void btnNoActionPerformed(java.awt.event.ActionEvent evt)
-    {
+    private static void btnNoActionPerformed(java.awt.event.ActionEvent evt) {
         ContState = false;
         hideDialog();
         d = null;
         d = new JDialog();
     }
 
-    public static void hideDialog()
-    {
+    public static void hideDialog() {
         d.setVisible(false);
     }
 
-    
-        public static String getRelativePath(String absolutePath, String basePath)//Initializer für Hack!
+
+    public static String getRelativePath(String absolutePath, String basePath)//Initializer für Hack!
     {
-       return FileTK.getRelativePath(absolutePath, basePath);
+        return FileTK.getRelativePath(absolutePath, basePath);
     }
-    
+
     /**
      * Array shortening method
-     * @param toTrunc SArray to remove
-     * @param number Amount to remove
+     *
+     * @param toTrunc  SArray to remove
+     * @param number   Amount to remove
      * @param fromBack True means remove from end, false means remove from start
      * @return Shortened array
      */
     @SuppressWarnings("ManualArrayToCollectionCopy")//Quick and Dirty Hack
-    public static Object[] truncateArray(Object[] toTrunc, int number, boolean fromBack)
-    {
+    public static Object[] truncateArray(Object[] toTrunc, int number, boolean fromBack) {
         //number++;//fucked up error!
         if (toTrunc.length - number < 1)//Error bei Zahlen <0
         {
@@ -658,15 +587,11 @@ public class Tools
         Object[] out = new Object[toTrunc.length - number];
         if (fromBack == true)//Hinten weg
         {
-            for (int i = 0; i < toTrunc.length - number; i++)
-            {
+            for (int i = 0; i < toTrunc.length - number; i++) {
                 out[i] = toTrunc[i];
             }
-        }
-        else
-        {   //Evil loop :P (linenumber)
-            for (int i = 0; i > toTrunc.length - number; i++)
-            {
+        } else {   //Evil loop :P (linenumber)
+            for (int i = 0; i > toTrunc.length - number; i++) {
                 int j = i + number;
                 out[i] = toTrunc[j];
             }
@@ -674,32 +599,29 @@ public class Tools
         return out;
     }
 
-    
+
     /**
      * OPens a Input window for a line of text
+     *
      * @param title Title of the window
-     * @return 
+     * @return
      */
-    public static String getInputString(String title)
-    {
+    public static String getInputString(String title) {
         return getInputString(title, false);
     }
-    
+
     /**
      * OPens a Input window for a line of text
-     * @param title Title of the window
+     *
+     * @param title  Title of the window
      * @param txArea WHether to use a MUltiline input or a singleline inout
-     * @return 
+     * @return
      */
-    public static String getInputString(String title, boolean txArea)
-    {
+    public static String getInputString(String title, boolean txArea) {
         Object txfIP;//Hack!!!!
-        if (txArea == true)
-        {
+        if (txArea == true) {
             txfIP = new JTextArea(20, 40);
-        }
-        else
-        {
+        } else {
             txfIP = new JTextField(30);
         }
         //passwordField.setEchoChar('#');
@@ -709,12 +631,9 @@ public class Tools
                 title,
                 JOptionPane.PLAIN_MESSAGE);
         String ret = "";
-        if (txArea == true)
-        {
+        if (txArea == true) {
             ret = ((JTextArea) txfIP).getText();
-        }
-        else
-        {
+        } else {
             ret = ((JTextField) txfIP).getText();
         }
         return ret;
@@ -722,49 +641,43 @@ public class Tools
 
     /**
      * Shorthand to write serialized data to a file
+     *
      * @param o Object to dump
      * @param p Destination file
      */
-    public static void saveSerializedObject(Object[] o, String p)
-    {
-        try
-        {
+    public static void saveSerializedObject(Object[] o, String p) {
+        try {
             FileOutputStream fos = new FileOutputStream(p);
             ObjectOutputStream os = new ObjectOutputStream(fos);
             os.writeObject(o);
-        }
-        catch (Exception e)
-        {
+        } catch (Exception e) {
             //NOP
         }
     }
-    
+
     /**
      * Shorthand to load serialized data
+     *
      * @param p Path to load from
      * @return Array with the objects dumped
      */
-    public static Object[] loadSerializedObject(String p)
-    {
-        try
-        {
+    public static Object[] loadSerializedObject(String p) {
+        try {
             FileInputStream fis = new FileInputStream(p);
             ObjectInputStream o = new ObjectInputStream(fis);
             return (Object[]) o.readObject();
-        }
-        catch (Exception e)
-        {
-            l.warn("Loader.failure @{}",p);
+        } catch (Exception e) {
+            l.warn("Loader.failure @{}", p);
             e.printStackTrace();
             return null;
         }
     }
+
     private static JList lstItemz;
     private static String retval;
 
-    public static String listSelectorPopup(String[] elemsToChoseFrom, String Question)
-    {
-        if(hl)return "";
+    public static String listSelectorPopup(String[] elemsToChoseFrom, String Question) {
+        if (hl) return "";
         JPanel p = new JPanel();
         d.setModal(true);
         lstItemz = new javax.swing.JList();
@@ -788,18 +701,15 @@ public class Tools
         ((DefaultListModel) (lstItemz.getModel())).clear();
         //  String[] availUPIDs = dbc.querySIngleColumn("Select UPID20 from upidlst");
 
-        for (String elem : elemsToChoseFrom)
-        {
+        for (String elem : elemsToChoseFrom) {
             ((DefaultListModel) (Tools.lstItemz.getModel())).addElement(elem);
         }
 
 
         retval = "NOP";
 
-        btnCont.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
+        btnCont.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
                 retval = (String) lstItemz.getSelectedValue();
                 hideDialog();
                 d = null;
@@ -807,43 +717,41 @@ public class Tools
             }
         });
 
-        btnAbort.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
+        btnAbort.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
                 retval = "NOP";
                 hideDialog();
                 d = null;
-                d = new JDialog();;
+                d = new JDialog();
+                ;
             }
         });
 
 
-
         javax.swing.GroupLayout layout = new javax.swing.GroupLayout(p);
         p.setLayout(layout);
         layout.setHorizontalGroup(
                 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                .addComponent(jScrollPane1)
-                .addGroup(layout.createSequentialGroup()
-                .addGap(47, 47, 47)
-                .addComponent(txtQuestion, javax.swing.GroupLayout.PREFERRED_SIZE, 494, javax.swing.GroupLayout.PREFERRED_SIZE)
-                .addContainerGap(95, Short.MAX_VALUE))
-                .addGroup(layout.createSequentialGroup()
-                .addComponent(btnCont, javax.swing.GroupLayout.PREFERRED_SIZE, 327, javax.swing.GroupLayout.PREFERRED_SIZE)
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addComponent(btnAbort, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
+                        .addComponent(jScrollPane1)
+                        .addGroup(layout.createSequentialGroup()
+                                .addGap(47, 47, 47)
+                                .addComponent(txtQuestion, javax.swing.GroupLayout.PREFERRED_SIZE, 494, javax.swing.GroupLayout.PREFERRED_SIZE)
+                                .addContainerGap(95, Short.MAX_VALUE))
+                        .addGroup(layout.createSequentialGroup()
+                                .addComponent(btnCont, javax.swing.GroupLayout.PREFERRED_SIZE, 327, javax.swing.GroupLayout.PREFERRED_SIZE)
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                .addComponent(btnAbort, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
         layout.setVerticalGroup(
                 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                .addGroup(layout.createSequentialGroup()
-                .addGap(26, 26, 26)
-                .addComponent(txtQuestion)
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
-                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE)
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                .addComponent(btnCont, javax.swing.GroupLayout.DEFAULT_SIZE, 34, Short.MAX_VALUE)
-                .addComponent(btnAbort, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))));
+                        .addGroup(layout.createSequentialGroup()
+                                .addGap(26, 26, 26)
+                                .addComponent(txtQuestion)
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE)
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                                        .addComponent(btnCont, javax.swing.GroupLayout.DEFAULT_SIZE, 34, Short.MAX_VALUE)
+                                        .addComponent(btnAbort, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))));
         d.add(p);
         Dimension d2 = p.getPreferredSize();
         d2 = new Dimension(d2.width, d2.height + 40);
@@ -851,57 +759,50 @@ public class Tools
         d.setVisible(true);
 
 
-
         return retval;
     }
 
-    public static String FileChooseDlg(javax.swing.JFrame frm)
-    {
-        return FileChooseDlg(frm,false,false,null);
+    public static String FileChooseDlg(javax.swing.JFrame frm) {
+        return FileChooseDlg(frm, false, false, null);
     }
-    
-    
+
+
     /**
      * Opens a FileChooser and returns the path that got chosen
-     * @param frm Frame the Dialog links to
+     *
+     * @param frm      Frame the Dialog links to
      * @param restrict flag to select if a FileLimiter should be used
      * @param dirsOnly flag to restrict the CHooser to directories only
-     * @param exts Array of FileExtensions
+     * @param exts     Array of FileExtensions
      * @return Path when file got opened or empty string if none selected
      */
-    public static String FileChooseDlg(javax.swing.JFrame frm,boolean restrict,boolean dirsOnly,String[] exts)
-    {
+    public static String FileChooseDlg(javax.swing.JFrame frm, boolean restrict, boolean dirsOnly, String[] exts) {
         JFileChooser fc = new JFileChooser();
         String ret = "";
-        if(!dirsOnly)
+        if (!dirsOnly)
             fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
         else
             fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
-        if(restrict)
-        {
+        if (restrict) {
             FIleLImiter f = new FIleLImiter();
             f.setExtensions(exts);
             fc.setFileFilter(f);
         }
         int returnVal = fc.showOpenDialog(frm);
-        if (returnVal == JFileChooser.APPROVE_OPTION)
-        {
+        if (returnVal == JFileChooser.APPROVE_OPTION) {
             File file = fc.getSelectedFile();
-            try
-            {
+            try {
                 ret = file.getCanonicalPath();
-            }
-            catch (IOException ex)
-            {
+            } catch (IOException ex) {
             }
         }
         return ret;
     }
+
     private static int retnumber = 0;
 
-    public static int numberInputWIndow(int maxNbr, int[] blockednumbrs)
-    {
-        if(hl) return -1;
+    public static int numberInputWIndow(int maxNbr, int[] blockednumbrs) {
+        if (hl) return -1;
         l.info("niw");
         k1 = new javax.swing.JButton();
         k2 = new javax.swing.JButton();
@@ -920,7 +821,6 @@ public class Tools
         btnClear = new javax.swing.JButton();
 
 
-
         d = new JDialog();
         d.setModal(true);
         numEntered = 0;
@@ -937,46 +837,35 @@ public class Tools
         k9.setEnabled(true);
         retnumber = 0;
 
-        for (int i : blockednumbrs)
-        {
-            if (i == 0)
-            {
+        for (int i : blockednumbrs) {
+            if (i == 0) {
                 k0.setEnabled(false);
             }
-            if (i == 1)
-            {
+            if (i == 1) {
                 k1.setEnabled(false);
             }
-            if (i == 2)
-            {
+            if (i == 2) {
                 k2.setEnabled(false);
             }
-            if (i == 3)
-            {
+            if (i == 3) {
                 k3.setEnabled(false);
             }
-            if (i == 4)
-            {
+            if (i == 4) {
                 k4.setEnabled(false);
             }
-            if (i == 5)
-            {
+            if (i == 5) {
                 k5.setEnabled(false);
             }
-            if (i == 6)
-            {
+            if (i == 6) {
                 k6.setEnabled(false);
             }
-            if (i == 7)
-            {
+            if (i == 7) {
                 k7.setEnabled(false);
             }
-            if (i == 8)
-            {
+            if (i == 8) {
                 k8.setEnabled(false);
             }
-            if (i == 9)
-            {
+            if (i == 9) {
                 k9.setEnabled(false);
             }
 
@@ -984,131 +873,100 @@ public class Tools
         }
 
 
-
-
-
         k1.setText("1");
-        k1.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
+        k1.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
                 k1ActionPerformed(evt);
             }
         });
 
         k2.setText("2");
-        k2.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
+        k2.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
                 k2ActionPerformed(evt);
             }
         });
 
         k3.setText("3");
-        k3.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
+        k3.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
                 k3ActionPerformed(evt);
             }
         });
 
         k4.setText("4");
-        k4.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
+        k4.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
                 k4ActionPerformed(evt);
             }
         });
 
         k5.setText("5");
-        k5.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
+        k5.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
                 k5ActionPerformed(evt);
             }
         });
 
         k6.setText("6");
-        k6.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
+        k6.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
                 k6ActionPerformed(evt);
             }
         });
 
         k7.setText("7");
-        k7.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
+        k7.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
                 k7ActionPerformed(evt);
             }
         });
 
         k8.setText("8");
-        k8.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
+        k8.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
                 k8ActionPerformed(evt);
             }
         });
 
         k9.setText("9");
-        k9.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
+        k9.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
                 k9ActionPerformed(evt);
             }
         });
 
         btnOk.setText("OK");
-        btnOk.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
+        btnOk.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
                 btnOkActionPerformed(evt);
             }
         });
 
         btnAbbr.setText("ABBR");
-        btnAbbr.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
+        btnAbbr.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
                 btnAbbrActionPerformed(evt);
             }
         });
 
         k0.setText("0");
-        k0.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
+        k0.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
                 k0ActionPerformed(evt);
             }
         });
 
         kC.setText("<--");
-        kC.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
+        kC.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
                 kCActionPerformed(evt);
             }
         });
 
         btnClear.setText("Clr");
-        btnClear.addActionListener(new java.awt.event.ActionListener()
-        {
-            public void actionPerformed(java.awt.event.ActionEvent evt)
-            {
+        btnClear.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
                 btnClearActionPerformed(evt);
             }
         });
@@ -1117,69 +975,69 @@ public class Tools
         d.getContentPane().setLayout(layout);
         layout.setHorizontalGroup(
                 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                .addGroup(layout.createSequentialGroup()
-                .addContainerGap()
-                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
-                .addGroup(layout.createSequentialGroup()
-                .addComponent(btnOk, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addComponent(btnAbbr, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
-                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
-                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
-                .addComponent(k1, javax.swing.GroupLayout.DEFAULT_SIZE, 51, Short.MAX_VALUE)
-                .addComponent(k4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
-                .addComponent(k2, javax.swing.GroupLayout.DEFAULT_SIZE, 49, Short.MAX_VALUE)
-                .addComponent(k5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
-                .addComponent(k3, javax.swing.GroupLayout.DEFAULT_SIZE, 49, Short.MAX_VALUE)
-                .addComponent(k6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
-                .addGroup(layout.createSequentialGroup()
-                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
-                .addComponent(k7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                .addComponent(btnClear, javax.swing.GroupLayout.DEFAULT_SIZE, 51, Short.MAX_VALUE))
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
-                .addComponent(k0, javax.swing.GroupLayout.DEFAULT_SIZE, 49, Short.MAX_VALUE)
-                .addComponent(k8, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                .addComponent(k9, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                .addComponent(kC, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
-                .addComponent(entrdNbr))
-                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
+                        .addGroup(layout.createSequentialGroup()
+                                .addContainerGap()
+                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+                                        .addGroup(layout.createSequentialGroup()
+                                                .addComponent(btnOk, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
+                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                                .addComponent(btnAbbr, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+                                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+                                                        .addComponent(k1, javax.swing.GroupLayout.DEFAULT_SIZE, 51, Short.MAX_VALUE)
+                                                        .addComponent(k4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+                                                        .addComponent(k2, javax.swing.GroupLayout.DEFAULT_SIZE, 49, Short.MAX_VALUE)
+                                                        .addComponent(k5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+                                                        .addComponent(k3, javax.swing.GroupLayout.DEFAULT_SIZE, 49, Short.MAX_VALUE)
+                                                        .addComponent(k6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+                                        .addGroup(layout.createSequentialGroup()
+                                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+                                                        .addComponent(k7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                                        .addComponent(btnClear, javax.swing.GroupLayout.DEFAULT_SIZE, 51, Short.MAX_VALUE))
+                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+                                                        .addComponent(k0, javax.swing.GroupLayout.DEFAULT_SIZE, 49, Short.MAX_VALUE)
+                                                        .addComponent(k8, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                                                        .addComponent(k9, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                                        .addComponent(kC, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+                                        .addComponent(entrdNbr))
+                                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
         layout.setVerticalGroup(
                 layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                .addGroup(layout.createSequentialGroup()
-                .addGap(7, 7, 7)
-                .addComponent(entrdNbr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
-                .addComponent(k3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                .addComponent(k2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                .addComponent(k1, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE))
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
-                .addComponent(k6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                .addComponent(k5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                .addComponent(k4, javax.swing.GroupLayout.PREFERRED_SIZE, 48, javax.swing.GroupLayout.PREFERRED_SIZE))
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
-                .addComponent(k7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                .addComponent(k8, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                .addComponent(k9, javax.swing.GroupLayout.PREFERRED_SIZE, 49, javax.swing.GroupLayout.PREFERRED_SIZE))
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
-                .addComponent(k0, javax.swing.GroupLayout.DEFAULT_SIZE, 46, Short.MAX_VALUE)
-                .addComponent(kC, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                .addComponent(btnClear, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
-                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
-                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
-                .addComponent(btnAbbr, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
-                .addComponent(btnOk, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE))
-                .addGap(0, 8, Short.MAX_VALUE)));
+                        .addGroup(layout.createSequentialGroup()
+                                .addGap(7, 7, 7)
+                                .addComponent(entrdNbr, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+                                        .addComponent(k3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                        .addComponent(k2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                        .addComponent(k1, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE))
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+                                        .addComponent(k6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                        .addComponent(k5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                        .addComponent(k4, javax.swing.GroupLayout.PREFERRED_SIZE, 48, javax.swing.GroupLayout.PREFERRED_SIZE))
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+                                        .addComponent(k7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                        .addComponent(k8, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                        .addComponent(k9, javax.swing.GroupLayout.PREFERRED_SIZE, 49, javax.swing.GroupLayout.PREFERRED_SIZE))
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+                                        .addComponent(k0, javax.swing.GroupLayout.DEFAULT_SIZE, 46, Short.MAX_VALUE)
+                                        .addComponent(kC, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                        .addComponent(btnClear, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                                        .addComponent(btnAbbr, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
+                                        .addComponent(btnOk, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE))
+                                .addGap(0, 8, Short.MAX_VALUE)));
 
         d.pack();
         d.setVisible(true);
@@ -1187,149 +1045,122 @@ public class Tools
         return retnumber;
     }// </editor-fold>
 
-    private static void k1ActionPerformed(java.awt.event.ActionEvent evt)
-    {
-        if (numEntered >= numMax)
-        {
+    private static void k1ActionPerformed(java.awt.event.ActionEvent evt) {
+        if (numEntered >= numMax) {
             return;
         }
         entrdNbr.setText(entrdNbr.getText() + "1");
         numEntered++;
     }
 
-    private static void k2ActionPerformed(java.awt.event.ActionEvent evt)
-    {
-        if (numEntered >= numMax)
-        {
+    private static void k2ActionPerformed(java.awt.event.ActionEvent evt) {
+        if (numEntered >= numMax) {
             return;
         }
         entrdNbr.setText(entrdNbr.getText() + "2");
         numEntered++;
     }
 
-    private static void k3ActionPerformed(java.awt.event.ActionEvent evt)
-    {
-        if (numEntered >= numMax)
-        {
+    private static void k3ActionPerformed(java.awt.event.ActionEvent evt) {
+        if (numEntered >= numMax) {
             return;
         }
         entrdNbr.setText(entrdNbr.getText() + "3");
         numEntered++;
     }
 
-    private static void k4ActionPerformed(java.awt.event.ActionEvent evt)
-    {
-        if (numEntered >= numMax)
-        {
+    private static void k4ActionPerformed(java.awt.event.ActionEvent evt) {
+        if (numEntered >= numMax) {
             return;
         }
         entrdNbr.setText(entrdNbr.getText() + "4");
         numEntered++;
     }
 
-    private static void k5ActionPerformed(java.awt.event.ActionEvent evt)
-    {
-        if (numEntered >= numMax)
-        {
+    private static void k5ActionPerformed(java.awt.event.ActionEvent evt) {
+        if (numEntered >= numMax) {
             return;
         }
         entrdNbr.setText(entrdNbr.getText() + "5");
         numEntered++;
     }
 
-    private static void k6ActionPerformed(java.awt.event.ActionEvent evt)
-    {
-        if (numEntered >= numMax)
-        {
+    private static void k6ActionPerformed(java.awt.event.ActionEvent evt) {
+        if (numEntered >= numMax) {
             return;
         }
         entrdNbr.setText(entrdNbr.getText() + "6");
         numEntered++;
     }
 
-    private static void k7ActionPerformed(java.awt.event.ActionEvent evt)
-    {
-        if (numEntered >= numMax)
-        {
+    private static void k7ActionPerformed(java.awt.event.ActionEvent evt) {
+        if (numEntered >= numMax) {
             return;
         }
         entrdNbr.setText(entrdNbr.getText() + "7");
         numEntered++;
     }
 
-    private static void k8ActionPerformed(java.awt.event.ActionEvent evt)
-    {
-        if (numEntered >= numMax)
-        {
+    private static void k8ActionPerformed(java.awt.event.ActionEvent evt) {
+        if (numEntered >= numMax) {
             return;
         }
         entrdNbr.setText(entrdNbr.getText() + "8");
         numEntered++;
     }
 
-    private static void k9ActionPerformed(java.awt.event.ActionEvent evt)
-    {
-        if (numEntered >= numMax)
-        {
+    private static void k9ActionPerformed(java.awt.event.ActionEvent evt) {
+        if (numEntered >= numMax) {
             return;
         }
         entrdNbr.setText(entrdNbr.getText() + "9");
         numEntered++;
     }
 
-    private static void btnClearActionPerformed(java.awt.event.ActionEvent evt)
-    {
+    private static void btnClearActionPerformed(java.awt.event.ActionEvent evt) {
         numEntered = 0;
         entrdNbr.setText("");
     }
 
-    private static void k0ActionPerformed(java.awt.event.ActionEvent evt)
-    {
-        if (numEntered >= numMax)
-        {
+    private static void k0ActionPerformed(java.awt.event.ActionEvent evt) {
+        if (numEntered >= numMax) {
             return;
         }
         entrdNbr.setText(entrdNbr.getText() + "0");
         numEntered++;
     }
 
-    private static void kCActionPerformed(java.awt.event.ActionEvent evt)
-    {
+    private static void kCActionPerformed(java.awt.event.ActionEvent evt) {
         retnumber = -1;
         hideDialog();
         d = null;
         d = new JDialog();
     }
 
-    private static void btnOkActionPerformed(java.awt.event.ActionEvent evt)
-    {
+    private static void btnOkActionPerformed(java.awt.event.ActionEvent evt) {
         retnumber = Integer.valueOf(entrdNbr.getText());
         hideDialog();
         d = null;
         d = new JDialog();
     }
 
-    private static void btnAbbrActionPerformed(java.awt.event.ActionEvent evt)
-    {
+    private static void btnAbbrActionPerformed(java.awt.event.ActionEvent evt) {
         //retnumber=-1;
         hideDialog();
         d = null;
         d = new JDialog();
     }
 
-    public static String processEnvVarsinLine(String line)
-    {
+    public static String processEnvVarsinLine(String line) {
         Map<String, String> env = System.getenv();
         String linemod = line;
         int varstart = linemod.indexOf("%");
         int varend = linemod.indexOf("%", varstart + 1);
         String preVar = "";
-        if (varstart == -1)
-        {
+        if (varstart == -1) {
             return line;
         }
-        if (varstart > 0)
-        {
+        if (varstart > 0) {
             preVar = linemod.substring(0, varstart);
         }
         String postVar = linemod.substring(varend + 1);
@@ -1338,59 +1169,52 @@ public class Tools
         line = preVar + var + postVar;
         return line;
     }
-    public static String replaceHashmarkedVars(String line,String varname,String toReplace)
-    {
-        
-        return line.replaceAll("#"+varname+"#", toReplace.replace("\\", "\\\\")).replace("\\\\", "\\");
-        
+
+    public static String replaceHashmarkedVars(String line, String varname, String toReplace) {
+
+        return line.replaceAll("#" + varname + "#", toReplace.replace("\\", "\\\\")).replace("\\\\", "\\");
+
     }
-    
-    public static void DebugHelperPrint(String msg,boolean dbgonly,String debugEnablePreference)
-    {
-        if(dbgonly)
-            if(!Boolean.valueOf(Preferences.userRoot().get(debugEnablePreference, "false")))
-            return;
+
+    public static void DebugHelperPrint(String msg, boolean dbgonly, String debugEnablePreference) {
+        if (dbgonly)
+            if (!Boolean.valueOf(Preferences.userRoot().get(debugEnablePreference, "false")))
+                return;
         l.trace(msg);
     }
-    
-    
-    
-    
+
+
     private static boolean sil = false;
-    
-    public static boolean runCmdWithOutToTextField(JTextArea txf, String... cmd)
-    {
-        return runCmdStreamable(txf,new PrintStream(new NullOutputStream()),false, cmd);  
+
+    public static boolean runCmdWithOutToTextField(JTextArea txf, String... cmd) {
+        return runCmdStreamable(txf, new PrintStream(new NullOutputStream()), false, cmd);
     }
-    
-    public static boolean runCmdWithOutToTextField(JTextArea txf, ProcessWatcher w,String... cmd)
-    {
-        return runCmdStreamable(txf,new PrintStream(new NullOutputStream()),false,w, cmd);  
+
+    public static boolean runCmdWithOutToTextField(JTextArea txf, ProcessWatcher w, String... cmd) {
+        return runCmdStreamable(txf, new PrintStream(new NullOutputStream()), false, w, cmd);
     }
-    
-    public static boolean runCmdWithPassthru(PrintStream p,String... cmd)
-    {
-        return runCmdStreamable(new JTextArea(),p,false, cmd);
+
+    public static boolean runCmdWithPassthru(PrintStream p, String... cmd) {
+        return runCmdStreamable(new JTextArea(), p, false, cmd);
     }
-    
-    public static boolean runCmdWithPassthru(PrintStream p,ProcessWatcher w,String... cmd)
-    {
-        return runCmdStreamable(new JTextArea(),p,false,w, cmd);
+
+    public static boolean runCmdWithPassthru(PrintStream p, ProcessWatcher w, String... cmd) {
+        return runCmdStreamable(new JTextArea(), p, false, w, cmd);
     }
-    
+
     //private static ExecuteStreamHandler s;
     //private static JTextArea txf;
     //private static PrintStream otherOut;
-    public static boolean runCmdStreamable(JTextArea txf,PrintStream otherOut,final boolean SpamException, String... cmd)
-    {
+    public static boolean runCmdStreamable(JTextArea txf, PrintStream otherOut, final boolean SpamException, String... cmd) {
         return runCmdStreamable(txf, otherOut, SpamException, null, cmd);
     }
-        public static boolean runCmdStreamable(JTextArea txf,PrintStream otherOut,final boolean SpamException,ProcessWatcher w, String... cmd)//synchronized gint nen fetten Bug
+
+    public static boolean runCmdStreamable(JTextArea txf, PrintStream otherOut, final boolean SpamException, ProcessWatcher w, String... cmd)//synchronized gint nen fetten Bug
     {
-        return runCmdStreamable(txf, otherOut, SpamException, w,null,false ,cmd);
+        return runCmdStreamable(txf, otherOut, SpamException, w, null, false, cmd);
     }
-    
-    public static boolean runCmdStreamable(JTextArea txf,PrintStream otherOut,final boolean SpamException,ProcessWatcher w,OutputStreamBridge bridge,boolean async, String... cmd)//synchronized gint nen fetten Bug
+
+    public static boolean runCmdStreamable(JTextArea txf, PrintStream otherOut, final boolean SpamException, ProcessWatcher w, OutputStreamBridge bridge, boolean async, String... cmd)//synchronized gint nen fetten Bug
     {
         try //synchronized gint nen fetten Bug
         {
@@ -1400,85 +1224,66 @@ public class Tools
             // (
             //     new ByteArrayInputStream(new byte[]{0})
             // );//das einzelne Byte ist n(ö|ä)tig um ne NPX zu verhindern
-            
-            if(txf==null)
-            {
-                txf=new JTextArea();
+
+            if (txf == null) {
+                txf = new JTextArea();
             }
-            
-            if(otherOut==null)
-            {
-                otherOut=new PrintStream(new NullOutputStream());
+
+            if (otherOut == null) {
+                otherOut = new PrintStream(new NullOutputStream());
             }
-            l.trace("OtherOut="+otherOut);
-            
+            l.trace("OtherOut=" + otherOut);
+
             ProcessBuilder pb = new ProcessBuilder(Arrays.asList(cmd));
             pb.redirectErrorStream(true);
             //ProcessLauncher l = Native.get(ProcessLauncher.class);
             Process process = pb.start();
-            if(w!=null)
-            {
+            if (w != null) {
                 w.receiveProcess(process);
             }
             PrintStream stdout = new PrintStreamCapturer(txf, otherOut);
             Thread stdoutThread = new Thread(new TextDumper(process.getInputStream(), stdout));
             stdoutThread.start();
-            if(async)
-            {
-                if(bridge!=null)
-                {
-                    bridge.s=process.getOutputStream();
+            if (async) {
+                if (bridge != null) {
+                    bridge.s = process.getOutputStream();
                 }
                 l.trace("ASYNC background task");
                 return true;
-            }
-            else
-            {
-            int result = process.waitFor();
-            stdoutThread.join();
-            Tools.l.trace("FIN");
-            return result!=0;
+            } else {
+                int result = process.waitFor();
+                stdoutThread.join();
+                Tools.l.trace("FIN");
+                return result != 0;
             }
             //sil=false;
-        }
-        catch (InterruptedException|IOException ex)
-        {
+        } catch (InterruptedException | IOException ex) {
             ex.printStackTrace();
         }
         return true;
     }
 
-    
-    public static String getFormatStrforThisAsMax(int nbr)      
-    {
-        int filesMax=nbr;
+
+    public static String getFormatStrforThisAsMax(int nbr) {
+        int filesMax = nbr;
         String nfs = "%1";
-        if (filesMax > 9)
-        {
+        if (filesMax > 9) {
             nfs = "%2";
-            if (filesMax > 99)
-            {
+            if (filesMax > 99) {
                 nfs = "%3";
-                if (filesMax > 999)
-                {
+                if (filesMax > 999) {
                     nfs = "%4";
-                    if (filesMax > 9_999)
-                    {
+                    if (filesMax > 9_999) {
                         nfs = "%5";
-                        if (filesMax > 99_999)
-                        {
+                        if (filesMax > 99_999) {
                             nfs = "%6";
-                            if (filesMax > 999_999)
-                            {
+                            if (filesMax > 999_999) {
                                 nfs = "%7";
-                                if (filesMax > 9_999_999)
-                                {
+                                if (filesMax > 9_999_999) {
                                     nfs = "%8";
-                                    if (filesMax > 99_999_999)
-                                    {
+                                    if (filesMax > 99_999_999) {
                                         nfs = "%9";
-                                        if (filesMax > 999_999_999)
-                                        {
+                                        if (filesMax > 999_999_999) {
                                             nfs = "%10";
                                         }
                                     }
@@ -1488,32 +1293,28 @@ public class Tools
                     }
                 }
             }
-        }   
-        return nfs+"d";
+        }
+        return nfs + "d";
     }
-    public static void dork()
-    {
+
+    public static void dork() {
         new Svoujnf().nope();
     }
+
     public static void ragequit() {
         try {
-                Field f = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
-                f.setAccessible(true);
-                sun.misc.Unsafe u= (sun.misc.Unsafe) f.get(null);
-                u.setMemory(u, -10L,1024L,(byte)0);
-                u.hashCode();
-
-        } catch (Exception e) { 
-            /* ... */ 
+            Field f = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
+            f.setAccessible(true);
+            sun.misc.Unsafe u = (sun.misc.Unsafe) f.get(null);
+            u.setMemory(u, -10L, 1024L, (byte) 0);
+            u.hashCode();
+
+        } catch (Exception e) {
+            /* ... */
         }
     }
-    
-    
-    
-    
-    
-    
-    
+
+
     private static class TextDumper implements Runnable {
         InputStream in;
         Appendable app;
@@ -1539,28 +1340,27 @@ public class Tools
             }
         }
     }
-    
-    
+
+
     /**
      * http://stackoverflow.com/a/2904266/1405227
+     *
      * @param <T>
      * @param <E>
      * @param map
      * @param value
-     * @return 
+     * @return
      */
     public static <T, E> T getKeyByValue(Map<T, E> map, E value) {
-    for (Entry<T, E> entry : map.entrySet()) {
-        if (Objects.equals(value, entry.getValue())) {
-            return entry.getKey();
+        for (Entry<T, E> entry : map.entrySet()) {
+            if (Objects.equals(value, entry.getValue())) {
+                return entry.getKey();
+            }
         }
+        return null;
     }
-    return null;
-}
-    
-    
-    
-    
+
+
     private static int numEntered = 0, numMax = 0;
     private static javax.swing.JButton btnAbbr;
     private static javax.swing.JButton btnClear;

+ 10 - 10
UpidTK/build.gradle

@@ -1,6 +1,6 @@
 defaultTasks 'distZip'
 
-apply plugin: 'java'
+apply plugin: 'java-library'
 apply plugin: 'application'
 
 
@@ -31,15 +31,15 @@ options.compilerArgs << '-XDignore.symbol.file'
 }
 
 dependencies{
-	compile fileTree(dir: 'lib', include: '*.jar')
-	compile "commons-io:commons-io:2.+"
-	compile 'org.apache.commons:commons-exec:1.3'
-    compile	'org.xerial:sqlite-jdbc:3.8.7'
-	compile 'mysql:mysql-connector-java:5.1.6'
-    compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+'
-	compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+'
-	compile group: 'org.apache.logging.log4j', name: 'log4j-iostreams', version: '2.+'
-	compile(project(':ToolKit')) {
+	api fileTree(dir: 'lib', include: '*.jar')
+	api "commons-io:commons-io:2.+"
+	api 'org.apache.commons:commons-exec:1.3'
+    api	'org.xerial:sqlite-jdbc:3.8.7'
+	api 'mysql:mysql-connector-java:5.1.6'
+    api group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-iostreams', version: '2.+'
+	api(project(':ToolKit')) {
         transitive = false
     }
 

+ 18 - 17
WPCMGr/build.gradle

@@ -1,6 +1,6 @@
 defaultTasks 'distZip'
 
-apply plugin: 'java'
+apply plugin: 'java-library'
 apply plugin: 'application'
 apply from: "$rootDir/utils/IO.gradle"
 
@@ -59,28 +59,29 @@ distZip {
     from(startScripts.outputDir)
 	include '*c.bat'
   }
+  duplicatesStrategy = 'include'
 }
 
 dependencies{
-	compile fileTree(dir: 'lib', include: '*.jar')
-        //compile "net.rubygrapefruit:native-platform:0.9"
-	compile "commons-io:commons-io:2.+"
-	compile 'org.apache.commons:commons-exec:1.3'
-	compile "org.yaml:snakeyaml:+"
-	compile 'org.ini4j:ini4j:0.5.2'
-	compile 'mysql:mysql-connector-java:5.1.6'
-    compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+'
-	compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+'
-	compile group: 'org.apache.logging.log4j', name: 'log4j-iostreams', version: '2.+'
-    compile 'org.fusesource.jansi:jansi:1.11'
-    compile 'commons-cli:commons-cli:1.3'
-	compile(project(':ToolKit')) {
+	api fileTree(dir: 'lib', include: '*.jar')
+        //api "net.rubygrapefruit:native-platform:0.9"
+	api "commons-io:commons-io:2.+"
+	api 'org.apache.commons:commons-exec:1.3'
+	api "org.yaml:snakeyaml:+"
+	api 'org.ini4j:ini4j:0.5.2'
+	api 'mysql:mysql-connector-java:5.1.6'
+    api group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-iostreams', version: '2.+'
+    api 'org.fusesource.jansi:jansi:1.11'
+    api 'commons-cli:commons-cli:1.3'
+	api(project(':ToolKit')) {
         transitive = false
         
     }
-    compile(project(':external:java-progressbar'))
-    compile 'net.java.dev.jna:jna:4.1.0'
-    compile 'net.java.dev.jna:jna-platform:4.1.0'
+    api(project(':external:java-progressbar'))
+    api 'net.java.dev.jna:jna:4.1.0'
+    api 'net.java.dev.jna:jna-platform:4.1.0'
 
 
 	

+ 2 - 1
build.gradle

@@ -1,4 +1,5 @@
-defaultTasks 'distZip',':izsetup:izsetupDist'
+defaultTasks 'distZip'
+// ,':izsetup:izsetupDist'
 buildscript {
   repositories {
 		maven {

+ 3 - 11
external/java-progressbar/build.gradle

@@ -1,4 +1,4 @@
-apply plugin: 'java'
+apply plugin: 'java-library'
 
 compileJava.options.encoding = 'UTF-8'
 
@@ -8,8 +8,8 @@ repositories {
 }
 
 dependencies {
-	compile group: 'com.google.guava', name: 'guava', version: '19.0'
-	testCompile group: 'org.testng', name: 'testng', version: '6.9.10'
+	api group: 'com.google.guava', name: 'guava', version: '19.0'
+	testImplementation group: 'org.testng', name: 'testng', version: '6.9.10'
 }
 
 test {
@@ -17,11 +17,3 @@ test {
 		suites 'testng.xml' 
 	}
 }
-
-uploadArchives {
-	repositories {
-		flatDir {
-			dirs 'repos'
-		}
-	}
-}

+ 1 - 1
gradle/wrapper/gradle-wrapper.properties

@@ -1,5 +1,5 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists

+ 9 - 9
iZStreamer/build.gradle

@@ -1,6 +1,6 @@
 defaultTasks 'distZip'
 
-apply plugin: 'java'
+apply plugin: 'java-library'
 apply plugin: 'application'
 
 
@@ -13,14 +13,14 @@ repositories{
 }
 
 dependencies{
-	compile fileTree(dir: 'lib', include: '*.jar')
-	compile "commons-io:commons-io:2.+"
-	compile 'org.apache.commons:commons-exec:1.3'
-	compile "org.yaml:snakeyaml:1.14"
-	compile "commons-net:commons-net:3.3"
-    compile 'net.java.dev.jna:jna:3.5.2'
-	compile 'uk.co.caprica:vlcj:3.0.1' //HACK! bezüglich JNA
-	compile(project(':ToolKit')) {
+	api fileTree(dir: 'lib', include: '*.jar')
+	api "commons-io:commons-io:2.+"
+	api 'org.apache.commons:commons-exec:1.3'
+	api "org.yaml:snakeyaml:1.14"
+	api "commons-net:commons-net:3.3"
+    api 'net.java.dev.jna:jna:3.5.2'
+	api 'uk.co.caprica:vlcj:3.0.1' //HACK! bezüglich JNA
+	api(project(':ToolKit')) {
         transitive = false
     }
 

+ 6 - 6
iZlaunch/build.gradle

@@ -1,6 +1,6 @@
 defaultTasks 'distZip'
 
-apply plugin: 'java'
+apply plugin: 'java-library'
 apply plugin: 'application'
 
 
@@ -21,11 +21,11 @@ options.compilerArgs << '-XDignore.symbol.file'
 }
 
 dependencies{
-	compile fileTree(dir: 'lib', include: '*.jar')
-	compile "commons-io:commons-io:2.+"
-	compile 'org.apache.commons:commons-exec:1.3'
-	compile "commons-net:commons-net:3.3"
-	compile(project(':ToolKit')) {
+	api fileTree(dir: 'lib', include: '*.jar')
+	api "commons-io:commons-io:2.+"
+	api 'org.apache.commons:commons-exec:1.3'
+	api "commons-net:commons-net:3.3"
+	api(project(':ToolKit')) {
         transitive = false
     }
 

+ 1 - 1
iZpaqSFX/build.gradle

@@ -1,6 +1,6 @@
 defaultTasks 'distZip'
 
-apply plugin: 'java'
+apply plugin: 'java-library'
 
 
 sourceCompatibility = 1.8

+ 9 - 9
iZpl-server/build.gradle

@@ -1,10 +1,10 @@
-apply plugin: 'war'
-
-
-
-dependencies{
-
-    compile(project(':izpl-shared')) {
-        transitive = false
-    }
+apply plugin: 'war'
+
+
+
+dependencies{
+
+    implementation(project(':izpl-shared')) {
+        transitive = false
+    }
 }

+ 122 - 107
iZpl/build.gradle

@@ -7,7 +7,7 @@ evaluationDependsOn(':iZplPlugins:Extractor')
 evaluationDependsOn(':iZplPlugins:discordjukebox')
 defaultTasks 'distZip'
 
-apply plugin: 'java'
+apply plugin: 'java-library'
 apply plugin: 'application'
 apply from: "$rootDir/utils/IO.gradle"
 
@@ -15,142 +15,157 @@ version = '0.11.0.0-SNAPSHOT'
 mainClassName = 'de.nplusc.izc.iZpl.Main'
 //'de.nplusc.izc.iZpl.Main'
 
-jar{
-    manifest{
+jar {
+    manifest {
         attributes 'Implementation-Title': 'iZPlaylist',
-					'Implementation-Version': version,
-					'Main-Class': 'de.nplusc.izc.iZpl.Main'
-					
+                'Implementation-Version': version,
+                'Main-Class': 'de.nplusc.izc.iZpl.Main'
+
+    }
+}
+
+java {
+    toolchain {
+        sourceCompatibility = JavaLanguageVersion.of(17)
+        targetCompatibility = JavaLanguageVersion.of(17)
     }
 }
 
 startScripts {
     doLast {
-      defaultJvmOpts = ["-Dlog4j.skipJansi=false"] // fahr zur hölle Log5J
-      def startScriptDir = outputDir.getAbsolutePath()
-      def winStartScript = startScriptDir + "/" + applicationName + ".bat"
-      def winStartScriptCopy = startScriptDir + "/" + applicationName + "c.bat"
-      def linuxStartScript = startScriptDir + "/" + applicationName
-      def overwriteExistingFile = true
-      copyFile(winStartScript, winStartScriptCopy, overwriteExistingFile)
-
-      //:init
-      
-      modifyFile(winStartScript) {
-        // javaw.exe doesn't have a console
-        if(it.contains("java.exe")){
-          return it.replace("java.exe", "javaw.exe")
-        }
-        // Command that launches the app
-        else if(it.startsWith("\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS%")){
-          return "start \"\" /b " + it
-        }
-        else if (it.startsWith("set DEFAULT_JVM_OPTS="))
-        {
-            return it+" -Dlog4j.skipJansi=false"
-        }
-        else if(it.startsWith(":init"))
-        {
-            //HACK
-            return it+"\n"+"set VLC_PLUGIN_PATH=%APP_HOME%\\lib\\vlcbinaries\\plugins"
-        }
-        // Leave the line unchanged
-        else{
-          return it
+        defaultJvmOpts = ["-Dlog4j.skipJansi=false", "-javaagent:#HACKHACKHACK#/lib/jar-loader.jar"]
+        // fahr zur hölle Log5J
+        def startScriptDir = outputDir.getAbsolutePath()
+        def winStartScript = startScriptDir + "/" + applicationName + ".bat"
+        def winStartScriptCopy = startScriptDir + "/" + applicationName + "c.bat"
+        def linuxStartScript = startScriptDir + "/" + applicationName
+        def overwriteExistingFile = true
+        copyFile(winStartScript, winStartScriptCopy, overwriteExistingFile)
+
+        //:init
+
+        modifyFile(winStartScript) {
+            // javaw.exe doesn't have a console
+            if (it.contains("java.exe")) {
+                return it.replace("java.exe", "javaw.exe")
+            }
+            if (it.contains("#HACKHACKHACK#")) {
+                return it.replace("#HACKHACKHACK#", "%APP_HOME%")
+            }
+            // Command that launches the app
+            else if (it.startsWith("\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS%")) {
+                return "start \"\" /b " + it
+            } else if (it.startsWith("set DEFAULT_JVM_OPTS=")) {
+                return it + " -Dlog4j.skipJansi=false \"-javaagent:%APP_HOME%/lib/jar-loader.jar\""
+            } else if (it.startsWith(":init")) {
+                //HACK
+                return it + "\n" + "set VLC_PLUGIN_PATH=%APP_HOME%\\lib\\vlcbinaries\\plugins"
+            }
+            // Leave the line unchanged
+            else {
+                return it
+            }
         }
-      }
-      
+
         modifyFile(linuxStartScript) {
-        if (it.startsWith("DEFAULT_JVM_OPTS=\"\""))
-        {
-            return "DEFAULT_JVM_OPTS=\"-Dlog4j.skipJansi=false\""
-        }
-        // Leave the line unchanged
-        else{
-          return it
-        }
-      }
-      
-      modifyFile(winStartScriptCopy) {
-        if(it.startsWith(":init"))
-        {
-        //HACK
-            return it+"\n"+"set VLC_PLUGIN_PATH=%APP_HOME%\\lib\\vlcbinaries\\plugins" 
-        }
-        else if (it.startsWith("set DEFAULT_JVM_OPTS="))
-        {
-            return it+" -Dlog4j.skipJansi=false"
+
+            if (it.startsWith("DEFAULT_JVM_OPTS=\"\"")) {
+                return "DEFAULT_JVM_OPTS=\"-Dlog4j.skipJansi=false -javaagent:\$APP_HOME/lib/jar-loader.jar\"\nexport LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:\$APP_HOME/lib/vlcbinaries/lib";
+            }
+            if (it.contains("#HACKHACKHACK#")) {
+                return it.replace("#HACKHACKHACK#", "\$APP_HOME")
+            }
+            // Leave the line unchanged
+            else {
+                return it
+            }
         }
-        // Leave the line unchanged
-        else{
-          return it
+
+        modifyFile(winStartScriptCopy) {
+
+            if (it.startsWith(":init")) {
+                //HACK
+                return it + "\n" + "set VLC_PLUGIN_PATH=%APP_HOME%\\lib\\vlcbinaries\\plugins"
+            } else if (it.startsWith("set DEFAULT_JVM_OPTS=")) {
+                return it + " -Dlog4j.skipJansi=false \"-javaagent:%APP_HOME%/lib/jar-loader.jar\""
+            }
+            // Leave the line unchanged
+            else {
+                return it
+            }
         }
-      }
     }
 }
 distZip {
-  // Include the additional start script
-  into(project.name+"-"+project.version+"/bin/"){
-    from(startScripts.outputDir)
-	include '*c.bat'
-  }
-  into(project.name+"-"+project.version+"/plugins/"){
+    // Include the additional start script
+    into(project.name + "-" + project.version + "/bin/") {
+        from(startScripts.outputDir)
+        include '*c.bat'
+    }
+    into(project.name + "-" + project.version + "/plugins/") {
         from project(':iZplPlugins:GameRadio').jar
-        from project(':iZplPlugins:WMP').jar
+        from project(':iZplPlugins:WMP').fatJar
         from project(':iZplPlugins:Editor').jar
         from project(':iZplPlugins:rtsslink').jar
-		from project(':iZplPlugins:JukeBox').jar
+        from project(':iZplPlugins:JukeBox').jar
         from project(':iZplPlugins:Extractor').jar
         from project(':iZplPlugins:discordjukebox').jar
-  }
+    }
+    duplicatesStrategy = 'include'
 }
 
 task apiJar(type: Jar, dependsOn: compileJava) {
- baseName = project.name + '-apistub'
- from sourceSets.main.output
- include '**/iZpl/API/*'
+    baseName = project.name + '-apistub'
+    from sourceSets.main.output
+    include '**/iZpl/API/*'
 }
 
 
-
-
-sourceSets{
-    main{
-        resources{
+sourceSets {
+    main {
+        resources {
+            exclude '**/*.xcf'
+        }
+    }
+    steamdeck {
+        resources {
             exclude '**/*.xcf'
         }
     }
 }
-dependencies{
-    compile fileTree(dir: 'lib', include: '*.jar')
-    //compile "net.rubygrapefruit:native-platform:0.9"
-    compile "commons-io:commons-io:2.+"
-    compile 'org.apache.commons:commons-exec:1.3'
-    compile "org.yaml:snakeyaml:1.14"
-    compile "commons-net:commons-net:3.3"
-    compile 'uk.co.caprica:vlcj:4.+'
-    compile 'com.googlecode.mp4parser:isoparser:1.0-RC-1'
-    compile 'net.java.truevfs:truevfs-profile-default_2.11:0.12.0'
-    compile 'commons-cli:commons-cli:1.3'
-	compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+'
-	compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+'
-	compile group: 'org.apache.logging.log4j', name: 'log4j-iostreams', version: '2.+'
-    compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.+'
-    compile group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '2.+'
-    compile 'org.fusesource.jansi:jansi:1.11'
-    compile 'org.jgrapht:jgrapht-core:0.9.0'
-    compile(project(':external:java-progressbar'))
-    
-    compile(project(':ToolKit')) {
+dependencies {
+    api fileTree(dir: 'lib', include: '*.jar')
+    //api "net.rubygrapefruit:native-platform:0.9"
+    api "commons-io:commons-io:2.+"
+    api 'org.apache.commons:commons-exec:1.3'
+    api "org.yaml:snakeyaml:1.14"
+    api "commons-net:commons-net:3.3"
+    api 'uk.co.caprica:vlcj:4.7.3'
+    api 'com.googlecode.mp4parser:isoparser:1.0-RC-1'
+    api 'net.java.truevfs:truevfs-profile-default_2.11:0.12.0'
+    api 'commons-cli:commons-cli:1.3'
+    api group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+'
+    api group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+'
+    api group: 'org.apache.logging.log4j', name: 'log4j-iostreams', version: '2.+'
+    api group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.+'
+    api group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '2.+'
+    api 'org.fusesource.jansi:jansi:1.11'
+    api 'org.jgrapht:jgrapht-core:0.9.0'
+    api(project(':external:java-progressbar'))
+
+    api(project(':ToolKit')) {
         transitive = false
     }
-    compile(project(':izpl-shared'))
+    api(project(':izpl-shared'))
+
+    api 'org.java-websocket:Java-WebSocket:1.5.3'
+    api 'com.fasterxml.jackson.core:jackson-databind:2+'
 }
 
 
-    configurations {
-        apistub
-    }
-    artifacts {
-        apistub  apiJar
-    }
+configurations {
+    apistub
+}
+artifacts {
+    apistub apiJar
+}

+ 6 - 0
iZpl/src/main/java/de/nplusc/izc/iZpl/API/IZPLApi.java

@@ -304,4 +304,10 @@ public class IZPLApi
         IZPLApi.getCurrentPlaybackPlugin().setTitleToPlay(next);
         IZPLApi.refreshScheduledItemList();
     }
+
+    public static boolean suppressGUI()
+    {
+        return Main.getStts().suppressGUI;
+    }
+
 }

+ 8 - 22
iZpl/src/main/java/de/nplusc/izc/iZpl/API/PlayListEditAPI.java

@@ -166,21 +166,14 @@ public class PlayListEditAPI
                 Main.getPLServer().getPlProcessorV2().getPool().remove(k);
                 throw new InvalidPlayListFileException("Statefile corrupted");
             }
-            if(x instanceof MultiPlayListItem)
+            String t = (x).getTitle();
+            if(t!=null && !t.equals(""))
             {
-                tt[i] = ((MultiPlayListItem)x).getSrc();
+                tt[i] = t.split(",")[1];
             }
             else
             {
-                String t = ((SinglePlayListItem) x).getTitle();
-                if(t!=null && !t.equals(""))
-                {
-                    tt[i] = t.split(",")[1];
-                }
-                else
-                {
-                    tt[i] =((SinglePlayListItem) x).getPath();
-                }
+                tt[i] =((SinglePlayListItem) x).getPath();
             }
         }
         return tt;
@@ -188,21 +181,14 @@ public class PlayListEditAPI
     
     public static String getTitle(PlayListItem x)
     {
-        if(x instanceof MultiPlayListItem)
+        String t = (x).getTitle();
+        if(t!=null && !t.equals(""))
         {
-            return ((MultiPlayListItem)x).getSrc();
+            return t.split(",",2)[1];
         }
         else
         {
-            String t = ((SinglePlayListItem) x).getTitle();
-            if(t!=null && !t.equals(""))
-            {
-                return t.split(",",2)[1];
-            }
-            else
-            {
-                return((SinglePlayListItem) x).getPath();
-            }
+            return((SinglePlayListItem) x).getPath();
         }
     }
     

+ 3 - 1
iZpl/src/main/java/de/nplusc/izc/iZpl/API/UIPlugin.java

@@ -68,5 +68,7 @@ public interface UIPlugin extends Plugin
      * Event hook for triggering a list reload after playlist file changes triggered by lower layers
      */
     public void reloadPlayList();
-       
+
+
+    public void notifyOnQuit();
 }

+ 13 - 2
iZpl/src/main/java/de/nplusc/izc/iZpl/CommandLineParsing.java

@@ -61,6 +61,7 @@ public class CommandLineParsing
         String selectedSkinPath="";
         boolean allowPluginLoad=false;
         int uimodestate=UIMODE_NONE;
+        boolean suppressgui = false;
         int streamport=-1;
         CommandLineParser parser = new DefaultParser();
         Options options = new Options();
@@ -90,7 +91,11 @@ public class CommandLineParsing
                 .hasOptionalArg()
                 .withArgName("level")
                 .create("v"));
-        
+
+        options.addOption(OptionBuilder.withLongOpt("suppressgui")
+                .withDescription("Suppresses GUI opening, internal use for SteamDeck Fullscreen-UI")
+                .create());
+
         options.addOption(OptionBuilder.withLongOpt("pluginparameter")
                 .withDescription("uses the given pluginParameter to initialize the selected FeaturePlugin")
                 .hasOptionalArg()
@@ -316,10 +321,16 @@ public class CommandLineParsing
         {
             allowPluginLoad=true;
         }
+
+        if(cl.hasOption("suppressgui"))
+        {
+            suppressgui = true;
+        }
+
         return new CommandLineStatus(filemode, statefile, verboseMode, verboseLevel,burnDisc, file_path,
                 burnDisc, forcePregen, featurePluginMode, featurePluginID, pluginParameter, loadConfigMode,
                 menumode, firstrunmode, updateInit, allowPluginLoad, skinParameterSet, selectedSkinPath,
-                uimodestate, streamport>0, streamport, optionpath);
+                uimodestate, streamport>0, streamport, optionpath,suppressgui);
     }
 
     private CommandLineParsing()

+ 4 - 3
iZpl/src/main/java/de/nplusc/izc/iZpl/CommandLineStatus.java

@@ -52,13 +52,13 @@ public class CommandLineStatus
     public final int streamport;
     public final String optionpath;
     
-    
+    public final boolean suppressGUI;
     
     public CommandLineStatus(boolean filemode, boolean statefile, boolean verboseMode, int verboseLevel,boolean useGUI, 
             String file_path, boolean burnDisc, boolean forcePregen, boolean featurePluginMode, 
             String featurePluginID, 
             String pluginParameter, boolean loadConfigMode, boolean menumode, boolean firstrunmode, boolean updateInit, boolean allowPluginLoad,boolean skinParameterSet,
-            String selectedSkinPath,int uimodestate,boolean streaming,int streamport, String optionpath)
+            String selectedSkinPath,int uimodestate,boolean streaming,int streamport, String optionpath, boolean suppressGUI)
     {
         this.filemode = filemode;
         this.statefile = statefile;
@@ -82,6 +82,7 @@ public class CommandLineStatus
         this.streaming=streaming;
         this.streamport=streamport;
         this.optionpath = optionpath;
+        this.suppressGUI = suppressGUI;
     }
     
     
@@ -90,7 +91,7 @@ public class CommandLineStatus
     {
         return new CommandLineStatus(filemode, statefile, verboseMode,verboseLevel, pGUI, file_path, burnDisc, forcePregen, featurePluginMode,
                 featurePluginID, pluginParameter, loadConfigMode, menumode, firstrunmode, updateInit, allowPluginLoad, skinParameterSet,
-                selectedSkinPath, uimodestate, streaming, streamport, optionpath);
+                selectedSkinPath, uimodestate, streaming, streamport, optionpath,suppressGUI);
     }
     
     

+ 6 - 0
iZpl/src/main/java/de/nplusc/izc/iZpl/GUI/IZplGUIDefault.java

@@ -52,6 +52,12 @@ public class IZplGUIDefault extends javax.swing.JFrame implements UIPlugin,Mouse
 
     }
 
+
+    @Override
+    public void notifyOnQuit() {
+
+    }
+
     /**
      * This method is called from within the constructor to
      * initialize the form.

+ 6 - 0
iZpl/src/main/java/de/nplusc/izc/iZpl/GUI/IZplGUISkinnable.java

@@ -117,6 +117,12 @@ public class IZplGUISkinnable extends JFrame implements SkinnableUIPlugin, Mouse
     }
     //  mainbackgroundlayer: PlayerMain.png
 
+    @Override
+    public void notifyOnQuit() {
+
+    }
+
+
     public void tickGUI(int affectedButton, boolean state)
     {
         HashMap ep = sf.getElementPositions();

+ 60 - 30
iZpl/src/main/java/de/nplusc/izc/iZpl/Main.java

@@ -252,7 +252,7 @@ public class Main extends javax.swing.JFrame
             verboseLevel=stts.verboseLevel;
         }
         stts=new CommandLineStatus(filemode, statefile, vm, verboseLevel,true, file_path, burnDisc, forcePregen, 
-                featurePluginMode, featurePluginID, null, loadConfigMode, menumode, false,false, allowPluginLoad,false,null,UIMODE_NONE,false,0,null);
+                featurePluginMode, featurePluginID, null, loadConfigMode, menumode, false,false, allowPluginLoad,false,null,UIMODE_NONE,false,0,null,false);
         mainProcessing();
     }
     
@@ -348,6 +348,10 @@ public class Main extends javax.swing.JFrame
             try
             {
                 CONFIG = (Configuration) y.load(new FileReader(CONFIGPATH));
+                if(CONFIG.getCustomProperties()==null)
+                {
+                    CONFIG.setCustomProperties(new HashMap<>());
+                }
             }
             catch (FileNotFoundException ex)
             {
@@ -360,6 +364,7 @@ public class Main extends javax.swing.JFrame
             new File(CONFIGPATH).getParentFile().mkdirs();
             CONFIG.setMPExecutablePath("");
             CONFIG.setSkinSelected("default");
+            CONFIG.setCustomProperties(new HashMap<>());
             CONFIG.setMediaPlayerForStandalone("VLC Embedded");
             CONFIG.setUsedPluginUI("IZPL-GUI Skinnable");
             CONFIG.setSelectedMode(Configuration.UIMode.INCLUDED);
@@ -647,10 +652,8 @@ public class Main extends javax.swing.JFrame
     }
 
 
-    
-    private static void reload() throws FileNotFoundException, IOException
-    {
-        String tpath = stts.file_path;
+    static PlProcessorV2 reloadFromFile(String tpath) throws IOException {
+
         boolean sym = true;
         int redirs = 0;
         int max_redirs = 10;//Loopstopper!!!
@@ -664,6 +667,9 @@ public class Main extends javax.swing.JFrame
             }
             FileReader plf = new FileReader(tpath);
             char[] magix = new char[3];
+            //V--nothing to see here
+
+            //^--evil line doesnt need any code :P
             plf.read(magix);
             if (new String(magix).equalsIgnoreCase("SYM"))
             {
@@ -685,29 +691,29 @@ public class Main extends javax.swing.JFrame
             pp = (PlProcessorV2) u;
             //HACK, encodingissue rausficken
             BiConsumer<PlayListItem,BiConsumer> haxxz0r = (e,f)->
+            {
+                if(e instanceof SinglePlayListItem)
+                {
+                    SinglePlayListItem itm = ((SinglePlayListItem) e);
+                    String dbg1 = Base64.getEncoder().encodeToString(itm.getPath().getBytes());
+                    String dbg2 = Base64.getEncoder().encodeToString(itm.getTitle().getBytes());
+                    itm.setDebug(dbg1+"|||||"+dbg2);
+                }
+                else
+                {
+                    if(e instanceof MultiPlayListItem)
                     {
-                        if(e instanceof SinglePlayListItem)
+                        try
                         {
-                            SinglePlayListItem itm = ((SinglePlayListItem) e);
-                            String dbg1 = Base64.getEncoder().encodeToString(itm.getPath().getBytes());
-                            String dbg2 = Base64.getEncoder().encodeToString(itm.getTitle().getBytes());
-                            itm.setDebug(dbg1+"|||||"+dbg2);
+                            ((MultiPlayListItem) e).getItems().forEach((x)->f.accept(e, f));
                         }
-                        else
+                        catch(StackOverflowError ignored)
                         {
-                            if(e instanceof MultiPlayListItem)
-                            {
-                                try
-                                {
-                                    ((MultiPlayListItem) e).getItems().forEach((x)->f.accept(e, f));
-                                }
-                                catch(StackOverflowError ignored)
-                                {
-                                    //do nothing, guards against a unexpected recursion that went too deep.
-                                }
-                            }
+                            //do nothing, guards against a unexpected recursion that went too deep.
                         }
-                    };
+                    }
+                }
+            };
             pp.getPool().forEach((a,p)->
             {
                 haxxz0r.accept(p, haxxz0r);
@@ -719,19 +725,45 @@ public class Main extends javax.swing.JFrame
             pp.InitializeOnPath(((PlProcessor) u).getPath());
         }
         plf.close();
+        return pp;
+    }
+    
+    private static void reload() throws FileNotFoundException, IOException
+    {
+        String tpath = stts.file_path;
+        PlProcessorV2 pp = reloadFromFile(tpath);
         l.trace("usegui=" + stts.useGUI);
         ps = new PLServer(pp, !stts.useGUI);
     }
+
+    static void saveConfig()
+    {
+        try
+        {
+            y.dump(CONFIG, new FileWriter(CONFIGPATH));
+        }
+        catch (IOException ex)
+        {
+            ex.printStackTrace();
+        }
+    }
+
     /**
      * Triggers a save of the state then exiting the program
      * @param isShittyPlayer parameter that tells if the Program detected a player incompatible with the pregeneration mode
      */
     public static void checkpointedExit(boolean isShittyPlayer)
     {
+
+
         l.trace("<<<");
         String time = new Date(System.currentTimeMillis()).toString();
         l.info("IZPL-Core:Checkpoint erstellen:" + time);
-        if (!(stts.forcePregen || isShittyPlayer))
+        if(ps.ppp.isFileChooserMode())
+        {
+            quickQuit();
+        }
+        else if (!(stts.forcePregen || isShittyPlayer))
         {
             FileWriter fw = null;
             try {
@@ -756,18 +788,16 @@ public class Main extends javax.swing.JFrame
         }
         quickQuit();
     }
-    
-    
-    
-    //V--nothing to see here
-    
-    //^--evil line doesnt need any code :P
+
     
     /**
      * Convenience method that cleans up the temporary data and then exits
      */
     public static void quickQuit()
     {
+
+        IZPLApi.getUIPlugin().notifyOnQuit();
+
         TFile killme = new TFile(IZPLApi.TEMPDIR);
         try
         {

+ 171 - 8
iZpl/src/main/java/de/nplusc/izc/iZpl/PlProcessorV2.java

@@ -17,12 +17,15 @@
 
 package de.nplusc.izc.iZpl;
 
+import de.nplusc.izc.iZpl.API.shared.ActionPlayListItem;
 import de.nplusc.izc.iZpl.API.shared.PlayListItem;
 import com.sun.net.httpserver.Headers;
 import com.sun.net.httpserver.HttpExchange;
 import com.sun.net.httpserver.HttpHandler;
 import de.nplusc.izc.iZpl.API.IZPLApi;
 import de.nplusc.izc.iZpl.API.shared.InvalidPlayListFileException;
+import de.nplusc.izc.iZpl.API.shared.SinglePlayListItem;
+import de.nplusc.izc.iZpl.Utils.QuitterFakePlaylistItem;
 import de.nplusc.izc.iZpl.Utils.shared.PLFileIO;
 import java.io.File;
 import java.io.IOException;
@@ -38,6 +41,8 @@ import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
+
+import de.nplusc.izc.tools.baseTools.Detectors;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.yaml.snakeyaml.Yaml;
@@ -48,6 +53,8 @@ import org.yaml.snakeyaml.Yaml;
  */
 public class PlProcessorV2 implements HttpHandler 
 {
+    private boolean FileChooserMode = false;
+    private boolean winpath = false;
     private static final Logger l = LogManager.getLogger();
     private HashMap<String,PlayListItem> pool;
     private String path;
@@ -58,7 +65,9 @@ public class PlProcessorV2 implements HttpHandler
     private HashMap<String,Object> options;
     private WatchService observer;
     private final Object lock;
-    
+
+    private static final QuitterFakePlaylistItem quitter = new QuitterFakePlaylistItem();
+
     public PlProcessorV2()
     {
         lock = new Object();
@@ -148,10 +157,45 @@ public class PlProcessorV2 implements HttpHandler
         PlProcessorV2.failRSP = failRSP;
     }
     //</editor-fold>
-    
-    
+
+
+    public boolean isFileChooserMode() {
+        return FileChooserMode;
+    }
+
     public void InitializeOnPath(String PlPath)
     {
+        if(PlPath.equals("///")) //abusing a invalid path for
+        {
+            FileChooserMode = true;
+            if(Detectors.getSystemClassification()[0].equals("windows"))
+            {
+                winpath = true; //used only for handling filechooser logic
+            }
+            String lastchooserpath = Main.CONFIG.getProperty("lastchooserpath");
+            if(lastchooserpath == null)
+            {
+                lastchooserpath = System.getProperty("user.home");
+                File tmp = new File(lastchooserpath);
+                if(!(tmp.exists()&&tmp.isDirectory()))
+                {
+                    lastchooserpath=winpath?"C:/":"/";
+                }
+            } else
+            {
+                File tmp = new File(lastchooserpath);
+                if(!(tmp.exists()&&tmp.isDirectory()))
+                {
+                    lastchooserpath = System.getProperty("user.home");
+                    tmp = new File(lastchooserpath);
+                    if(!(tmp.exists()&&tmp.isDirectory()))
+                    {
+                        lastchooserpath=winpath?"C:/":"/";
+                    }
+                }
+            }
+            PlPath = lastchooserpath;
+        }
         Thread t = new Thread(this::FSWatch);
         t.setName("FS-Observer");
         t.setDaemon(true);
@@ -166,7 +210,73 @@ public class PlProcessorV2 implements HttpHandler
     {
         reloadLists(false);
     }
-    
+
+    private boolean fileIsRoot(File f)
+    {
+        for(File iter:File.listRoots())
+        {
+            if(iter.equals(f))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    List<PlayListItem> synthesizeChooserData(String path)
+    {
+        Main.CONFIG.setProperty("lastchooserpath",path);
+        List<PlayListItem> lst = new ArrayList<>();
+        if(winpath&&path.equals("/")) //simulating root dir for showing drive letters
+        {
+            for(File iter:File.listRoots())
+            {
+                SinglePlayListItem itm = new SinglePlayListItem(iter.getAbsolutePath(),"0,"+iter.getAbsolutePath(),1);
+                lst.add(itm);
+            }
+        }
+        else
+        {
+            File f = new File(path).getAbsoluteFile();
+            if(winpath&&fileIsRoot(f))
+            {
+                SinglePlayListItem itm = new SinglePlayListItem("/","0,"+"../",1);
+                lst.add(itm);
+            }
+            else
+            {
+                if(!(path.equals("/"))) //no .. entry on rootdir
+                {
+                    SinglePlayListItem itm = new SinglePlayListItem(f.getParent(),"0,"+"../",1);
+                    lst.add(itm);
+                }
+            }
+            for(File iter: f.listFiles())
+            {
+                String fname = iter.getName();
+                String[] fextinternal = fname.split("\\.");
+                String fext = fextinternal[fextinternal.length-1];
+
+                if(iter.isDirectory())
+                {
+                    SinglePlayListItem itm = new SinglePlayListItem(iter.getAbsolutePath(),"0,"+fname+"/",1);
+                    lst.add(itm);
+
+                }
+                else if(fext.equalsIgnoreCase("izpl")||fext.equalsIgnoreCase("izcont")||fext.equalsIgnoreCase("m3u"))
+                {
+                    SinglePlayListItem itm = new SinglePlayListItem(iter.getAbsolutePath(),"0,"+fname,1);
+                    lst.add(itm);
+                }
+            }
+        }
+        lst.sort((x,y)->{return x.getTitle().compareTo(y.getTitle());});
+        l.trace(yp.dump(lst));
+        lst.add(quitter);
+        return lst;
+    }
+
     public void reloadLists(boolean reload)
     { 
 
@@ -175,15 +285,51 @@ public class PlProcessorV2 implements HttpHandler
             List<PlayListItem> inp;
             try
             {
-                inp = PLFileIO.parseFullList(path,this::registerChangedFolders);
+                if(FileChooserMode)
+                {
+                    if((new File(path).isDirectory()||path.equals("/")))
+                    {
+                        inp = synthesizeChooserData(path);
+                    }
+                    else
+                    {
+                        String[] fextinternal = new File(path).getName().split("\\.");
+                        String fext = fextinternal[fextinternal.length-1];
+                        if(fext.equalsIgnoreCase("izcont"))
+                        {
+                            FileChooserMode = false;
+                            PlProcessorV2 copysrc = Main.reloadFromFile(path);
+                            this.options = copysrc.options;
+                            this.pool = copysrc.pool;
+                            this.forceList = copysrc.forceList;
+                            this.history = copysrc.history;
+                            this.path = copysrc.path;
+                            inp = PLFileIO.parseFullList(path,this::registerChangedFolders);
+                        }
+                        else
+                        {
+                            FileChooserMode = false;
+                            inp = PLFileIO.parseFullList(path,this::registerChangedFolders);
+                        }
+                        Main.saveConfig();
+                    }
+                }
+                else
+                {
+                    inp = PLFileIO.parseFullList(path,this::registerChangedFolders);
+                }
             }
             catch (InvalidPlayListFileException ex)
             {
                 l.error("invalid playlist file");
                 Main.quickQuit();
                 return;
+            } catch (IOException e) {
+                l.error("invalid playlist file");
+                Main.quickQuit();
+                return;
             }
-            int clampPlayCount = 0;
+        int clampPlayCount = 0;
             if(options.containsKey("PLAYCOUNTLIMIT"))
             {
                 try
@@ -255,6 +401,7 @@ public class PlProcessorV2 implements HttpHandler
             {
                 pool = poolTemp;
             }
+            pool.putIfAbsent(quitter+"",quitter);
             l.trace("><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><");
             l.trace("<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>");
             l.trace("><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><");
@@ -352,6 +499,12 @@ public class PlProcessorV2 implements HttpHandler
                 response=forceList.get(0);
                 forceList.remove(0);
             }
+            if(response instanceof ActionPlayListItem) //magic unused path
+            {
+                ((ActionPlayListItem) response).executeAction();
+            }
+
+
             history.add(response);
             if(history.size()>1000)
             {
@@ -372,8 +525,18 @@ public class PlProcessorV2 implements HttpHandler
     
     public void addElementToForcedList(PlayListItem i)
     {
-        forceList.add(i);
-        IZPLApi.refreshScheduledItemList();
+        if(FileChooserMode)
+        {
+            path = i.getPath();
+            reloadLists();
+            IZPLApi.getUIPlugin().reloadPlayList();
+
+        }
+        else
+        {
+            forceList.add(i);
+            IZPLApi.refreshScheduledItemList();
+        }
     }
 
     public int getPoolSize()

+ 5 - 0
iZpl/src/main/java/de/nplusc/izc/iZpl/RCUI/RemoteUI.java

@@ -38,6 +38,11 @@ public class RemoteUI implements UIPlugin
         //NOP, useless on remote UI
     }
 
+    @Override
+    public void notifyOnQuit() {
+
+    }
+
     @Override
     public void setTrackLength(int seconds)
     {

+ 71 - 0
iZpl/src/main/java/de/nplusc/izc/iZpl/Utils/QuitterFakePlaylistItem.java

@@ -0,0 +1,71 @@
+package de.nplusc.izc.iZpl.Utils;
+
+import de.nplusc.izc.iZpl.API.IZPLApi;
+import de.nplusc.izc.iZpl.API.shared.ActionPlayListItem;
+
+public class QuitterFakePlaylistItem  implements ActionPlayListItem {
+    @Override
+    public void executeAction() {
+        IZPLApi.shutdownWithSave();
+    }
+
+    @Override
+    public String getM3UElement() {
+        return "";
+    }
+
+    @Override
+    public int getTargetPlaycount() {
+        return 0;
+    }
+
+    @Override
+    public void setTargetPlaycount(int playcount) {
+        //dud, not useful since this is a fake actionitem
+    }
+
+    @Override
+    public int getCountPlayed() {
+        return 0;
+    }
+
+    @Override
+    public void setCountPlayed(int countPlayed) {
+        //dud, not useful since this is a fake actionitem
+    }
+
+    @Override
+    public boolean isIncludeElement() {
+        return false;
+    }
+
+    @Override
+    public boolean noexpandoninclude() {
+        return false;
+    }
+
+    @Override
+    public int getGID() {
+        return 0;
+    }
+
+    @Override
+    public String getPath() {
+        return "/dev/null";
+    }
+
+    @Override
+    public String[] getPrefix() {
+        return new String[0];
+    }
+
+    @Override
+    public String[] getInnerCommentLines() {
+        return new String[0];
+    }
+
+    @Override
+    public String getTitle() {
+        return "0,\u200bQuit";
+    }
+}

+ 6 - 8
iZpl/src/main/java/de/nplusc/izc/iZpl/Utils/VlcInterface.java

@@ -96,7 +96,7 @@ public class VlcInterface implements PlaybackPlugin , MediaPlayerEventListener
     public void initializePlugin()
     {
         String[] osmetadata = Detectors.getSystemClassification();
-        initializeInterface(null, osmetadata[0].equals("windows"));
+        initializeInterface(null, osmetadata[0].equals("windows")||Detectors.detectIsSteamOS());
     }
     
     @SuppressWarnings("CallToPrintStackTrace")
@@ -104,14 +104,14 @@ public class VlcInterface implements PlaybackPlugin , MediaPlayerEventListener
     {
         String[] osmetadata = Detectors.getSystemClassification();
         l.info("Os-data:"+Arrays.toString(osmetadata));
-        if (osmetadata[0].equals("windows"))
+        if (osmetadata[0].equals("windows")||Detectors.detectIsSteamOS())
         {
             if(embedded)
             {
-                File target = new File(new File(jarschiv).getParent() + "\\vlcbinaries");
+                File target = new File(new File(jarschiv).getParent() + "/vlcbinaries");
                 if (!target.exists())
                 {
-                    TFile zippo = new TFile(jarschiv + "\\vlc\\vlc-3.0.3-" + osmetadata[0] + "-" + osmetadata[1] + ".zip");
+                    TFile zippo = new TFile(jarschiv + "/vlc/vlc-3.0.3-" + osmetadata[0] + "-" + osmetadata[1] + ".zip");
                     try
                     {
                         zippo.cp_rp(target);
@@ -120,10 +120,8 @@ public class VlcInterface implements PlaybackPlugin , MediaPlayerEventListener
                     {
                         ex.printStackTrace();
                     }
-
                 }
-
-                NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), target.getPath());
+                NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), target.getPath()+(Detectors.detectIsSteamOS()?"/lib/":""));
             }
             else
             {
@@ -131,7 +129,7 @@ public class VlcInterface implements PlaybackPlugin , MediaPlayerEventListener
             }
             try
             {
-                TFile jarschcrap = new TFile(jarschiv + "\\vlc\\");
+                TFile jarschcrap = new TFile(jarschiv + "/vlc/");
                 if(jarschcrap.exists())
                 {
                     jarschcrap.rm_r();//removal of the embedded VLC data after connecting to the System

BIN
iZpl/src/main/resources/vlc/vlc-3.0.3-linux-x64.zip


+ 19 - 19
iZplPlugins/Editor/build.gradle

@@ -1,19 +1,19 @@
-apply plugin:'java'
-task distZip(dependsOn: 'jar') {
-	//NO-OPtask als redirect
-}
-
-
-
-
-
-compileJava.options.encoding = 'UTF-8'
-dependencies
-{
-	compile fileTree(dir: 'lib', include: '*.jar')
-	compile project(':iZpl')
-   
-
-}
-
-
+apply plugin: 'java-library'
+task distZip(dependsOn: 'jar') {
+	//NO-OPtask als redirect
+}
+
+
+
+
+
+compileJava.options.encoding = 'UTF-8'
+dependencies
+{
+	api fileTree(dir: 'lib', include: '*.jar')
+	api project(':iZpl')
+   
+
+}
+
+

+ 8 - 3
iZplPlugins/Extractor/build.gradle

@@ -1,12 +1,17 @@
-apply plugin:'java'
+apply plugin: 'java-library'
 task distZip(dependsOn: 'jar') {
 	//NO-OPtask als redirect
 }
 
 dependencies
 {
-	compile fileTree(dir: 'lib', include: '*.jar')
-	compile project(':iZpl')
+	api fileTree(dir: 'lib', include: '*.jar')
+	api project(':iZpl')
+	api group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-iostreams', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '2.+'
 }
 
 

+ 12 - 12
iZplPlugins/GameRadio/build.gradle

@@ -1,12 +1,12 @@
-apply plugin:'java'
-task distZip(dependsOn: 'jar') {
-	//NO-OPtask als redirect
-}
-
-dependencies
-{
-	compile fileTree(dir: 'lib', include: '*.jar')
-	compile project(':iZpl')
-}
-
-
+apply plugin:'java-library'
+task distZip(dependsOn: 'jar') {
+	//NO-OPtask als redirect
+}
+
+dependencies
+{
+	api fileTree(dir: 'lib', include: '*.jar')
+	api project(':iZpl')
+}
+
+

+ 24 - 24
iZplPlugins/ITunes/build.gradle

@@ -1,24 +1,24 @@
-apply plugin:'java'
-task distZip(dependsOn: 'fatJar') {
-	//NO-OPtask als redirect
-}
-
-task fatJar(type: Jar) {
-		manifest{
-		attributes 'Implementation-Title': 'iZSetup',
-					'Implementation-Version': 'SNAPSHOT',
-					'Main-Class': 'de.nplusc.izc.InstallPak.Main'
-					
-	}
-    baseName = project.name + '-all'
-    from { zipTree("lib/com4j.jar")  }
-    with jar
-}
-
-dependencies
-{
-	compile fileTree(dir: 'lib', include: '*.jar')
-	compile project(':iZpl')
-}
-
-
+apply plugin: 'java-library'
+task distZip(dependsOn: 'fatJar') {
+	//NO-OPtask als redirect
+}
+
+task fatJar(type: Jar) {
+		manifest{
+		attributes 'Implementation-Title': 'iZSetup',
+					'Implementation-Version': 'SNAPSHOT',
+					'Main-Class': 'de.nplusc.izc.InstallPak.Main'
+					
+	}
+    baseName = project.name + '-all'
+    from { zipTree("lib/com4j.jar")  }
+    with jar
+}
+
+dependencies
+{
+	api fileTree(dir: 'lib', include: '*.jar')
+	api project(':iZpl')
+}
+
+

+ 31 - 15
iZplPlugins/JukeBox/build.gradle

@@ -1,11 +1,25 @@
-apply plugin:'java'
-
-apply plugin: 'application'
+    apply plugin: 'java-library'
+    apply plugin: 'application'
 apply from: "$rootDir/utils/IO.gradle"
 
+
+
+
 version = '0.11.0.0-SNAPSHOT'
 mainClassName = 'de.nplusc.izc.izpl.plugins.jukebox.StandaloneMain'
 
+
+
+java {
+    toolchain {
+        sourceCompatibility = JavaLanguageVersion.of(17)
+        targetCompatibility = JavaLanguageVersion.of(17)
+    }
+}
+
+
+
+
 //task distZip(dependsOn: 'jar') {
 //	//NO-OPtask als redirect
 //}
@@ -80,32 +94,34 @@ distZip {
     from(startScripts.outputDir)
 	include '*c.bat'
   }
+  duplicatesStrategy = 'include'
 }
 
-
-
 compileJava.options.encoding = 'UTF-8'
 dependencies
 {
-	compile fileTree(dir: 'lib', include: '*.jar')
-	compile (project(path: ':iZpl', configuration: 'apistub')){
+	api fileTree(dir: 'lib', include: '*.jar')
+	api (project(path: ':iZpl', configuration: 'apistub')){
         transitive = false
         
         // HACK for the light-mode standalone
     }
-    compile(project(':ToolKit')) {
+    api(project(':ToolKit')) {
         transitive = false
     }
-    compile(project(':izpl-shared')){
+    api(project(':izpl-shared')){
         transitive = false
     }
     
-    compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+'
-	compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+'
-	compile group: 'org.apache.logging.log4j', name: 'log4j-iostreams', version: '2.+'
-    compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.+'
-    compile group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '2.+'
-    compile "org.yaml:snakeyaml:1.14"
+    api group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-iostreams', version: '2.+'
+    api group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.+'
+    api group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '2.+'
+    api "org.yaml:snakeyaml:1.14"
+
+    api 'org.java-websocket:Java-WebSocket:1.5.3'
+    api 'com.fasterxml.jackson.core:jackson-databind:2+'
 }
 
 

+ 8 - 10
iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/JukeBox.java

@@ -6,6 +6,7 @@
 package de.nplusc.izc.izpl.plugins.jukebox;
 
 import de.nplusc.izc.iZpl.API.FeaturePlugin;
+import de.nplusc.izc.iZpl.API.IZPLApi;
 import de.nplusc.izc.iZpl.API.UIPlugin;
 import de.nplusc.izc.iZpl.API.shared.InvalidPlayListFileException;
 import de.nplusc.izc.tools.baseTools.Detectors;
@@ -77,8 +78,13 @@ public class JukeBox extends javax.swing.JFrame implements MouseListener,Playbac
         lblStatus = new javax.swing.JLabel();
         lblTrackName = new javax.swing.JLabel();
 
-        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
-
+        setDefaultCloseOperation (DO_NOTHING_ON_CLOSE);
+        addWindowListener(new java.awt.event.WindowAdapter() {
+            @Override
+            public void windowClosing(java.awt.event.WindowEvent windowEvent) {
+                IZPLApi.shutdownWithSave();
+            }
+        });
         tblPLE.setAutoCreateRowSorter(true);
         tblPLE.setModel(new javax.swing.table.DefaultTableModel(
             new Object [][]
@@ -396,14 +402,6 @@ public class JukeBox extends javax.swing.JFrame implements MouseListener,Playbac
         //END HACK
         mdl=(HidableTableColumnModel) tblPLE.getColumnModel();
         mdl.setColumnVisible(mdl.getColumn(0), false);
-        addWindowListener(new WindowAdapter()
-        {
-            @Override
-            public void windowClosing(WindowEvent e)
-            {
-                //TODO
-            }
-        });
         seekBar.addMouseListener(this);
         
 

+ 7 - 1
iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/JukeBoxPlugin.java

@@ -17,6 +17,7 @@
 package de.nplusc.izc.izpl.plugins.jukebox;
 
 import de.nplusc.izc.iZpl.API.FeaturePlugin;
+import de.nplusc.izc.iZpl.API.IZPLApi;
 import de.nplusc.izc.iZpl.API.UIPlugin;
 import java.awt.Image;
 import org.apache.logging.log4j.LogManager;
@@ -38,6 +39,11 @@ public class JukeBoxPlugin implements UIPlugin, FeaturePlugin
         
     }
 
+    @Override
+    public void notifyOnQuit() {
+        backend.notifyQuit();
+    }
+
     @Override
     public void setTrackLength(int length)
     {
@@ -53,7 +59,7 @@ public class JukeBoxPlugin implements UIPlugin, FeaturePlugin
     @Override
     public void setVisible(boolean visible)
     {
-        frontend.setVisible(visible);
+        frontend.setVisible(visible&&!IZPLApi.suppressGUI());
     }
 
     @Override

+ 2 - 93
iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/JukeboxClientHandler.java

@@ -123,101 +123,10 @@ public class JukeboxClientHandler
     }
     private void parsePacket(Packet p)
     {
-
-        
-        HashMap<String,Object> packet = p.getData();
-        String commandType = (String) packet.get("COMMAND");
-        String param = (String) packet.get("PARAM");
-        
-        switch(commandType)
-        {
-            case "play":
-                srv.play();
-                break;
-            case "sync":
-                sync();
-                break;
-            case "pause":
-                srv.pause();
-                break;
-            case "skip":
-                srv.skip();
-                break;
-            case "seek":
-                try
-                {
-                   int pos = Integer.valueOf(param);
-                   srv.seek(pos);
-                }
-                catch(NumberFormatException e)
-                {
-                    //TODO error
-                }
-                break;
-            case "enqueue":
-                try
-                {
-                   int pos = Integer.valueOf(param);
-                   srv.enqueue(pos);
-                }
-                catch(NumberFormatException e)
-                {
-                    //TODO error
-                }
-                break;
-            case "reload":
-                srv.reload();
-                break;
-            case "getTitles":
-                {
-                    try
-                    {
-                        String[] titles = srv.getTitles();
-                        HashMap<String,Object> data = new HashMap<>();
-                        Packet response = new Packet();
-                        data.put("RESPONSE", "TITLES");
-                        data.put("DATA", titles);
-                        response.setData(data);
-                        respondToLinkedClient(response);
-
-
-                    }
-                    catch (InvalidPlayListFileException ex)
-                    {
-                        ex.printStackTrace();
-                    }
-                }
-                break;
-            case "getScheduled":
-                List<String> titles = srv.getScheduledTracks();
-                HashMap<String,Object> data = new HashMap<>();
-                Packet response = new Packet();
-                data.put("RESPONSE", "QUEUE");
-                data.put("DATA", titles);
-                response.setData(data);
-                respondToLinkedClient(response);
-                break;
-            default:
-                break;
-        }
+        srv.parsePacket(p,this::respondToLinkedClient);
     }
     private void sync()
     {
-        l.info("SYNC");
-        Packet titles = srv.createUpdatePackage("TRACKS","");
-        respondToLinkedClient(titles);
-        l.trace("SNYC Tracks");
-        Packet queue = srv.createUpdatePackage("QUEUE","");
-        respondToLinkedClient(queue);
-        l.trace("SNYC QUEUE");
-        Packet title = srv.createUpdatePackage("TITLE",srv.getTitle());
-        respondToLinkedClient(title);
-        l.trace("SNYC LENGTH");
-        Packet length = srv.createUpdatePackage("LENGTH",srv.getTrackLength()+"");
-        respondToLinkedClient(length);
-        l.trace("SNYC PLAYING");
-        Packet playbackStatus = srv.createUpdatePackage("PLAYING",srv.getPlaybackStatus()+"");
-        respondToLinkedClient(playbackStatus);
-        l.info("SYNC finished");
+
     }
 }

+ 175 - 4
iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/JukeboxServer.java

@@ -16,30 +16,43 @@
  */
 package de.nplusc.izc.izpl.plugins.jukebox;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import de.nplusc.izc.iZpl.API.shared.InvalidPlayListFileException;
 import de.nplusc.izc.iZpl.API.shared.networking.Packet;
 import java.io.IOException;
+import java.net.InetSocketAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
+import java.util.function.Consumer;
+
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
+import org.java_websocket.WebSocket;
+import org.java_websocket.handshake.ClientHandshake;
+import org.java_websocket.server.WebSocketServer;
+import org.yaml.snakeyaml.Yaml;
 
 /**
  *
  * @author iZc <nplusc.de>
  */
-public class JukeboxServer implements PlaybackStatusUpdater,Backend
+public class JukeboxServer extends WebSocketServer implements PlaybackStatusUpdater,Backend
 {
     private LocalBackend backend;
     private static final Logger l = LogManager.getLogger();
     private List<JukeboxClientHandler> currentClients;
+    private ObjectMapper mapper = new ObjectMapper();
+
     public JukeboxServer(LocalBackend backend)
     {
+        super(new InetSocketAddress(JukeBox.JUKEBOX_PORT+1));
         this.backend=backend;
         currentClients = new ArrayList<>();
+
     }
     
     public void deregisterClient(JukeboxClientHandler c)
@@ -84,6 +97,16 @@ public class JukeboxServer implements PlaybackStatusUpdater,Backend
     {
         final Packet response = createUpdatePackage(action, value);
         currentClients.forEach((c->c.respondToLinkedClient(response)));
+        String jsonedPacket = null;
+        try {
+            jsonedPacket = mapper.writeValueAsString(response);
+        } catch (JsonProcessingException e) {
+            l.error("invalid object, can't broadcast to clients");
+            l.trace(new Yaml().dump(response));
+            e.printStackTrace();
+        }
+        l.trace(jsonedPacket);
+        this.broadcast(jsonedPacket);
     }
     
     Packet createUpdatePackage(String action,String value)
@@ -133,7 +156,10 @@ public class JukeboxServer implements PlaybackStatusUpdater,Backend
         sendUpdate("QUEUE", "");
     }
 
-    
+    public void notifyQuit()
+    {
+        sendUpdate("QUIT", "");
+    }
     
     
     @Override
@@ -213,6 +239,151 @@ public class JukeboxServer implements PlaybackStatusUpdater,Backend
     {
         return backend.getTrackLength();
     }
-    
-    
+
+
+    void parsePacket(Packet p, Consumer<Packet> responder)
+    {
+        HashMap<String,Object> packet = p.getData();
+        String commandType = (String) packet.get("COMMAND");
+        String param = (String) packet.get("PARAM");
+
+        switch(commandType)
+        {
+            case "play":
+                this.play();
+                break;
+            case "sync":
+                {
+                    l.info("SYNC");
+                    Packet titles = this.createUpdatePackage("TRACKS","");
+                    responder.accept(titles);
+                    l.trace("SNYC Tracks");
+                    Packet queue = this.createUpdatePackage("QUEUE","");
+                    responder.accept(queue);
+                    l.trace("SNYC QUEUE");
+                    Packet title = this.createUpdatePackage("TITLE",this.getTitle());
+                    responder.accept(title);
+                    l.trace("SNYC LENGTH");
+                    Packet length = this.createUpdatePackage("LENGTH",this.getTrackLength()+"");
+                    responder.accept(length);
+                    l.trace("SNYC PLAYING");
+                    Packet playbackStatus = this.createUpdatePackage("PLAYING",this.getPlaybackStatus()+"");
+                    responder.accept(playbackStatus);
+                    l.info("SYNC finished");
+                }
+                break;
+            case "pause":
+                this.pause();
+                break;
+            case "skip":
+                this.skip();
+                break;
+            case "seek":
+                try
+                {
+                    int pos = Integer.valueOf(param);
+                    this.seek(pos);
+                }
+                catch(NumberFormatException e)
+                {
+                    //TODO error
+                }
+                break;
+            case "enqueue":
+                try
+                {
+                    int pos = Integer.valueOf(param);
+                    this.enqueue(pos);
+                }
+                catch(NumberFormatException e)
+                {
+                    //TODO error
+                }
+                break;
+            case "reload":
+                this.reload();
+                break;
+            case "getTitles":
+            {
+                try
+                {
+                    String[] titles = this.getTitles();
+                    HashMap<String,Object> data = new HashMap<>();
+                    Packet response = new Packet();
+                    data.put("RESPONSE", "TITLES");
+                    data.put("DATA", titles);
+                    response.setData(data);
+                    responder.accept(response);
+
+
+                }
+                catch (InvalidPlayListFileException ex)
+                {
+                    ex.printStackTrace();
+                }
+            }
+            break;
+            case "getScheduled":
+                List<String> titles = this.getScheduledTracks();
+                HashMap<String,Object> data = new HashMap<>();
+                Packet response = new Packet();
+                data.put("RESPONSE", "QUEUE");
+                data.put("DATA", titles);
+                response.setData(data);
+                responder.accept(response);
+                break;
+            default:
+                break;
+        }
+    }
+
+
+
+
+
+    @Override
+    public void onOpen(WebSocket conn, ClientHandshake handshake) {
+
+    }
+
+    @Override
+    public void onClose(WebSocket conn, int code, String reason, boolean remote) {
+
+    }
+
+    @Override
+    public void onMessage(WebSocket conn, String message) {
+
+        Consumer<Packet> responseCB = (response)->{
+            String jsonedPacket = null;
+            try {
+                jsonedPacket = mapper.writeValueAsString(response);
+            } catch (JsonProcessingException e) {
+                l.error("invalid object, can't broadcast to clients");
+                l.trace(new Yaml().dump(response));
+                e.printStackTrace();
+            }
+            l.trace(jsonedPacket);
+            conn.send(jsonedPacket);
+        };
+        try {
+            Packet p = mapper.readValue(message,Packet.class);
+            parsePacket(p,responseCB);
+        } catch (JsonProcessingException e) {
+            l.error("Invalid packet");
+            l.error(message);
+            e.printStackTrace();
+        }
+
+    }
+
+    @Override
+    public void onError(WebSocket conn, Exception ex) {
+
+    }
+
+    @Override
+    public void onStart() {
+
+    }
 }

+ 3 - 0
iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/LocalBackend.java

@@ -46,9 +46,12 @@ public class LocalBackend implements Backend
         selectedPlaybackPlugin=IZPLApi.getCurrentPlaybackPlugin();
         l.trace(selectedPlaybackPlugin+"");
         JukeboxServer s = new JukeboxServer(this);
+        Thread wsthread = new Thread(s);
         Thread t = new Thread(s::ServerThreadMain);
         t.setName("serverMain");
+        wsthread.setName("websocketMain");
         t.start();
+        wsthread.start();
         l.info("Loaded Server");
         server = s;
     }

+ 2 - 0
iZplPlugins/JukeBox/src/main/java/de/nplusc/izc/izpl/plugins/jukebox/PlaybackStatusUpdater.java

@@ -28,4 +28,6 @@ public interface PlaybackStatusUpdater
     void triggerTableRefresh();
     void triggerScheduleRefresh();
     void setPlayStatus(boolean playing);
+
+    default void notifyQuit(){};
 }

+ 19 - 19
iZplPlugins/Smartphonizer/build.gradle

@@ -1,19 +1,19 @@
-apply plugin:'java'
-task distZip(dependsOn: 'jar') {
-	//NO-OPtask als redirect
-}
-
-
-
-
-
-compileJava.options.encoding = 'UTF-8'
-dependencies
-{
-	compile fileTree(dir: 'lib', include: '*.jar')
-	compile project(':iZpl')
-   
-
-}
-
-
+apply plugin: 'java-library'
+task distZip(dependsOn: 'jar') {
+	//NO-OPtask als redirect
+}
+
+
+
+
+
+compileJava.options.encoding = 'UTF-8'
+dependencies
+{
+	api fileTree(dir: 'lib', include: '*.jar')
+	api project(':iZpl')
+   
+
+}
+
+

+ 24 - 24
iZplPlugins/WMP/build.gradle

@@ -1,24 +1,24 @@
-apply plugin:'java'
-task distZip(dependsOn: 'fatJar') {
-	//NO-OPtask als redirect
-}
-
-task fatJar(type: Jar) {
-		manifest{
-		attributes 'Implementation-Title': 'iZPlaylist-WMP',
-					'Implementation-Version': 'SNAPSHOT'
-					
-	}
-    baseName = project.name + '-all'
-    from { zipTree("lib/com4j.jar")  }
-    with jar
-}
-
-
-dependencies
-{
-	compile fileTree(dir: 'lib', include: '*.jar')
-	compile project(':iZpl')
-}
-
-
+apply plugin: 'java-library'
+task distZip(dependsOn: 'fatJar') {
+	//NO-OPtask als redirect
+}
+
+task fatJar(type: Jar) {
+		manifest{
+		attributes 'Implementation-Title': 'iZPlaylist-WMP',
+					'Implementation-Version': 'SNAPSHOT'
+					
+	}
+    baseName = project.name + '-all'
+    from { zipTree("lib/com4j.jar")  }
+    with jar
+}
+
+
+dependencies
+{
+	api fileTree(dir: 'lib', include: '*.jar')
+	api project(':iZpl')
+}
+
+

+ 3 - 3
iZplPlugins/discordjukebox/build.gradle

@@ -1,4 +1,4 @@
-apply plugin:'java'
+apply plugin: 'java-library'
 task distZip(dependsOn: 'jar') {
 	//NO-OPtask als redirect
 }
@@ -10,8 +10,8 @@ task distZip(dependsOn: 'jar') {
 compileJava.options.encoding = 'UTF-8'
 dependencies
 {
-	compile fileTree(dir: 'lib', include: '*.jar')
-	compile project(':iZpl')
+	api fileTree(dir: 'lib', include: '*.jar')
+	api project(':iZpl')
    
 
 }

+ 13 - 13
iZplPlugins/foobar2000_others/build.gradle

@@ -1,13 +1,13 @@
-apply plugin:'java'
-
-task distZip(dependsOn: 'jar') {
-	//NO-OPtask als redirect
-}
-
-
-dependencies
-{
-	compile fileTree(dir: 'lib', include: '*.jar')
-	compile(project(':iZpl'))
-}
-
+apply plugin: 'java-library'
+
+task distZip(dependsOn: 'jar') {
+	//NO-OPtask als redirect
+}
+
+
+dependencies
+{
+	api fileTree(dir: 'lib', include: '*.jar')
+	api(project(':iZpl'))
+}
+

+ 3 - 3
iZplPlugins/rtsslink/build.gradle

@@ -1,4 +1,4 @@
-apply plugin:'java'
+apply plugin: 'java-library'
 task distZip(dependsOn: 'jar') {
 	//NO-OPtask als redirect
 }
@@ -10,8 +10,8 @@ task distZip(dependsOn: 'jar') {
 compileJava.options.encoding = 'UTF-8'
 dependencies
 {
-	compile fileTree(dir: 'lib', include: '*.jar')
-	compile project(':iZpl')
+	api fileTree(dir: 'lib', include: '*.jar')
+	api project(':iZpl')
    
 
 }

+ 8 - 8
izpl-shared/build.gradle

@@ -1,13 +1,13 @@
-apply plugin: 'java'
+apply plugin: 'java-library'
 
 sourceCompatibility = 1.7
 targetCompatibility = 1.7
 dependencies{
-    compile fileTree(dir: 'lib', include: '*.jar')
-    compile "org.yaml:snakeyaml:1.14"
-	compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+'
-	compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+'
-	compile group: 'org.apache.logging.log4j', name: 'log4j-iostreams', version: '2.+'
-    compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.+'
-	compile "net.jthink:jaudiotagger:2+"
+    api fileTree(dir: 'lib', include: '*.jar')
+    api "org.yaml:snakeyaml:1.14"
+	api group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.+'
+	api group: 'org.apache.logging.log4j', name: 'log4j-iostreams', version: '2.+'
+    api group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.+'
+	api "net.jthink:jaudiotagger:2+"
 }

+ 5 - 0
izpl-shared/src/main/java/de/nplusc/izc/iZpl/API/shared/ActionPlayListItem.java

@@ -0,0 +1,5 @@
+package de.nplusc.izc.iZpl.API.shared;
+
+public interface ActionPlayListItem extends PlayListItem{
+    void executeAction();
+}

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно