From 6f3644e995d50f4d4e47b81985b298ad8dc50751 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Tue, 24 Nov 2015 21:31:48 +0100 Subject: [PATCH] Add more commands --- .../java/net/pterodactylus/fcp/FreenetBase64.java | 90 ++++++++++++++++++++++ src/main/java/net/pterodactylus/fcp/Key.java | 20 +++++ .../java/net/pterodactylus/fcp/LoadPlugin.java | 47 +++++++++++ .../java/net/pterodactylus/fcp/PeerNoteType.java | 23 ++++++ .../java/net/pterodactylus/fcp/ReloadPlugin.java | 31 ++++++++ .../net/pterodactylus/fcp/RequestProgress.java | 63 +++++++++++++++ .../java/net/pterodactylus/fcp/UnsubscribeUSK.java | 15 ++++ 7 files changed, 289 insertions(+) create mode 100644 src/main/java/net/pterodactylus/fcp/FreenetBase64.java create mode 100644 src/main/java/net/pterodactylus/fcp/Key.java create mode 100644 src/main/java/net/pterodactylus/fcp/LoadPlugin.java create mode 100644 src/main/java/net/pterodactylus/fcp/PeerNoteType.java create mode 100644 src/main/java/net/pterodactylus/fcp/ReloadPlugin.java create mode 100644 src/main/java/net/pterodactylus/fcp/RequestProgress.java create mode 100644 src/main/java/net/pterodactylus/fcp/UnsubscribeUSK.java diff --git a/src/main/java/net/pterodactylus/fcp/FreenetBase64.java b/src/main/java/net/pterodactylus/fcp/FreenetBase64.java new file mode 100644 index 0000000..4c3422d --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/FreenetBase64.java @@ -0,0 +1,90 @@ +package net.pterodactylus.fcp; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * Freenet-specific Base64 implementation. + * + * @author David ‘Bombe’ Roden + */ +public class FreenetBase64 { + + private static final char[] FREENET_BASE64_ALPHABET = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~-".toCharArray(); + private static final int[] REVERSE_FREENET_BASE64_ALPHABET = reverse(FREENET_BASE64_ALPHABET); + + private static int[] reverse(char[] alphabet) { + String alphabetString = new String(alphabet); + int[] reversedAlphabet = new int[128]; + for (int i = 0; i < 128; i++) { + if (alphabetString.indexOf(i) > -1) { + reversedAlphabet[i] = alphabetString.indexOf(i); + } else { + reversedAlphabet[i] = -1; + } + } + return reversedAlphabet; + } + + public String encode(byte[] data) { + StringBuilder result = new StringBuilder(); + int currentValue = 0; + int index = 0; + while (index < data.length) { + currentValue = (currentValue << 8) | data[index]; + if (index % 3 == 2) { + result.append(FREENET_BASE64_ALPHABET[(currentValue >> 18) & 0x3f]); + result.append(FREENET_BASE64_ALPHABET[(currentValue >> 12) & 0x3f]); + result.append(FREENET_BASE64_ALPHABET[(currentValue >> 6) & 0x3f]); + result.append(FREENET_BASE64_ALPHABET[currentValue & 0x3f]); + } + index++; + } + if (index % 3 == 1) { + result.append(FREENET_BASE64_ALPHABET[(currentValue >> 2) & 0x3f]); + result.append(FREENET_BASE64_ALPHABET[(currentValue << 4) & 0x3f]); + result.append("=="); + } else if (index % 3 == 2) { + result.append(FREENET_BASE64_ALPHABET[(currentValue >> 10) & 0x3f]); + result.append(FREENET_BASE64_ALPHABET[(currentValue >> 4) & 0x3f]); + result.append(FREENET_BASE64_ALPHABET[(currentValue << 2) & 0x3f]); + result.append("="); + } + return result.toString(); + } + + public byte[] decode(String data) { + ByteArrayOutputStream dataOutput = new ByteArrayOutputStream(data.length() * 3 / 4); + try { + int currentValue = 0; + int index = 0; + for (char c : data.toCharArray()) { + if (c == '=') { + break; + } + currentValue = (currentValue << 6) | REVERSE_FREENET_BASE64_ALPHABET[c]; + if (index % 4 == 3) { + dataOutput.write((currentValue >> 16) & 0xff); + dataOutput.write((currentValue >> 8) & 0xff); + dataOutput.write(currentValue & 0xff); + } + index++; + } + if (index % 4 == 2) { + dataOutput.write((currentValue >> 4) & 0xff); + } else if (index % 4 == 3) { + dataOutput.write((currentValue >> 10) & 0xff); + dataOutput.write((currentValue >> 2) & 0xff); + } + return dataOutput.toByteArray(); + } finally { + try { + dataOutput.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + +} diff --git a/src/main/java/net/pterodactylus/fcp/Key.java b/src/main/java/net/pterodactylus/fcp/Key.java new file mode 100644 index 0000000..f16b752 --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/Key.java @@ -0,0 +1,20 @@ +package net.pterodactylus.fcp; + +/** + * Non-validating wrapper around a Freenet key. + * + * @author David ‘Bombe’ Roden + */ +public class Key { + + private final String key; + + public Key(String key) { + this.key = key; + } + + public String getKey() { + return key; + } + +} diff --git a/src/main/java/net/pterodactylus/fcp/LoadPlugin.java b/src/main/java/net/pterodactylus/fcp/LoadPlugin.java new file mode 100644 index 0000000..9eb2d2d --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/LoadPlugin.java @@ -0,0 +1,47 @@ +package net.pterodactylus.fcp; + +/** + * The “LoadPlugin” message is used to load a plugin. + * + * @author David ‘Bombe’ Roden + */ +public class LoadPlugin extends FcpMessage { + + public enum UrlType { + + OFFICIAL, + FILE, + FREENET, + URL + + } + + public enum OfficialSource { + + FREENET, + HTTPS + + } + + public LoadPlugin(String identifier) { + super("LoadPlugin"); + setField("Identifier", identifier); + } + + public void setPluginUrl(String pluginUrl) { + setField("PluginURL", pluginUrl); + } + + public void setUrlType(UrlType urlType) { + setField("URLType", urlType.toString().toLowerCase()); + } + + public void setStore(boolean store) { + setField("Store", String.valueOf(store)); + } + + public void setOfficialSource(OfficialSource officialSource) { + setField("OfficialSource", officialSource.toString().toLowerCase()); + } + +} diff --git a/src/main/java/net/pterodactylus/fcp/PeerNoteType.java b/src/main/java/net/pterodactylus/fcp/PeerNoteType.java new file mode 100644 index 0000000..7ebede3 --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/PeerNoteType.java @@ -0,0 +1,23 @@ +package net.pterodactylus.fcp; + +/** + * All possible peer note types. + * + * @author David ‘Bombe’ Roden + */ +public enum PeerNoteType { + + PRIVATE_DARKNET_COMMENT(1); + + private int value; + + PeerNoteType(int value) { + this.value = value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + +} diff --git a/src/main/java/net/pterodactylus/fcp/ReloadPlugin.java b/src/main/java/net/pterodactylus/fcp/ReloadPlugin.java new file mode 100644 index 0000000..bcdcde9 --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/ReloadPlugin.java @@ -0,0 +1,31 @@ +package net.pterodactylus.fcp; + +/** + * The “ReloadPlugin” message is used to reload a plugin. + * + * @author David ‘Bombe’ Roden + */ +public class ReloadPlugin extends FcpMessage { + + public ReloadPlugin(String identifier) { + super("ReloadPlugin"); + setField("Identifier", identifier); + } + + public void setPluginName(String pluginName) { + setField("PluginName", pluginName); + } + + public void setMaxWaitTime(int maxWaitTime) { + setField("MaxWaitTime", String.valueOf(maxWaitTime)); + } + + public void setPurge(boolean purge) { + setField("Purge", String.valueOf(purge)); + } + + public void setStore(boolean store) { + setField("Store", String.valueOf(store)); + } + +} diff --git a/src/main/java/net/pterodactylus/fcp/RequestProgress.java b/src/main/java/net/pterodactylus/fcp/RequestProgress.java new file mode 100644 index 0000000..2dcc109 --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/RequestProgress.java @@ -0,0 +1,63 @@ +package net.pterodactylus.fcp; + +/** + * Progress information about a request. + * + * @author David ‘Bombe’ Roden + */ +public class RequestProgress { + + private final int total; + private final int required; + private final int failed; + private final int fatallyFailed; + private final long lastProgress; + private final int succeeded; + private final boolean finalizedTotal; + private final int minSuccessFetchBlocks; + + public RequestProgress(int total, int required, int failed, int fatallyFailed, long lastProgress, int succeeded, + boolean finalizedTotal, int minSuccessFetchBlocks) { + this.total = total; + this.required = required; + this.failed = failed; + this.fatallyFailed = fatallyFailed; + this.lastProgress = lastProgress; + this.succeeded = succeeded; + this.finalizedTotal = finalizedTotal; + this.minSuccessFetchBlocks = minSuccessFetchBlocks; + } + + public int getTotal() { + return total; + } + + public int getRequired() { + return required; + } + + public int getFailed() { + return failed; + } + + public int getFatallyFailed() { + return fatallyFailed; + } + + public long getLastProgress() { + return lastProgress; + } + + public int getSucceeded() { + return succeeded; + } + + public boolean isFinalizedTotal() { + return finalizedTotal; + } + + public int getMinSuccessFetchBlocks() { + return minSuccessFetchBlocks; + } + +} diff --git a/src/main/java/net/pterodactylus/fcp/UnsubscribeUSK.java b/src/main/java/net/pterodactylus/fcp/UnsubscribeUSK.java new file mode 100644 index 0000000..baadefb --- /dev/null +++ b/src/main/java/net/pterodactylus/fcp/UnsubscribeUSK.java @@ -0,0 +1,15 @@ +package net.pterodactylus.fcp; + +/** + * The “UnsubscribeUSK” message is used to cancel a {@link SubscribeUSK USK subscription}. + * + * @author David ‘Bombe’ Roden + */ +public class UnsubscribeUSK extends FcpMessage { + + public UnsubscribeUSK(String identifier) { + super("UnsubscribeUSK"); + setField("Identifier", identifier); + } + +} -- 2.7.4