Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions ffi/TerracottaAndroidAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -234,32 +235,35 @@ public static void setWaiting() {
/**
* <p>Set Terracotta Android into 'host-scanning' state.</p>
*
* @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<String> extraNodes) {
assertStarted();
setScanning0(room, player);
setScanning0(room, player, extraNodes == null ? null : String.join("\0", extraNodes));
}

/**
* <p>Set Terracotta Android into 'guest-connecting' state.</p>
*
* @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<String> extraNodes) {
Objects.requireNonNull(room, "room");

assertStarted();
return setGuesting0(room, player);
return setGuesting0(room, player, extraNodes == null ? null : String.join("\0", extraNodes));
}

/**
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);

Expand Down
16 changes: 10 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down Expand Up @@ -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<String> = 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<String> = 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
Expand Down