diff --git a/EOCV-Sim/build.gradle b/EOCV-Sim/build.gradle index dfa77ef..b014a1e 100644 --- a/EOCV-Sim/build.gradle +++ b/EOCV-Sim/build.gradle @@ -75,9 +75,6 @@ dependencies { implementation "org.apache.logging.log4j:log4j-slf4j2-impl:$log4j_version" implementation "com.github.deltacv:steve:1.1.1" - api("com.github.deltacv:AprilTagDesktop:$apriltag_plugin_version") { - exclude group: 'com.github.deltacv.EOCVSim', module: 'Common' - } implementation 'info.picocli:picocli:4.6.1' implementation 'com.google.code.gson:gson:2.8.9' diff --git a/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/gui/dialog/SuperAccessRequest.kt b/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/gui/dialog/SuperAccessRequest.kt index 6b8d807..58d98dc 100644 --- a/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/gui/dialog/SuperAccessRequest.kt +++ b/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/gui/dialog/SuperAccessRequest.kt @@ -1,165 +1,169 @@ -/* - * Copyright (c) 2024 Sebastian Erives - * - * 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.deltacv.eocvsim.gui.dialog - -import com.formdev.flatlaf.FlatLightLaf -import com.formdev.flatlaf.intellijthemes.FlatArcDarkIJTheme -import com.formdev.flatlaf.intellijthemes.FlatArcOrangeIJTheme -import com.formdev.flatlaf.intellijthemes.FlatCobalt2IJTheme -import com.github.serivesmejia.eocvsim.gui.EOCVSimIconLibrary -import com.github.serivesmejia.eocvsim.gui.Icons -import com.github.serivesmejia.eocvsim.gui.Icons.getImage -import java.awt.BorderLayout -import java.awt.Dimension -import java.awt.Font -import java.awt.event.WindowEvent -import java.awt.event.WindowListener -import javax.swing.* -import kotlin.system.exitProcess - -class SuperAccessRequest(sourceName: String, reason: String) { - - init { - FlatArcDarkIJTheme.setup() - - val panel = JPanel(BorderLayout()) - val frame = JDialog() - - frame.title = "EOCV-Sim SuperAccess Request" - - // Create UI components - val titleLabel = JLabel("SuperAccess request from $sourceName", JLabel.CENTER) - - // Set the font of the JLabel to bold - titleLabel.font = titleLabel.font.deriveFont(Font.BOLD, 21f) - - // Text Area for Reason Input - val reasonTextArea = JTextPane().apply { - isEditable = false - contentType = "text/html" - - font = font.deriveFont(18f) - - var formattedReason = "" - - for(line in reason.split("
")) { - formattedReason += wrapText(line, 80) + "
" - } - - text = formattedReason - } - val scrollPane = JScrollPane(reasonTextArea) - - // Create a panel for buttons - val buttonPanel = JPanel().apply { - layout = BoxLayout(this, BoxLayout.X_AXIS) - val acceptButton = JButton("Accept").apply { - preferredSize = Dimension(100, 30) - addActionListener { - exitProcess(171) - } - } - - val rejectButton = JButton("Reject").apply { - preferredSize = Dimension(100, 30) - addActionListener { - exitProcess(-172) - } - } - - add(Box.createHorizontalGlue()) // Push buttons to the center - add(acceptButton) - add(Box.createRigidArea(Dimension(10, 0))) // Space between buttons - add(rejectButton) - add(Box.createHorizontalGlue()) // Push buttons to the center - } - - // Add components to the panel - panel.add(titleLabel, BorderLayout.NORTH) - panel.add(scrollPane, BorderLayout.CENTER) - panel.add(buttonPanel, BorderLayout.SOUTH) - - // Setup the frame - frame.contentPane = panel - frame.isAlwaysOnTop = true - frame.defaultCloseOperation = JDialog.HIDE_ON_CLOSE - frame.isResizable = false - - frame.addWindowListener(object: WindowListener { - override fun windowOpened(e: WindowEvent?) {} - override fun windowClosing(e: WindowEvent?) {} - override fun windowIconified(e: WindowEvent?) {} - override fun windowDeiconified(e: WindowEvent?) {} - override fun windowActivated(e: WindowEvent?) {} - override fun windowDeactivated(e: WindowEvent?) {} - - override fun windowClosed(e: WindowEvent?) { - exitProcess(-129) - } - }) - - frame.setIconImage(EOCVSimIconLibrary.icoEOCVSim.image) - - frame.pack() - - frame.setLocationRelativeTo(null) // Center the window on the screen - frame.isVisible = true - } - -} - -private fun wrapText(text: String, maxLineLength: Int): String { - val words = text.split(" ") - val wrappedLines = mutableListOf() - var currentLine = StringBuilder() - val breakTag = "
" // HTML break tag - - for (word in words) { - // Calculate the length of the line with a break tag - val lineWithWord = if (currentLine.isEmpty()) { - word - } else { - "$currentLine $word" - } - val lineLengthWithBreak = lineWithWord.length + (if (currentLine.isEmpty()) 0 else breakTag.length) - - // Check if adding the next word exceeds the maxLineLength - if (lineLengthWithBreak > maxLineLength) { - // If it does, add the current line to the list and start a new line - wrappedLines.add(currentLine.toString()) - currentLine = StringBuilder(word) - } else { - // Append the word to the current line - currentLine.append(" ").append(word) - } - } - - // Add the last line if it's not empty - if (currentLine.isNotEmpty()) { - wrappedLines.add(currentLine.toString()) - } - - // Join all lines with
for HTML - return wrappedLines.joinToString(breakTag) +/* + * Copyright (c) 2024 Sebastian Erives + * + * 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.deltacv.eocvsim.gui.dialog + +import com.formdev.flatlaf.FlatLightLaf +import com.formdev.flatlaf.intellijthemes.FlatArcDarkIJTheme +import com.formdev.flatlaf.intellijthemes.FlatArcOrangeIJTheme +import com.formdev.flatlaf.intellijthemes.FlatCobalt2IJTheme +import com.github.serivesmejia.eocvsim.gui.EOCVSimIconLibrary +import com.github.serivesmejia.eocvsim.gui.Icons +import com.github.serivesmejia.eocvsim.gui.Icons.getImage +import java.awt.BorderLayout +import java.awt.Dimension +import java.awt.Font +import java.awt.event.WindowEvent +import java.awt.event.WindowListener +import javax.swing.* + +class SuperAccessRequest(sourceName: String, reason: String, val callback: (Boolean) -> Unit) { + + init { + FlatArcDarkIJTheme.setup() + + val panel = JPanel(BorderLayout()) + val frame = JDialog() + + frame.title = "EOCV-Sim SuperAccess Request" + + // Create UI components + val titleLabel = JLabel("SuperAccess request from $sourceName", JLabel.CENTER) + + // Set the font of the JLabel to bold + titleLabel.font = titleLabel.font.deriveFont(Font.BOLD, 21f) + + // Text Area for Reason Input + val reasonTextArea = JTextPane().apply { + isEditable = false + contentType = "text/html" + + font = font.deriveFont(18f) + + var formattedReason = "" + + for(line in reason.split("
")) { + formattedReason += wrapText(line, 80) + "
" + } + + text = formattedReason + } + val scrollPane = JScrollPane(reasonTextArea) + + // Create a panel for buttons + val buttonPanel = JPanel().apply { + layout = BoxLayout(this, BoxLayout.X_AXIS) + val acceptButton = JButton("Accept").apply { + preferredSize = Dimension(100, 30) + addActionListener { + callback(true) + + frame.isVisible = false + frame.dispose() + } + } + + val rejectButton = JButton("Reject").apply { + preferredSize = Dimension(100, 30) + addActionListener { + callback(false) + + frame.isVisible = false + frame.dispose() + } + } + + add(Box.createHorizontalGlue()) // Push buttons to the center + add(acceptButton) + add(Box.createRigidArea(Dimension(10, 0))) // Space between buttons + add(rejectButton) + add(Box.createHorizontalGlue()) // Push buttons to the center + } + + // Add components to the panel + panel.add(titleLabel, BorderLayout.NORTH) + panel.add(scrollPane, BorderLayout.CENTER) + panel.add(buttonPanel, BorderLayout.SOUTH) + + // Setup the frame + frame.contentPane = panel + frame.isAlwaysOnTop = true + frame.defaultCloseOperation = JDialog.HIDE_ON_CLOSE + frame.isResizable = false + + frame.addWindowListener(object: WindowListener { + override fun windowOpened(e: WindowEvent?) {} + override fun windowClosing(e: WindowEvent?) {} + override fun windowIconified(e: WindowEvent?) {} + override fun windowDeiconified(e: WindowEvent?) {} + override fun windowActivated(e: WindowEvent?) {} + override fun windowDeactivated(e: WindowEvent?) {} + + override fun windowClosed(e: WindowEvent?) { + } + }) + + frame.setIconImage(EOCVSimIconLibrary.icoEOCVSim.image) + + frame.pack() + + frame.setLocationRelativeTo(null) // Center the window on the screen + frame.isVisible = true + } + +} + +private fun wrapText(text: String, maxLineLength: Int): String { + val words = text.split(" ") + val wrappedLines = mutableListOf() + var currentLine = StringBuilder() + val breakTag = "
" // HTML break tag + + for (word in words) { + // Calculate the length of the line with a break tag + val lineWithWord = if (currentLine.isEmpty()) { + word + } else { + "$currentLine $word" + } + val lineLengthWithBreak = lineWithWord.length + (if (currentLine.isEmpty()) 0 else breakTag.length) + + // Check if adding the next word exceeds the maxLineLength + if (lineLengthWithBreak > maxLineLength) { + // If it does, add the current line to the list and start a new line + wrappedLines.add(currentLine.toString()) + currentLine = StringBuilder(word) + } else { + // Append the word to the current line + currentLine.append(" ").append(word) + } + } + + // Add the last line if it's not empty + if (currentLine.isNotEmpty()) { + wrappedLines.add(currentLine.toString()) + } + + // Join all lines with
for HTML + return wrappedLines.joinToString(breakTag) } \ No newline at end of file diff --git a/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/gui/dialog/SuperAccessRequestMain.java b/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/gui/dialog/SuperAccessRequestMain.java deleted file mode 100644 index 27d76e4..0000000 --- a/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/gui/dialog/SuperAccessRequestMain.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2024 Sebastian Erives - * - * 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.deltacv.eocvsim.gui.dialog; - -import javax.swing.*; - -public class SuperAccessRequestMain { - public static void main(String[] args) { - SwingUtilities.invokeLater(() -> new SuperAccessRequest(args[0].replace("-", " "), args[1].replace("-", " "))); - } -} diff --git a/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/plugin/security/PluginSignatureVerifier.kt b/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/plugin/security/PluginSignatureVerifier.kt index c1e84a5..4b2960c 100644 --- a/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/plugin/security/PluginSignatureVerifier.kt +++ b/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/plugin/security/PluginSignatureVerifier.kt @@ -26,6 +26,7 @@ package io.github.deltacv.eocvsim.plugin.security import com.github.serivesmejia.eocvsim.util.extension.hashString import com.github.serivesmejia.eocvsim.util.loggerForThis import com.moandjiezana.toml.Toml +import io.github.deltacv.eocvsim.plugin.loader.InvalidPluginException import java.io.File import java.security.PublicKey import java.security.Signature @@ -124,8 +125,8 @@ object PluginSignatureVerifier { val signatureStatus = mutableMapOf() - for(signature in signatures) { - signatureStatus[signature.key] = false + for(sign in signatures) { + signatureStatus[sign.key] = false } for (classEntry in classEntries) { @@ -139,8 +140,7 @@ object PluginSignatureVerifier { // Verify the signature of the class if (!verifySignature(classData, signatures[classHash]!!, publicKey)) { - logger.warn("Signature verification failed for class $className") - return emptyResult + throw InvalidPluginException("Signature verification failed for class $className. Please try to re-download the plugin or discard it immediately.") } else { signatureStatus[classHash] = true } diff --git a/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/plugin/security/PluginSigningTool.kt b/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/plugin/security/PluginSigningTool.kt index ce8cbb7..b6a4ee7 100644 --- a/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/plugin/security/PluginSigningTool.kt +++ b/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/plugin/security/PluginSigningTool.kt @@ -198,19 +198,22 @@ class PluginSigningTool : Runnable { } } -// Use System.in -fun main() { - val scanner = Scanner(System.`in`) +fun main(args: Array) { + if(args.isEmpty()) { + val scanner = Scanner(System.`in`) - val tool = PluginSigningTool() - println("Enter the plugin JAR file path:") - tool.pluginFile = scanner.next() + val tool = PluginSigningTool() + println("Enter the plugin JAR file path:") + tool.pluginFile = scanner.next() - println("Enter the authority to sign the plugin with:") - tool.authority = scanner.next() + println("Enter the authority to sign the plugin with:") + tool.authority = scanner.next() - println("Enter the private key file path:") - tool.privateKeyFile = scanner.next() + println("Enter the private key file path:") + tool.privateKeyFile = scanner.next() - tool.run() + tool.run() + } else { + CommandLine(PluginSigningTool()).execute(*args) + } } \ No newline at end of file diff --git a/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/plugin/security/superaccess/SuperAccessDaemon.kt b/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/plugin/security/superaccess/SuperAccessDaemon.kt index 3b7441c..4a23d9c 100644 --- a/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/plugin/security/superaccess/SuperAccessDaemon.kt +++ b/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/plugin/security/superaccess/SuperAccessDaemon.kt @@ -24,25 +24,30 @@ package io.github.deltacv.eocvsim.plugin.security.superaccess import com.github.serivesmejia.eocvsim.util.JavaProcess +import com.github.serivesmejia.eocvsim.util.SysUtil import com.github.serivesmejia.eocvsim.util.io.EOCVSimFolder import com.github.serivesmejia.eocvsim.util.loggerForThis import com.github.serivesmejia.eocvsim.util.extension.plus import com.github.serivesmejia.eocvsim.util.serialization.PolymorphicAdapter import com.google.gson.GsonBuilder import com.moandjiezana.toml.Toml -import io.github.deltacv.eocvsim.gui.dialog.SuperAccessRequestMain +import io.github.deltacv.eocvsim.gui.dialog.SuperAccessRequest +import javax.swing.SwingUtilities import io.github.deltacv.eocvsim.plugin.loader.PluginManager.Companion.GENERIC_LAWYER_YEET import io.github.deltacv.eocvsim.plugin.loader.PluginManager.Companion.GENERIC_SUPERACCESS_WARN import io.github.deltacv.eocvsim.plugin.loader.PluginParser import io.github.deltacv.eocvsim.plugin.security.Authority import io.github.deltacv.eocvsim.plugin.security.AuthorityFetcher import io.github.deltacv.eocvsim.plugin.security.MutablePluginSignature +import kotlinx.coroutines.newFixedThreadPoolContext import org.java_websocket.client.WebSocketClient import java.net.URI import org.java_websocket.handshake.ServerHandshake import java.util.zip.ZipFile import java.io.File import java.lang.Exception +import java.security.MessageDigest +import java.util.concurrent.Executors import kotlin.system.exitProcess object SuperAccessDaemon { @@ -88,6 +93,8 @@ object SuperAccessDaemon { class WsClient(port: Int) : WebSocketClient(URI("ws://localhost:$port")) { + private val executor = Executors.newFixedThreadPool(6) + override fun onOpen(p0: ServerHandshake?) { logger.info("SuperAccessDaemon connection opened") } @@ -95,21 +102,37 @@ object SuperAccessDaemon { override fun onMessage(msg: String) { val message = gson.fromJson(msg, SuperAccessMessage::class.java) - when(message) { - is SuperAccessMessage.Request -> { - handleRequest(message) - } + executor.submit { + when (message) { + is SuperAccessMessage.Request -> { + handleRequest(message) + } - is SuperAccessMessage.Check -> { - handleCheck(message) + is SuperAccessMessage.Check -> { + handleCheck(message) + } } } } private fun handleRequest(message: SuperAccessMessage.Request) { + val pluginFile = File(message.pluginPath) + + val parser = parsePlugin(pluginFile) ?: run { + logger.error("Failed to parse plugin at ${message.pluginPath}") + (gson.toJson(SuperAccessResponse.Failure(message.id))) + return@handleRequest + } + + if(SUPERACCESS_FILE.exists() && SUPERACCESS_FILE.readLines().contains(pluginFile.fileHash())) { + accessGranted(message.id, message.pluginPath) + return + } + logger.info("Requesting SuperAccess for ${message.pluginPath}") var validAuthority: Authority? = null + var untrusted = false if(message.signature.authority != null) { val declaredAuthority = message.signature.authority!! @@ -125,19 +148,17 @@ object SuperAccessDaemon { validAuthority = Authority(authorityName, fetchedAuthorityKey) } else { logger.warn("Authority key does not match the fetched key for $authorityName") + untrusted = true } } - } - - val parser = parsePlugin(File(message.pluginPath)) ?: run { - logger.error("Failed to parse plugin at ${message.pluginPath}") - (gson.toJson(SuperAccessResponse.Failure(message.id))) - return@handleRequest + } else { + val fetch = AuthorityFetcher.fetchAuthority(parser.pluginAuthor) + untrusted = fetch != null // the plugin is claiming to be made by the authority but it's not signed by them } val reason = message.reason - val name = "${parser.pluginName} v${parser.pluginVersion} by ${parser.pluginAuthor}".replace(" ", "-") + val name = "${parser.pluginName} v${parser.pluginVersion} by ${parser.pluginAuthor}" var warning = "$GENERIC_SUPERACCESS_WARN" if(reason.trim().isNotBlank()) { @@ -145,22 +166,24 @@ object SuperAccessDaemon { } warning += if(validAuthority != null) { - "

This plugin is signed by the trusted authority ${validAuthority.name}." + "

This plugin has been digitally signed by ${validAuthority.name}, ensuring its integrity and authenticity.
${validAuthority.name} is a trusted authority in the EOCV-Sim ecosystem." + } else if(untrusted) { + "

This plugin claims to be made by trusted authority ${parser.pluginAuthor}, but it has not been digitally signed by them.

Beware of potential security risks.

" } else { GENERIC_LAWYER_YEET } warning += "" - if(JavaProcess.exec(SuperAccessRequestMain::class.java, null, listOf(name, warning)) == 171) { - logger.info("SuperAccess granted to ${message.pluginPath}") - send(gson.toJson(SuperAccessResponse.Success(message.id))) - - SUPERACCESS_FILE.appendText("${parser.hash()}\n") - access[message.pluginPath] = true - } else { - logger.info("SuperAccess denied to ${message.pluginPath}") - send(gson.toJson(SuperAccessResponse.Failure(message.id))) + SwingUtilities.invokeLater { + SuperAccessRequest(name, warning) { granted -> + if(granted) { + SUPERACCESS_FILE.appendText(pluginFile.fileHash() + "\n") + accessGranted(message.id, message.pluginPath) + } else { + accessDenied(message.id, message.pluginPath) + } + } } } @@ -175,19 +198,27 @@ object SuperAccessDaemon { } } - val parser = parsePlugin(File(message.pluginPath)) ?: run { + val pluginFile = File(message.pluginPath) + + val parser = parsePlugin(pluginFile) ?: run { logger.error("Failed to parse plugin at ${message.pluginPath}") send(gson.toJson(SuperAccessResponse.Failure(message.id))) return } - if(SUPERACCESS_FILE.readLines().contains(parser.hash())) { + if(SUPERACCESS_FILE.exists() && SUPERACCESS_FILE.readLines().contains(pluginFile.fileHash())) { accessGranted(message.id, message.pluginPath) } else { accessDenied(message.id, message.pluginPath) } } + private fun File.fileHash(): String { + val messageDigest = MessageDigest.getInstance("SHA-256") + messageDigest.update(readBytes()) + return SysUtil.byteArray2Hex(messageDigest.digest()) + } + private fun accessGranted(id: Int, pluginPath: String) { access[pluginPath] = true send(gson.toJson(SuperAccessResponse.Success(id))) diff --git a/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/plugin/security/superaccess/SuperAccessDaemonClient.kt b/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/plugin/security/superaccess/SuperAccessDaemonClient.kt index 538d282..dac20ea 100644 --- a/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/plugin/security/superaccess/SuperAccessDaemonClient.kt +++ b/EOCV-Sim/src/main/java/io/github/deltacv/eocvsim/plugin/security/superaccess/SuperAccessDaemonClient.kt @@ -24,20 +24,16 @@ package io.github.deltacv.eocvsim.plugin.security.superaccess import com.github.serivesmejia.eocvsim.util.JavaProcess -import com.github.serivesmejia.eocvsim.util.event.EventHandler -import com.github.serivesmejia.eocvsim.util.event.EventListenerRemover import com.github.serivesmejia.eocvsim.util.loggerForThis -import org.firstinspires.ftc.robotcore.internal.collections.EvictingBlockingQueue -import java.util.concurrent.ArrayBlockingQueue import org.java_websocket.WebSocket import org.java_websocket.handshake.ClientHandshake import org.java_websocket.server.WebSocketServer -import java.lang.Exception import java.io.File +import java.lang.Exception import java.net.InetSocketAddress import java.util.concurrent.Executors -import java.util.concurrent.locks.ReentrantLock import java.util.concurrent.locks.Condition +import java.util.concurrent.locks.ReentrantLock import kotlin.concurrent.withLock typealias ResponseReceiver = (SuperAccessDaemon.SuperAccessResponse) -> Unit diff --git a/Vision/build.gradle b/Vision/build.gradle index d62ff8c..ad38e4b 100644 --- a/Vision/build.gradle +++ b/Vision/build.gradle @@ -28,7 +28,7 @@ configurations.all { dependencies { implementation project(':Common') - implementation("com.github.deltacv:AprilTagDesktop:$apriltag_plugin_version") { + api("com.github.deltacv:AprilTagDesktop:$apriltag_plugin_version") { exclude group: 'com.github.deltacv.EOCVSim', module: 'Common' }