diff --git a/ffi/TerracottaAndroidAPI.java b/ffi/TerracottaAndroidAPI.java
index dbaff0e..a307e63 100644
--- a/ffi/TerracottaAndroidAPI.java
+++ b/ffi/TerracottaAndroidAPI.java
@@ -18,6 +18,7 @@
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
+import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
@@ -234,32 +235,35 @@ public static void setWaiting() {
/**
*
Set Terracotta Android into 'host-scanning' state.
*
- * @param player the player's name. A default value will be taken if it's null.
+ * @param room the room code, which may be used if it's valid.
+ * @param player the player's name. A default value will be taken if it's null.
+ * @param extraNodes extra public server nodes for EasyTier.
* @throws IllegalStateException if Terracotta Android hasn't been initialized.
* @implNote Usually, this method doesn't take a long time to fetch states.
* However, when initializing the EasyTier, state fetching may block for ~1 seconds.
*/
- public static void setScanning(@Nullable String room, @Nullable String player) {
+ public static void setScanning(@Nullable String room, @Nullable String player, @Nullable List extraNodes) {
assertStarted();
- setScanning0(room, player);
+ setScanning0(room, player, extraNodes == null ? null : String.join("\0", extraNodes));
}
/**
* Set Terracotta Android into 'guest-connecting' state.
*
- * @param room the room code. False will be returned if it's invalid.
- * @param player the player's name. A default value will be taken if it's null.
+ * @param room the room code. False will be returned if it's invalid.
+ * @param player the player's name. A default value will be taken if it's null.
+ * @param extraNodes extra public server nodes for EasyTier.
* @return True if room code is valid, false otherwise.
* @throws IllegalStateException if Terracotta Android hasn't been initialized.
* @throws NullPointerException if room is null.
* @implNote Usually, this method doesn't take a long time to fetch states.
* However, when initializing the EasyTier, state fetching may block for ~1 seconds.
*/
- public static boolean setGuesting(String room, @Nullable String player) {
+ public static boolean setGuesting(String room, @Nullable String player, @Nullable List extraNodes) {
Objects.requireNonNull(room, "room");
assertStarted();
- return setGuesting0(room, player);
+ return setGuesting0(room, player, extraNodes == null ? null : String.join("\0", extraNodes));
}
/**
@@ -381,7 +385,7 @@ public static void panic() {
private static final long FD_PENDING = ((long) Integer.MAX_VALUE) + 1;
private static final long FD_REJECT = FD_PENDING + 1;
-;
+
@SuppressWarnings("unused") // Native callback
private static int onVpnServiceStateChanged(byte ip1, byte ip2, byte ip3, byte ip4, short network_length, String cidr) throws UnknownHostException {
if (pendingRequest != null) {
@@ -460,9 +464,9 @@ private static void assertStarted() {
private static native void setWaiting0();
- private static native void setScanning0(String room, String player);
+ private static native void setScanning0(String room, String player, String extraNodes);
- private static native boolean setGuesting0(String room, String player);
+ private static native boolean setGuesting0(String room, String player, String extraNodes);
private static native int verifyRoomCode0(String room);
diff --git a/src/lib.rs b/src/lib.rs
index c05a357..ba2efdb 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -138,8 +138,8 @@ extern "system" fn JNI_OnLoad(vm: JavaVM, _: *mut c_void) -> jint {
of!["start0", "(Ljava/lang/String;I)I", jni_start],
of!["getState0", "()Ljava/lang/String;", jni_get_state],
of!["setWaiting0", "()V", jni_set_waiting],
- of!["setScanning0", "(Ljava/lang/String;Ljava/lang/String;)V", jni_set_scanning],
- of!["setGuesting0", "(Ljava/lang/String;Ljava/lang/String;)Z", jni_set_guesting],
+ of!["setScanning0", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", jni_set_scanning],
+ of!["setGuesting0", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z", jni_set_guesting],
of!["verifyRoomCode0", "(Ljava/lang/String;)I", jni_verify_room_code],
of!["getMetadata0", "()Ljava/lang/String;", jni_get_metadata],
of!["prepareExportLogs0", "()J", jni_prepare_export_logs],
@@ -276,20 +276,24 @@ extern "system" fn jni_set_waiting<'l>(jenv: JNIEnv<'l>, _: JClass<'l>) {
}
}
-extern "system" fn jni_set_scanning<'l>(jenv: JNIEnv<'l>, _: JClass<'l>, room: JString<'l>, player: JString<'l>) {
+extern "system" fn jni_set_scanning<'l>(jenv: JNIEnv<'l>, _: JClass<'l>, room: JString<'l>, player: JString<'l>, extra_nodes: JString<'l>) {
try_jvm! { |jenv|
let room = parse_jstring(&jenv, &room);
let player = parse_jstring(&jenv, &player);
- controller::set_scanning(room, player, vec![]);
+ let extra_nodes = parse_jstring(&jenv, &extra_nodes);
+ let extra_nodes: Vec = extra_nodes.map(|s| s.split("\0").map(|s| s.into()).collect()).unwrap_or(vec![]);
+ controller::set_scanning(room, player, extra_nodes);
}
}
-extern "system" fn jni_set_guesting<'l>(jenv: JNIEnv<'l>, _: JClass<'l>, room: JString<'l>, player: JString<'l>) -> jboolean {
+extern "system" fn jni_set_guesting<'l>(jenv: JNIEnv<'l>, _: JClass<'l>, room: JString<'l>, player: JString<'l>, extra_nodes: JString<'l>) -> jboolean {
try_jvm! { |jenv|
let room = parse_jstring(&jenv, &room).expect("'room' must not be NULL.");
let player = parse_jstring(&jenv, &player);
+ let extra_nodes = parse_jstring(&jenv, &extra_nodes);
+ let extra_nodes: Vec = extra_nodes.map(|s| s.split("\0").map(|s| s.into()).collect()).unwrap_or(vec![]);
- if let Some(room) = Room::from(&room) && controller::set_guesting(room, player, vec![]) {
+ if let Some(room) = Room::from(&room) && controller::set_guesting(room, player, extra_nodes) {
JNI_TRUE
} else {
JNI_FALSE