builder()
+ .put(OS.LINUX, true,
+ String.format(
+ "https://github.com/eugeneware/ffmpeg-static/releases/download/%s/linux-arm",
+ VERSION))
+ .put(OS.LINUX, false,
+ String.format(
+ "https://github.com/eugeneware/ffmpeg-static/releases/download/%s/linux-ia32",
+ VERSION))
+ .put(OS.WINDOWS, false,
+ String.format(
+ "https://github.com/eugeneware/ffmpeg-static/releases/download/%s/win32-ia32",
+ VERSION))
+ .build();
+ }
+
+ FFmpegInstaller(final Path folder) {
+ super(folder, "ffmpeg", BITS_32, BITS_64);
+ }
+
+ FFmpegInstaller() {
+ super("ffmpeg", BITS_32, BITS_64);
+ }
+
+ /**
+ * Constructs a new FFmpegInstaller with the specified directory for the executable.
+ *
+ * @param executable directory
+ * @return new FFmpegInstaller
+ */
+ public static FFmpegInstaller create(final Path executable) {
+ return new FFmpegInstaller(executable);
+ }
+
+ /**
+ * Constructs a new FFmpegInstaller with the default directory for the executable.
+ *
+ * For Windows, it is C:/Program Files/static-emc Otherwise, it is [user home
+ * directory]/static-emc
+ *
+ * @return new FFmpegInstaller
+ */
+ public static FFmpegInstaller create() {
+ return new FFmpegInstaller();
+ }
+
+ @Override
+ public boolean isSupported() {
+ return true;
+ }
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/rtsp/RTSPInstaller.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/rtsp/RTSPInstaller.java
new file mode 100644
index 0000000..02aa457
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/rtsp/RTSPInstaller.java
@@ -0,0 +1,96 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2021 Brandon Li
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package io.github.pulsebeat02.emcinstallers.implementation.rtsp;
+
+import com.google.common.collect.ImmutableTable;
+import com.google.common.collect.Table;
+import io.github.pulsebeat02.emcinstallers.OS;
+import io.github.pulsebeat02.emcinstallers.implementation.BaseInstaller;
+import java.nio.file.Path;
+
+public final class RTSPInstaller extends BaseInstaller {
+
+ private static final Table BITS_64;
+ private static final Table BITS_32;
+
+ static {
+ BITS_64 = ImmutableTable.builder()
+ .put(OS.LINUX, true,
+ "https://github.com/MinecraftMediaLibrary/rtsmp-binaries/raw/main/executables/linux-arm64")
+ .put(OS.LINUX, false,
+ "https://github.com/MinecraftMediaLibrary/rtsmp-binaries/raw/main/executables/linux-amd64")
+ .put(OS.MAC, true,
+ "https://github.com/MinecraftMediaLibrary/rtsmp-binaries/raw/main/executables/darwin-arm64")
+ .put(OS.MAC, false,
+ "https://github.com/MinecraftMediaLibrary/rtsmp-binaries/raw/main/executables/darwin-amd64")
+ .put(OS.WINDOWS, false,
+ "https://github.com/MinecraftMediaLibrary/rtsmp-binaries/raw/main/executables/windows-amd64.exe")
+ .put(OS.FREEBSD, false,
+ "https://github.com/MinecraftMediaLibrary/rtsmp-binaries/raw/main/executables/freebsd-amd64")
+ .build();
+ BITS_32 = ImmutableTable.builder()
+ .put(OS.LINUX, true,
+ "https://github.com/MinecraftMediaLibrary/rtsmp-binaries/raw/main/executables/linux-arm")
+ .put(OS.LINUX, false,
+ "https://github.com/MinecraftMediaLibrary/rtsmp-binaries/raw/main/executables/linux-ia32")
+ .put(OS.WINDOWS, false,
+ "https://github.com/MinecraftMediaLibrary/rtsmp-binaries/raw/main/executables/windows-ia32.exe")
+ .build();
+ }
+
+ RTSPInstaller(final Path folder) {
+ super(folder, "simple-rtsp-server", BITS_32, BITS_64);
+ }
+
+ RTSPInstaller() {
+ super("simple-rtsp-server", BITS_32, BITS_64);
+ }
+
+ /**
+ * Constructs a new FFmpegInstaller with the specified directory for the executable.
+ *
+ * @param executable directory
+ * @return new FFmpegInstaller
+ */
+ public static RTSPInstaller create(final Path executable) {
+ return new RTSPInstaller(executable);
+ }
+
+ /**
+ * Constructs a new RTSPInstaller with the default directory for the executable.
+ *
+ * For Windows, it is C:/Program Files/static-emc Otherwise, it is [user home
+ * directory]/static-emc
+ *
+ * @return new FFmpegInstaller
+ */
+ public static RTSPInstaller create() {
+ return new RTSPInstaller();
+ }
+
+ @Override
+ public boolean isSupported() {
+ return true;
+ }
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/VLCInstallationKit.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/VLCInstallationKit.java
new file mode 100644
index 0000000..b0c43f8
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/VLCInstallationKit.java
@@ -0,0 +1,120 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2021 Brandon Li
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package io.github.pulsebeat02.emcinstallers.implementation.vlc;
+
+import static io.github.pulsebeat02.emcinstallers.OS.MAC;
+import static io.github.pulsebeat02.emcinstallers.OS.getExecutablePath;
+
+import io.github.pulsebeat02.emcinstallers.OS;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.installation.VLCInstaller;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.EnhancedNativeDiscovery;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.DirectoryProviderDiscoveryStrategy;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Optional;
+
+public final class VLCInstallationKit {
+
+ private final Path[] others;
+
+ VLCInstallationKit(final Path... others) {
+ this.others = others;
+ }
+
+ VLCInstallationKit() {
+ this(getExecutablePath());
+ }
+
+ /**
+ * Attempts to search for the VLC binary in common installation paths. If a library has been found
+ * and loaded successfully, it will be available to be used by VLCJ. Otherwise, if a library could
+ * not be found, it will download the respective binary for the user operating system and load
+ * that libvlc that way.
+ *
+ * @return Optional containing path if found, otherwise empty
+ * @throws IOException if an issue occurred during installation
+ */
+ public Optional start() throws IOException {
+ return this.installBinary(true, this.others);
+ }
+
+ private Optional installBinary(final boolean chmod, final Path... others)
+ throws IOException {
+ this.addExtraSearchPaths(others);
+ final Optional binary = this.searchAndLoadBinary();
+ if (binary.isPresent()) {
+ return binary;
+ }
+ return this.loadInstalledBinaries(chmod);
+ }
+
+ private Optional loadInstalledBinaries(final boolean chmod) throws IOException {
+ this.addDownloadedSearchPath(chmod);
+ return this.searchAndLoadBinary();
+ }
+
+ private void addDownloadedSearchPath(final boolean chmod) throws IOException {
+ DirectoryProviderDiscoveryStrategy.addSearchDirectory(
+ this.getProperPath(VLCInstaller.create().download(chmod)));
+ }
+
+ private Path getProperPath(final Path path) {
+ if (OS.getOperatingSystem() == MAC) {
+ return path.resolve("Contents").resolve("MacOS").resolve("lib");
+ }
+ return path;
+ }
+
+ private void addExtraSearchPaths(final Path[] others) {
+ Arrays.stream(others).forEach(DirectoryProviderDiscoveryStrategy::addSearchDirectory);
+ }
+
+ private Optional searchAndLoadBinary() {
+ final EnhancedNativeDiscovery discovery = new EnhancedNativeDiscovery();
+ if (discovery.discover()) {
+ return Optional.of(Paths.get(discovery.getDiscoveredPath()));
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * Constructs a new VLCInstallationKit with default parameters for downloading/loading libvlc into
+ * the runtime.
+ *
+ * @return a new VLCInstallationKit
+ */
+ public static VLCInstallationKit create() {
+ return new VLCInstallationKit();
+ }
+
+ /**
+ * Constructs a new VLCInstallationKit with the specified path(s) for downloading/loading libvlc
+ * into the runtime.
+ *
+ * @param others the desired paths to search
+ * @return a new VLCInstallationKit
+ */
+ public static VLCInstallationKit create(final Path... others) {
+ return new VLCInstallationKit(others);
+ }
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/installation/InstallationStrategy.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/installation/InstallationStrategy.java
new file mode 100644
index 0000000..a9636df
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/installation/InstallationStrategy.java
@@ -0,0 +1,35 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2021 Brandon Li
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.installation;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Optional;
+
+public interface InstallationStrategy {
+
+ Optional getInstalledPath();
+
+ Path execute() throws IOException;
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/installation/ManualInstallationStrategy.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/installation/ManualInstallationStrategy.java
new file mode 100644
index 0000000..96adb14
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/installation/ManualInstallationStrategy.java
@@ -0,0 +1,45 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2021 Brandon Li
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.installation;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+public abstract class ManualInstallationStrategy implements InstallationStrategy {
+
+ private final VLCInstaller installer;
+
+ public ManualInstallationStrategy(final VLCInstaller installer) {
+ this.installer = installer;
+ }
+
+ public void deleteFile(final Path dmg) throws IOException {
+ Files.deleteIfExists(dmg);
+ }
+
+ public VLCInstaller getInstaller() {
+ return this.installer;
+ }
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/installation/VLCInstaller.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/installation/VLCInstaller.java
new file mode 100644
index 0000000..19e400a
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/installation/VLCInstaller.java
@@ -0,0 +1,127 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2021 Brandon Li
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.installation;
+
+import static io.github.pulsebeat02.emcinstallers.OS.MAC;
+import static io.github.pulsebeat02.emcinstallers.OS.WINDOWS;
+import static io.github.pulsebeat02.emcinstallers.OS.getOperatingSystem;
+
+import com.google.common.collect.ImmutableTable;
+import com.google.common.collect.Table;
+import io.github.pulsebeat02.emcinstallers.OS;
+import io.github.pulsebeat02.emcinstallers.implementation.BaseInstaller;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.installation.platform.osx.OSXInstallationStrategy;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.installation.platform.win.WinInstallationStrategy;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Optional;
+
+public final class VLCInstaller extends BaseInstaller {
+
+ public static final String VERSION;
+ private static final Table BITS_64;
+ private static final Table BITS_32;
+
+ static {
+ VERSION = "3.0.16";
+ BITS_64 = ImmutableTable.builder()
+ .put(MAC, true,
+ String.format("https://mirror.csclub.uwaterloo.ca/vlc/vlc/%s/macosx/vlc-%s-arm64.dmg",
+ VERSION, VERSION))
+ .put(MAC, false,
+ String.format(
+ "https://mirror.csclub.uwaterloo.ca/vlc/vlc/%s/macosx/vlc-%s-universal.dmg",
+ VERSION, VERSION))
+ .put(WINDOWS, false,
+ String.format("https://mirror.csclub.uwaterloo.ca/vlc/vlc/%s/win64/vlc-%s-win64.zip",
+ VERSION, VERSION))
+ .build();
+ BITS_32 = ImmutableTable.builder()
+ .put(WINDOWS, false,
+ String.format("https://mirror.csclub.uwaterloo.ca/vlc/vlc/%s/win32/vlc-%s-win32.zip",
+ VERSION, VERSION))
+ .build();
+ }
+
+ VLCInstaller(final Path folder) {
+ super(folder, "vlc", BITS_32, BITS_64);
+ }
+
+ VLCInstaller() {
+ super("vlc", BITS_32, BITS_64);
+ }
+
+ /**
+ * Constructs a new VLCInstaller with the specified directory for the executable.
+ *
+ * @param executable directory
+ * @return new VLCInstaller
+ */
+ public static VLCInstaller create(final Path executable) {
+ return new VLCInstaller(executable);
+ }
+
+ /**
+ * Constructs a new VLCInstaller with the default directory for the executable.
+ *
+ * For Windows, it is C:/Program Files/static-emc Otherwise, it is [user home
+ * directory]/static-emc
+ *
+ * @return new VLCInstaller
+ */
+ public static VLCInstaller create() {
+ return new VLCInstaller();
+ }
+
+ @Override
+ public Path download(final boolean chmod) throws IOException {
+
+ final InstallationStrategy strategy = this.getStrategy();
+ final Optional optional = strategy.getInstalledPath();
+ if (optional.isPresent()) {
+ return optional.get();
+ }
+
+ super.download(chmod);
+
+ return strategy.execute();
+ }
+
+ private InstallationStrategy getStrategy() {
+ switch (getOperatingSystem()) {
+ case MAC:
+ return new OSXInstallationStrategy(this);
+ case WINDOWS:
+ return new WinInstallationStrategy(this);
+ default:
+ throw new AssertionError("Operating System not Supported!");
+ }
+ }
+
+ @Override
+ public boolean isSupported() {
+ final OS os = getOperatingSystem();
+ return os == WINDOWS || os == MAC;
+ }
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/installation/platform/osx/OSXInstallationStrategy.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/installation/platform/osx/OSXInstallationStrategy.java
new file mode 100644
index 0000000..de41b71
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/installation/platform/osx/OSXInstallationStrategy.java
@@ -0,0 +1,84 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2021 Brandon Li
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.installation.platform.osx;
+
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.installation.VLCInstaller;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.installation.ManualInstallationStrategy;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Optional;
+
+public final class OSXInstallationStrategy extends ManualInstallationStrategy {
+
+ public OSXInstallationStrategy(
+ final VLCInstaller installer) {
+ super(installer);
+ }
+
+ @Override
+ public Optional getInstalledPath() {
+ final Path path = this.getInstaller().getPath().getParent().resolve("VLC.app");
+ return Files.exists(path) ? Optional.of(path) : Optional.empty();
+ }
+
+ @Override
+ public Path execute() throws IOException {
+ final String vlc = "VLC.app";
+ final Path dmg = this.getInstaller().getPath();
+ final Path disk = Paths.get("/Volumes/VLC media player");
+ final Path app = dmg.getParent().resolve(vlc);
+ this.mountDisk(dmg);
+ this.copyApplication(disk.resolve(vlc), app);
+ this.changePermissions(app);
+ this.unmountDisk(disk);
+ this.deleteFile(dmg);
+ return app;
+ }
+
+ private void unmountDisk(final Path disk) throws IOException {
+ this.runNativeProcess("diskutil", "unmount", disk.toString());
+ }
+
+ private void changePermissions(final Path app) throws IOException {
+ this.runNativeProcess("chmod", "-R", "755", app.toString());
+ }
+
+ private void mountDisk(final Path dmg) throws IOException {
+ this.runNativeProcess("/usr/bin/hdiutil", "attach", dmg.toString());
+ }
+
+ private void copyApplication(final Path src, final Path app) throws IOException {
+ this.runNativeProcess("rsync", "-a", String.format("%s/", src.toString()), app.toString());
+ }
+
+ private void runNativeProcess(final String... arguments) throws IOException {
+ try {
+ new ProcessBuilder(arguments).start().waitFor();
+ } catch (final InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/installation/platform/win/WinInstallationStrategy.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/installation/platform/win/WinInstallationStrategy.java
new file mode 100644
index 0000000..5741a8f
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/installation/platform/win/WinInstallationStrategy.java
@@ -0,0 +1,94 @@
+/**
+ * MIT License
+ *
+ * Copyright (c) 2021 Brandon Li
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.installation.platform.win;
+
+import com.google.common.io.ByteStreams;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.installation.VLCInstaller;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.installation.ManualInstallationStrategy;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Enumeration;
+import java.util.Optional;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+public final class WinInstallationStrategy extends ManualInstallationStrategy {
+
+ public WinInstallationStrategy(
+ final VLCInstaller installer) {
+ super(installer);
+ }
+
+ @Override
+ public Optional getInstalledPath() {
+ final Path path = this.getInstaller().getPath().getParent().resolve("VLC");
+ return Files.exists(path) ? Optional.of(path) : Optional.empty();
+ }
+
+ @Override
+ public Path execute() throws IOException {
+ final Path zip = this.getInstaller().getPath();
+ final Path parent = zip.getParent();
+ final Path temp = parent.resolve("temp-vlc");
+ final Path path = parent.resolve("VLC");
+ this.extractArchive(zip, temp);
+ this.deleteFile(zip);
+ this.moveFiles(temp, path);
+ this.deleteFile(temp);
+ return path;
+ }
+
+ private void extractArchive(final Path zip, final Path temp) throws IOException {
+ try (final ZipFile zipFile = new ZipFile(zip.toFile())) {
+ final Enumeration extends ZipEntry> entries = zipFile.entries();
+ while (entries.hasMoreElements()) {
+ final ZipEntry entry = entries.nextElement();
+ final Path entryDestination = temp.resolve(entry.getName());
+ if (entry.isDirectory()) {
+ this.createDirectories(entryDestination);
+ } else {
+ this.createDirectories(entryDestination.getParent());
+ try (final InputStream in = zipFile.getInputStream(entry);
+ final OutputStream out = new FileOutputStream(entryDestination.toFile())) {
+ ByteStreams.copy(in, out);
+ }
+ }
+ }
+ }
+ }
+
+ private void createDirectories(final Path path) throws IOException {
+ if (Files.notExists(path)) {
+ Files.createDirectories(path);
+ }
+ }
+
+ private void moveFiles(final Path temp, final Path dest) throws IOException {
+ Files.move(temp.resolve(String.format("vlc-%s", VLCInstaller.VERSION)), dest);
+ }
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/EnhancedNativeDiscovery.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/EnhancedNativeDiscovery.java
new file mode 100644
index 0000000..a99f887
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/EnhancedNativeDiscovery.java
@@ -0,0 +1,108 @@
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.search;
+
+import static uk.co.caprica.vlcj.binding.LibVlc.libvlc_new;
+import static uk.co.caprica.vlcj.binding.LibVlc.libvlc_release;
+
+import com.sun.jna.NativeLibrary;
+import com.sun.jna.StringArray;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.strategy.BaseNativeDiscoveryStrategy;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.strategy.NativeDiscoveryStrategy;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.strategy.linux.LinuxNativeDiscoveryStrategy;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.strategy.osx.OsxNativeDiscoveryStrategy;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.strategy.win.WindowsNativeDiscoveryStrategy;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import uk.co.caprica.vlcj.binding.RuntimeUtil;
+import uk.co.caprica.vlcj.binding.internal.libvlc_instance_t;
+import uk.co.caprica.vlcj.support.version.LibVlcVersion;
+
+public class EnhancedNativeDiscovery {
+
+ private static final List DEFAULT_STRATEGIES;
+ private static boolean FOUND;
+
+ static {
+ DEFAULT_STRATEGIES = Arrays.asList(
+ new LinuxNativeDiscoveryStrategy(),
+ new OsxNativeDiscoveryStrategy(),
+ new WindowsNativeDiscoveryStrategy());
+ }
+
+ private final List discoveryStrategies;
+ private NativeDiscoveryStrategy successfulStrategy;
+ private String discoveredPath;
+
+ public EnhancedNativeDiscovery(final NativeDiscoveryStrategy... discoveryStrategies) {
+ this.discoveryStrategies =
+ discoveryStrategies.length > 0 ? Arrays.asList(discoveryStrategies) : DEFAULT_STRATEGIES;
+ }
+
+ public final boolean discover() {
+ if (FOUND) {
+ return true;
+ } else {
+ for (final NativeDiscoveryStrategy discoveryStrategy : this.discoveryStrategies) {
+ if (discoveryStrategy.supported()) {
+ final Optional optional = discoveryStrategy.discover();
+ if (optional.isPresent()) {
+ final String path = optional.get();
+ this.addLibvlc(discoveryStrategy, path);
+ this.tryPluginPath(path, discoveryStrategy);
+ return this.attemptLibraryLoad(discoveryStrategy, path);
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ private boolean attemptLibraryLoad(final NativeDiscoveryStrategy discoveryStrategy,
+ final String path) {
+ if (this.tryLoadingLibrary()) {
+ this.successfulStrategy = discoveryStrategy;
+ this.discoveredPath = path;
+ FOUND = true;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private void addLibvlc(final NativeDiscoveryStrategy discoveryStrategy, final String path) {
+ if (discoveryStrategy.onFound(path)) {
+ NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), path);
+ }
+ }
+
+ private void tryPluginPath(final String path, final NativeDiscoveryStrategy discoveryStrategy) {
+ final String env = System.getenv(BaseNativeDiscoveryStrategy.PLUGIN_ENV_NAME);
+ if (env == null || env.length() == 0) {
+ discoveryStrategy.onSetPluginPath(path);
+ }
+ }
+
+ private boolean tryLoadingLibrary() {
+ try {
+ final libvlc_instance_t instance = libvlc_new(0, new StringArray(new String[0]));
+ if (instance != null) {
+ libvlc_release(instance);
+ final LibVlcVersion version = new LibVlcVersion();
+ if (version.isSupported()) {
+ return true;
+ }
+ }
+ } catch (final UnsatisfiedLinkError e) {
+ System.err.println(e.getMessage());
+ }
+ return false;
+ }
+
+ public NativeDiscoveryStrategy getDiscoveryStrategy() {
+ return this.successfulStrategy;
+ }
+
+ public String getDiscoveredPath() {
+ return this.discoveredPath;
+ }
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/DirectoryProviderDiscoveryStrategy.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/DirectoryProviderDiscoveryStrategy.java
new file mode 100644
index 0000000..db421f8
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/DirectoryProviderDiscoveryStrategy.java
@@ -0,0 +1,89 @@
+/*
+ * This file is part of VLCJ.
+ *
+ * VLCJ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * VLCJ is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with VLCJ. If not, see .
+ *
+ * Copyright 2009-2019 Caprica Software Limited.
+ */
+
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider;
+
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.linux.LinuxWellKnownDirectoryProvider;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.misc.ConfigurationFileDiscoveryDirectoryProvider;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.misc.CustomWellKnownDirectoryProvider;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.misc.JnaLibraryPathDirectoryProvider;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.osx.OsxWellKnownDirectoryProvider;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.path.SystemPathDirectoryProvider;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.path.UserDirDirectoryProvider;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.win.WindowsInstallDirectoryProvider;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.strategy.BaseNativeDiscoveryStrategy;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+public abstract class DirectoryProviderDiscoveryStrategy extends BaseNativeDiscoveryStrategy {
+
+ private static final Set DIRECTORY_PROVIDERS;
+
+ static {
+ DIRECTORY_PROVIDERS = new TreeSet<>((o1, o2) -> o2.priority() - o1.priority());
+ DIRECTORY_PROVIDERS.addAll(Arrays.asList(
+ new ConfigurationFileDiscoveryDirectoryProvider(),
+ new JnaLibraryPathDirectoryProvider(),
+ new LinuxWellKnownDirectoryProvider(),
+ new OsxWellKnownDirectoryProvider(),
+ new SystemPathDirectoryProvider(),
+ new UserDirDirectoryProvider(),
+ new WindowsInstallDirectoryProvider()
+ ));
+ }
+
+ private final Set directoryProviders;
+
+ public DirectoryProviderDiscoveryStrategy(final String[] filenamePatterns,
+ final String[] pluginPathFormats) {
+ super(filenamePatterns, pluginPathFormats);
+ this.directoryProviders = DIRECTORY_PROVIDERS;
+ }
+
+ @Override
+ public final List discoveryDirectories() {
+ final List directories = new ArrayList<>();
+ for (final DiscoveryDirectoryProvider provider : this.getSupportedProviders()) {
+ directories.addAll(Arrays.asList(provider.directories()));
+ }
+ return directories;
+ }
+
+ private List getSupportedProviders() {
+ final List result = new ArrayList<>();
+ for (final DiscoveryDirectoryProvider list : this.directoryProviders) {
+ if (list.supported()) {
+ result.add(list);
+ }
+ }
+ return this.sort(result);
+ }
+
+ private List sort(final List providers) {
+ return providers;
+ }
+
+ public static void addSearchDirectory(final Path path) {
+ DIRECTORY_PROVIDERS.add(new CustomWellKnownDirectoryProvider(path.toString()));
+ }
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/DiscoveryDirectoryProvider.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/DiscoveryDirectoryProvider.java
new file mode 100644
index 0000000..2abd4b7
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/DiscoveryDirectoryProvider.java
@@ -0,0 +1,29 @@
+/*
+ * This file is part of VLCJ.
+ *
+ * VLCJ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * VLCJ is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with VLCJ. If not, see .
+ *
+ * Copyright 2009-2019 Caprica Software Limited.
+ */
+
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider;
+
+public interface DiscoveryDirectoryProvider {
+
+ int priority();
+
+ String[] directories();
+
+ boolean supported();
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/DiscoveryProviderPriority.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/DiscoveryProviderPriority.java
new file mode 100644
index 0000000..6754d66
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/DiscoveryProviderPriority.java
@@ -0,0 +1,30 @@
+/*
+ * This file is part of VLCJ.
+ *
+ * VLCJ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * VLCJ is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with VLCJ. If not, see .
+ *
+ * Copyright 2009-2019 Caprica Software Limited.
+ */
+
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider;
+
+public interface DiscoveryProviderPriority {
+
+ int CONFIG_FILE = 1;
+ int JNA_LIBRARY_PATH = -1;
+ int USER_DIR = -2;
+ int INSTALL_DIR = -3;
+ int WELL_KNOWN_DIRECTORY = -3;
+ int SYSTEM_PATH = -4;
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/WellKnownDirectoryProvider.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/WellKnownDirectoryProvider.java
new file mode 100644
index 0000000..f5b5b7c
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/WellKnownDirectoryProvider.java
@@ -0,0 +1,28 @@
+/*
+ * This file is part of VLCJ.
+ *
+ * VLCJ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * VLCJ is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with VLCJ. If not, see .
+ *
+ * Copyright 2009-2019 Caprica Software Limited.
+ */
+
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider;
+
+public abstract class WellKnownDirectoryProvider implements DiscoveryDirectoryProvider {
+
+ @Override
+ public int priority() {
+ return DiscoveryProviderPriority.WELL_KNOWN_DIRECTORY;
+ }
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/linux/LinuxWellKnownDirectoryProvider.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/linux/LinuxWellKnownDirectoryProvider.java
new file mode 100644
index 0000000..c5cc181
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/linux/LinuxWellKnownDirectoryProvider.java
@@ -0,0 +1,52 @@
+/*
+ * This file is part of VLCJ.
+ *
+ * VLCJ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * VLCJ is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with VLCJ. If not, see .
+ *
+ * Copyright 2009-2019 Caprica Software Limited.
+ */
+
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.linux;
+
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.WellKnownDirectoryProvider;
+import uk.co.caprica.vlcj.binding.RuntimeUtil;
+
+public class LinuxWellKnownDirectoryProvider extends WellKnownDirectoryProvider {
+
+ private static final String[] DIRECTORIES;
+
+ static {
+ final String usr = "/usr";
+ final String lib = String.format("%s/lib", usr);
+ final String locallib = "/usr/local/lib";
+ DIRECTORIES = new String[]{
+ String.format("%s/x86_64-linux-gnu", lib),
+ String.format("%s64", lib),
+ String.format("%s/lib64", locallib),
+ String.format("%s/i386-linux-gnu", lib),
+ lib,
+ locallib
+ };
+ }
+
+ @Override
+ public String[] directories() {
+ return DIRECTORIES;
+ }
+
+ @Override
+ public boolean supported() {
+ return RuntimeUtil.isNix();
+ }
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/misc/ConfigurationFileDiscoveryDirectoryProvider.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/misc/ConfigurationFileDiscoveryDirectoryProvider.java
new file mode 100644
index 0000000..d7c37ba
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/misc/ConfigurationFileDiscoveryDirectoryProvider.java
@@ -0,0 +1,69 @@
+/*
+ * This file is part of VLCJ.
+ *
+ * VLCJ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * VLCJ is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with VLCJ. If not, see .
+ *
+ * Copyright 2009-2020 Caprica Software Limited.
+ */
+
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.misc;
+
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.DiscoveryDirectoryProvider;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.DiscoveryProviderPriority;
+import java.io.IOException;
+import java.io.Reader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Properties;
+
+public class ConfigurationFileDiscoveryDirectoryProvider implements DiscoveryDirectoryProvider {
+
+ private static final String CONFIG_DIR;
+ private static final String CONFIG_FILE_NAME;
+ private static final String PROPERTY_NAME;
+
+ static {
+ CONFIG_DIR = String.format("%s/.config/vlcj", System.getProperty("user.home"));
+ CONFIG_FILE_NAME = "vlcj.config";
+ PROPERTY_NAME = "nativeDirectory";
+ }
+
+ @Override
+ public int priority() {
+ return DiscoveryProviderPriority.CONFIG_FILE;
+ }
+
+ @Override
+ public String[] directories() {
+ final Path file = Paths.get(CONFIG_DIR, CONFIG_FILE_NAME);
+ final Properties properties = new Properties();
+ try (final Reader reader = Files.newBufferedReader(file)) {
+ properties.load(reader);
+ final String directory = properties.getProperty(PROPERTY_NAME);
+ if (directory != null) {
+ return new String[]{directory};
+ }
+ } catch (final IOException e) {
+ e.printStackTrace();
+ }
+ return new String[0];
+ }
+
+ @Override
+ public boolean supported() {
+ final Path file = Paths.get(CONFIG_DIR, CONFIG_FILE_NAME);
+ return Files.exists(file) && Files.isRegularFile(file) && Files.isReadable(file);
+ }
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/misc/CustomWellKnownDirectoryProvider.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/misc/CustomWellKnownDirectoryProvider.java
new file mode 100644
index 0000000..11803b1
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/misc/CustomWellKnownDirectoryProvider.java
@@ -0,0 +1,28 @@
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.misc;
+
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.DiscoveryDirectoryProvider;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.DiscoveryProviderPriority;
+
+public class CustomWellKnownDirectoryProvider implements DiscoveryDirectoryProvider {
+
+ private final String[] directories;
+
+ public CustomWellKnownDirectoryProvider(final String... directories) {
+ this.directories = directories;
+ }
+
+ @Override
+ public int priority() {
+ return DiscoveryProviderPriority.WELL_KNOWN_DIRECTORY;
+ }
+
+ @Override
+ public String[] directories() {
+ return this.directories;
+ }
+
+ @Override
+ public boolean supported() {
+ return true;
+ }
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/misc/JnaLibraryPathDirectoryProvider.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/misc/JnaLibraryPathDirectoryProvider.java
new file mode 100644
index 0000000..7e36cb6
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/misc/JnaLibraryPathDirectoryProvider.java
@@ -0,0 +1,47 @@
+/*
+ * This file is part of VLCJ.
+ *
+ * VLCJ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * VLCJ is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with VLCJ. If not, see .
+ *
+ * Copyright 2009-2019 Caprica Software Limited.
+ */
+
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.misc;
+
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.DiscoveryDirectoryProvider;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.DiscoveryProviderPriority;
+
+public class JnaLibraryPathDirectoryProvider implements DiscoveryDirectoryProvider {
+
+ private static final String SYSTEM_PROPERTY_NAME;
+
+ static {
+ SYSTEM_PROPERTY_NAME = "jna.library.path";
+ }
+
+ @Override
+ public int priority() {
+ return DiscoveryProviderPriority.JNA_LIBRARY_PATH;
+ }
+
+ @Override
+ public String[] directories() {
+ return System.getProperty("jna.library.path").split("/");
+ }
+
+ @Override
+ public boolean supported() {
+ return System.getProperty(SYSTEM_PROPERTY_NAME) != null;
+ }
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/osx/OsxWellKnownDirectoryProvider.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/osx/OsxWellKnownDirectoryProvider.java
new file mode 100644
index 0000000..190ef0d
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/osx/OsxWellKnownDirectoryProvider.java
@@ -0,0 +1,47 @@
+/*
+ * This file is part of VLCJ.
+ *
+ * VLCJ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * VLCJ is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with VLCJ. If not, see .
+ *
+ * Copyright 2009-2019 Caprica Software Limited.
+ */
+
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.osx;
+
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.WellKnownDirectoryProvider;
+import uk.co.caprica.vlcj.binding.RuntimeUtil;
+
+public class OsxWellKnownDirectoryProvider extends WellKnownDirectoryProvider {
+
+ private static final String[] DIRECTORIES;
+
+ static {
+ final String contents = "/Applications/VLC.app/Contents";
+ DIRECTORIES = new String[]{
+ String.format("%s/Frameworks", contents),
+ String.format("%s/MacOS/lib", contents)
+ };
+ }
+
+ @Override
+ public String[] directories() {
+ return DIRECTORIES;
+ }
+
+ @Override
+ public boolean supported() {
+ return RuntimeUtil.isMac();
+ }
+
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/path/SystemPathDirectoryProvider.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/path/SystemPathDirectoryProvider.java
new file mode 100644
index 0000000..ca62185
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/path/SystemPathDirectoryProvider.java
@@ -0,0 +1,43 @@
+/*
+ * This file is part of VLCJ.
+ *
+ * VLCJ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * VLCJ is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with VLCJ. If not, see .
+ *
+ * Copyright 2009-2019 Caprica Software Limited.
+ */
+
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.path;
+
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.DiscoveryDirectoryProvider;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.DiscoveryProviderPriority;
+
+public class SystemPathDirectoryProvider implements DiscoveryDirectoryProvider {
+
+ @Override
+ public int priority() {
+ return DiscoveryProviderPriority.SYSTEM_PATH;
+ }
+
+ @Override
+ public String[] directories() {
+ final String path = System.getenv("PATH");
+ return path != null ? path.split("/") : new String[0];
+ }
+
+ @Override
+ public boolean supported() {
+ return true;
+ }
+
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/path/UserDirDirectoryProvider.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/path/UserDirDirectoryProvider.java
new file mode 100644
index 0000000..877accd
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/path/UserDirDirectoryProvider.java
@@ -0,0 +1,43 @@
+/*
+ * This file is part of VLCJ.
+ *
+ * VLCJ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * VLCJ is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with VLCJ. If not, see .
+ *
+ * Copyright 2009-2019 Caprica Software Limited.
+ */
+
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.path;
+
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.DiscoveryDirectoryProvider;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.DiscoveryProviderPriority;
+
+public class UserDirDirectoryProvider implements DiscoveryDirectoryProvider {
+
+ @Override
+ public int priority() {
+ return DiscoveryProviderPriority.USER_DIR;
+ }
+
+ @Override
+ public String[] directories() {
+ final String path = System.getProperty("user.dir");
+ return path != null ? new String[]{path} : new String[0];
+ }
+
+ @Override
+ public boolean supported() {
+ return true;
+ }
+
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/win/WindowsInstallDirectoryProvider.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/win/WindowsInstallDirectoryProvider.java
new file mode 100644
index 0000000..88a7574
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/provider/win/WindowsInstallDirectoryProvider.java
@@ -0,0 +1,63 @@
+/*
+ * This file is part of VLCJ.
+ *
+ * VLCJ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * VLCJ is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with VLCJ. If not, see .
+ *
+ * Copyright 2009-2019 Caprica Software Limited.
+ */
+
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.win;
+
+import static com.sun.jna.platform.win32.WinReg.HKEY_LOCAL_MACHINE;
+
+import com.sun.jna.platform.win32.Advapi32Util;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.DiscoveryDirectoryProvider;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.DiscoveryProviderPriority;
+import uk.co.caprica.vlcj.binding.RuntimeUtil;
+
+public class WindowsInstallDirectoryProvider implements DiscoveryDirectoryProvider {
+
+ private static final String VLC_REGISTRY_KEY;
+ private static final String VLC_INSTALL_DIR_KEY;
+
+ static {
+ VLC_REGISTRY_KEY = "SOFTWARE\\VideoLAN\\VLC";
+ VLC_INSTALL_DIR_KEY = "InstallDir";
+ }
+
+ @Override
+ public int priority() {
+ return DiscoveryProviderPriority.INSTALL_DIR;
+ }
+
+ @Override
+ public String[] directories() {
+ final String installDir = this.getVlcInstallDir();
+ return installDir != null ? new String[]{installDir} : new String[0];
+ }
+
+ @Override
+ public boolean supported() {
+ return RuntimeUtil.isWindows();
+ }
+
+ private String getVlcInstallDir() {
+ try {
+ return Advapi32Util.registryGetStringValue(HKEY_LOCAL_MACHINE, VLC_REGISTRY_KEY,
+ VLC_INSTALL_DIR_KEY);
+ } catch (final Exception e) {
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/strategy/BaseNativeDiscoveryStrategy.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/strategy/BaseNativeDiscoveryStrategy.java
new file mode 100644
index 0000000..0c8e7c1
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/strategy/BaseNativeDiscoveryStrategy.java
@@ -0,0 +1,118 @@
+/*
+ * This file is part of VLCJ.
+ *
+ * VLCJ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * VLCJ is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with VLCJ. If not, see .
+ *
+ * Copyright 2009-2019 Caprica Software Limited.
+ */
+
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.search.strategy;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Predicate;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Stream;
+
+public abstract class BaseNativeDiscoveryStrategy implements NativeDiscoveryStrategy {
+
+ public static final String PLUGIN_ENV_NAME = "VLC_PLUGIN_PATH";
+
+ private final Pattern[] patternsToMatch;
+ private final String[] pluginPathFormats;
+
+ public BaseNativeDiscoveryStrategy(final String[] filenamePatterns,
+ final String[] pluginPathFormats) {
+ this.patternsToMatch = new Pattern[filenamePatterns.length];
+ this.pluginPathFormats = pluginPathFormats;
+ this.compilePatterns(filenamePatterns);
+ }
+
+ private void compilePatterns(final String[] filenamePatterns) {
+ for (int i = 0; i < filenamePatterns.length; i++) {
+ this.patternsToMatch[i] = Pattern.compile(filenamePatterns[i]);
+ }
+ }
+
+ @Override
+ public final Optional discover() {
+ return this.discoveryDirectories().stream().parallel().filter(this::find).findAny();
+ }
+
+ protected abstract List discoveryDirectories();
+
+ private boolean find(final String directoryName) {
+
+ final Path dir = Paths.get(directoryName);
+ if (Files.notExists(dir)) {
+ return false;
+ }
+
+ final Set matches = new HashSet<>(this.patternsToMatch.length);
+ try (final Stream stream = Files.walk(dir, 1).parallel()) {
+ return stream.anyMatch(this.getMatchingPatternFile(matches));
+ } catch (final IOException e) {
+ e.printStackTrace();
+ }
+
+ return false;
+ }
+
+ private Predicate getMatchingPatternFile(final Set matches) {
+ return file -> {
+ for (final Pattern pattern : this.patternsToMatch) {
+ if (this.validatePattern(matches, file, pattern)) {
+ return true;
+ }
+ }
+ return false;
+ };
+ }
+
+ private boolean validatePattern(final Set matches, final Path file,
+ final Pattern pattern) {
+ final Matcher matcher = pattern.matcher(file.getFileName().toString());
+ if (matcher.matches()) {
+ matches.add(pattern.pattern());
+ return matches.size() == this.patternsToMatch.length;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onFound(final String path) {
+ return true;
+ }
+
+ @Override
+ public final boolean onSetPluginPath(final String path) {
+ for (final String pathFormat : this.pluginPathFormats) {
+ final String pluginPath = String.format(pathFormat, path);
+ if (Files.exists(Paths.get(pluginPath))) {
+ return this.setPluginPath(pluginPath);
+ }
+ }
+ return false;
+ }
+
+ protected abstract boolean setPluginPath(String pluginPath);
+
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/strategy/NativeDiscoveryStrategy.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/strategy/NativeDiscoveryStrategy.java
new file mode 100644
index 0000000..698a55c
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/strategy/NativeDiscoveryStrategy.java
@@ -0,0 +1,33 @@
+/*
+ * This file is part of VLCJ.
+ *
+ * VLCJ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * VLCJ is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with VLCJ. If not, see .
+ *
+ * Copyright 2009-2019 Caprica Software Limited.
+ */
+
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.search.strategy;
+
+import java.util.Optional;
+
+public interface NativeDiscoveryStrategy {
+
+ boolean supported();
+
+ Optional discover();
+
+ boolean onFound(String path);
+
+ boolean onSetPluginPath(String path);
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/strategy/linux/LinuxNativeDiscoveryStrategy.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/strategy/linux/LinuxNativeDiscoveryStrategy.java
new file mode 100644
index 0000000..a284828
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/strategy/linux/LinuxNativeDiscoveryStrategy.java
@@ -0,0 +1,51 @@
+/*
+ * This file is part of VLCJ.
+ *
+ * VLCJ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * VLCJ is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with VLCJ. If not, see .
+ *
+ * Copyright 2009-2019 Caprica Software Limited.
+ */
+
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.search.strategy.linux;
+
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.DirectoryProviderDiscoveryStrategy;
+import uk.co.caprica.vlcj.binding.LibC;
+import uk.co.caprica.vlcj.binding.RuntimeUtil;
+
+public class LinuxNativeDiscoveryStrategy extends DirectoryProviderDiscoveryStrategy {
+
+ private static final String[] FILENAME_PATTERNS = new String[]{
+ "libvlc\\.so(?:\\.\\d)*",
+ "libvlccore\\.so(?:\\.\\d)*"
+ };
+
+ private static final String[] PLUGIN_PATH_FORMATS = new String[]{
+ "%s/plugins",
+ "%s/vlc/plugins"
+ };
+
+ public LinuxNativeDiscoveryStrategy() {
+ super(FILENAME_PATTERNS, PLUGIN_PATH_FORMATS);
+ }
+
+ @Override
+ public boolean supported() {
+ return RuntimeUtil.isNix();
+ }
+
+ @Override
+ protected boolean setPluginPath(final String pluginPath) {
+ return LibC.INSTANCE.setenv(PLUGIN_ENV_NAME, pluginPath, 1) == 0;
+ }
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/strategy/osx/OsxNativeDiscoveryStrategy.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/strategy/osx/OsxNativeDiscoveryStrategy.java
new file mode 100644
index 0000000..35eda67
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/strategy/osx/OsxNativeDiscoveryStrategy.java
@@ -0,0 +1,62 @@
+/*
+ * This file is part of VLCJ.
+ *
+ * VLCJ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * VLCJ is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with VLCJ. If not, see .
+ *
+ * Copyright 2009-2019 Caprica Software Limited.
+ */
+
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.search.strategy.osx;
+
+import com.sun.jna.NativeLibrary;
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.DirectoryProviderDiscoveryStrategy;
+import uk.co.caprica.vlcj.binding.LibC;
+import uk.co.caprica.vlcj.binding.RuntimeUtil;
+
+public class OsxNativeDiscoveryStrategy extends DirectoryProviderDiscoveryStrategy {
+
+ private static final String[] FILENAME_PATTERNS = new String[]{
+ "libvlc\\.dylib",
+ "libvlccore\\.dylib"
+ };
+
+ private static final String[] PLUGIN_PATH_FORMATS = new String[]{
+ "%s/../plugins"
+ };
+
+ public OsxNativeDiscoveryStrategy() {
+ super(FILENAME_PATTERNS, PLUGIN_PATH_FORMATS);
+ }
+
+ @Override
+ public boolean supported() {
+ return RuntimeUtil.isMac();
+ }
+
+ @Override
+ public boolean onFound(final String path) {
+ this.forceLoadLibVlcCore(path);
+ return true;
+ }
+
+ private void forceLoadLibVlcCore(final String path) {
+ NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcCoreLibraryName(), path);
+ NativeLibrary.getInstance(RuntimeUtil.getLibVlcCoreLibraryName());
+ }
+
+ @Override
+ protected boolean setPluginPath(final String pluginPath) {
+ return LibC.INSTANCE.setenv(PLUGIN_ENV_NAME, pluginPath, 1) == 0;
+ }
+}
diff --git a/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/strategy/win/WindowsNativeDiscoveryStrategy.java b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/strategy/win/WindowsNativeDiscoveryStrategy.java
new file mode 100644
index 0000000..6174238
--- /dev/null
+++ b/src/main/java/io/github/pulsebeat02/emcinstallers/implementation/vlc/search/strategy/win/WindowsNativeDiscoveryStrategy.java
@@ -0,0 +1,51 @@
+/*
+ * This file is part of VLCJ.
+ *
+ * VLCJ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * VLCJ is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with VLCJ. If not, see .
+ *
+ * Copyright 2009-2019 Caprica Software Limited.
+ */
+
+package io.github.pulsebeat02.emcinstallers.implementation.vlc.search.strategy.win;
+
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.search.provider.DirectoryProviderDiscoveryStrategy;
+import uk.co.caprica.vlcj.binding.LibC;
+import uk.co.caprica.vlcj.binding.RuntimeUtil;
+
+public class WindowsNativeDiscoveryStrategy extends DirectoryProviderDiscoveryStrategy {
+
+ private static final String[] FILENAME_PATTERNS = new String[]{
+ "libvlc\\.dll",
+ "libvlccore\\.dll"
+ };
+
+ private static final String[] PLUGIN_PATH_FORMATS = new String[]{
+ "%s\\plugins",
+ "%s\\vlc\\plugins"
+ };
+
+ public WindowsNativeDiscoveryStrategy() {
+ super(FILENAME_PATTERNS, PLUGIN_PATH_FORMATS);
+ }
+
+ @Override
+ public boolean supported() {
+ return RuntimeUtil.isWindows();
+ }
+
+ @Override
+ protected boolean setPluginPath(final String pluginPath) {
+ return LibC.INSTANCE._putenv(String.format("%s=%s", PLUGIN_ENV_NAME, pluginPath)) == 0;
+ }
+}
diff --git a/src/test/java/io/github/pulsebeat02/ffmpeginstaller/InstallerTest.java b/src/test/java/io/github/pulsebeat02/ffmpeginstaller/InstallerTest.java
new file mode 100644
index 0000000..a06f755
--- /dev/null
+++ b/src/test/java/io/github/pulsebeat02/ffmpeginstaller/InstallerTest.java
@@ -0,0 +1,12 @@
+package io.github.pulsebeat02.ffmpeginstaller;
+
+import io.github.pulsebeat02.emcinstallers.implementation.vlc.VLCInstallationKit;
+import java.io.IOException;
+
+public final class InstallerTest {
+
+ public static void main(final String[] args) throws IOException {
+ final VLCInstallationKit kit = VLCInstallationKit.create();
+ System.out.println(kit.start().get());
+ }
+}