diff --git a/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt b/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt index 3e6b6e25472cae2fb3afc6d1e86b61fb35d7b3db..f0e9eb91f5b8b45812decab702738c967fde149d 100644 --- a/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt +++ b/lib/src/main/java/de/kuschku/libquassel/connection/CoreConnection.kt @@ -28,6 +28,7 @@ import de.kuschku.libquassel.protocol.primitive.serializer.ProtocolInfoSerialize import de.kuschku.libquassel.protocol.primitive.serializer.VariantListSerializer import de.kuschku.libquassel.quassel.ProtocolFeature import de.kuschku.libquassel.session.ProtocolHandler +import de.kuschku.libquassel.util.Optional import de.kuschku.libquassel.util.compatibility.CompatibilityUtils import de.kuschku.libquassel.util.compatibility.HandlerService import de.kuschku.libquassel.util.compatibility.LoggingHandler.Companion.log @@ -46,6 +47,7 @@ import java.lang.Thread.UncaughtExceptionHandler import java.net.Socket import java.net.SocketException import java.nio.ByteBuffer +import javax.net.ssl.SSLSession import javax.net.ssl.X509TrustManager class CoreConnection( @@ -74,6 +76,10 @@ class CoreConnection( ) private var channel: WrappedChannel? = null + set(value) { + field = value + sslSession.onNext(Optional.ofNullable(value?.sslSession)) + } private fun connect() { setState(ConnectionState.CONNECTING) @@ -281,6 +287,6 @@ class CoreConnection( ) } - val sslSession - get() = channel?.sslSession + + val sslSession: BehaviorSubject<Optional<SSLSession>> = BehaviorSubject.createDefault(Optional.empty()) } diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/CoreInfo.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/CoreInfo.kt index 6584aded232e7635df317fc4d6e22f474c5c1f6e..ec971f43f1bf1f5f5d103c408f206e4cd7e6f731 100644 --- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/CoreInfo.kt +++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/CoreInfo.kt @@ -19,12 +19,12 @@ package de.kuschku.libquassel.quassel.syncables -import de.kuschku.libquassel.protocol.QVariant -import de.kuschku.libquassel.protocol.QVariantMap -import de.kuschku.libquassel.protocol.Type -import de.kuschku.libquassel.protocol.value +import de.kuschku.libquassel.protocol.* +import de.kuschku.libquassel.quassel.QuasselFeatures import de.kuschku.libquassel.quassel.syncables.interfaces.ICoreInfo import de.kuschku.libquassel.session.SignalProxy +import io.reactivex.subjects.BehaviorSubject +import org.threeten.bp.Instant class CoreInfo constructor( proxy: SignalProxy @@ -49,6 +49,56 @@ class CoreInfo constructor( } fun coreData() = _coreData + fun info() = _coreData.let { + CoreData( + quasselVersion = it["quasselVersion"]?.value("") ?: "", + quasselBuildDate = it["quasselBuildDate"]?.value("") ?: "", + startTime = it["startTime"]?.value(Instant.EPOCH) ?: Instant.EPOCH, + sessionConnectedClients = it["sessionConnectedClients"]?.value(0) ?: 0, + sessionConnectedClientData = it["sessionConnectedClientData"]?.value(emptyList<QVariant_>())?.map { + it.value(emptyMap<String, QVariant_>()).let { + ConnectedClientData( + id = it["id"]?.value(0) ?: 0, + remoteAddress = it["remoteAddress"]?.value("") ?: "", + location = it["location"]?.value("") ?: "", + clientVersion = it["clientVersion"]?.value("") ?: "", + clientVersionDate = it["clientVersionDate"]?.value("") ?: "", + connectedSince = it["connectedSince"]?.value(Instant.EPOCH) ?: Instant.EPOCH, + secure = it["secure"]?.value(false) ?: false, + features = QuasselFeatures( + Legacy_Feature.of(it["features"]?.value(0) ?: 0), + it["featureList"]?.valueOr(::emptyList) ?: emptyList() + ) + ) + } + } ?: emptyList() + ) + } + fun liveInfo() = live_coreData.map { info() } + private val live_coreData = BehaviorSubject.createDefault(Unit) private var _coreData: QVariantMap = emptyMap() + set(value) { + field = value + live_coreData.onNext(Unit) + } + + data class CoreData( + val quasselVersion: String, + val quasselBuildDate: String, + val startTime: Instant, + val sessionConnectedClients: Int, + val sessionConnectedClientData: List<ConnectedClientData> + ) + + data class ConnectedClientData( + val id: Int, + val remoteAddress: String, + val location: String, + val clientVersion: String, + val clientVersionDate: String, + val connectedSince: Instant, + val secure: Boolean, + val features: QuasselFeatures + ) } diff --git a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt index 328acf312c0aa788980c2269189df9878aa06de1..a3ab7adc7384247fa1da112c609a3b42c4a8a00c 100644 --- a/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt +++ b/lib/src/main/java/de/kuschku/libquassel/quassel/syncables/RpcHandler.kt @@ -100,7 +100,7 @@ class RpcHandler( override fun requestKickClient(id: Int) = RPC( - "2kickClient(Int)", + "2kickClient(int)", ARG(id, Type.Int) ) diff --git a/lib/src/main/java/de/kuschku/libquassel/session/ISession.kt b/lib/src/main/java/de/kuschku/libquassel/session/ISession.kt index 86bf0f762bec4661585912386c2d7c930f506fe2..7bacb7c22a3e69c54a15230fa3c4493539aec4f0 100644 --- a/lib/src/main/java/de/kuschku/libquassel/session/ISession.kt +++ b/lib/src/main/java/de/kuschku/libquassel/session/ISession.kt @@ -25,6 +25,7 @@ import de.kuschku.libquassel.protocol.IdentityId import de.kuschku.libquassel.protocol.NetworkId import de.kuschku.libquassel.quassel.QuasselFeatures import de.kuschku.libquassel.quassel.syncables.* +import de.kuschku.libquassel.util.Optional import io.reactivex.BackpressureStrategy import io.reactivex.Flowable import io.reactivex.Observable @@ -35,7 +36,7 @@ import javax.net.ssl.SSLSession interface ISession : Closeable { val state: Observable<ConnectionState> val features: Features - val sslSession: SSLSession? + val sslSession: Observable<Optional<SSLSession>> val aliasManager: AliasManager? val backlogManager: BacklogManager? @@ -71,7 +72,7 @@ interface ISession : Closeable { override val features: Features = Features( QuasselFeatures.empty(), QuasselFeatures.empty()) - override val sslSession: SSLSession? = null + override val sslSession: Observable<Optional<SSLSession>> = Observable.empty() override val rpcHandler: RpcHandler? = null override val aliasManager: AliasManager? = null diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt index 884213f0c0eb78064e06290db3ed98932507d2e0..19e4d54226004279a6dbbabe3058dfd00c7dbc06 100644 --- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/QuasselViewModel.kt @@ -23,10 +23,7 @@ import android.arch.lifecycle.ViewModel import de.kuschku.libquassel.connection.ConnectionState import de.kuschku.libquassel.protocol.* import de.kuschku.libquassel.quassel.BufferInfo -import de.kuschku.libquassel.quassel.syncables.BufferViewConfig -import de.kuschku.libquassel.quassel.syncables.IrcChannel -import de.kuschku.libquassel.quassel.syncables.IrcUser -import de.kuschku.libquassel.quassel.syncables.Network +import de.kuschku.libquassel.quassel.syncables.* import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork import de.kuschku.libquassel.session.Backend import de.kuschku.libquassel.session.ISession @@ -47,15 +44,15 @@ import java.util.concurrent.TimeUnit class QuasselViewModel : ViewModel() { fun resetAccount() { - stateReset.onNext(Unit) buffer.onNext(Int.MAX_VALUE) bufferViewConfigId.onNext(-1) selectedMessages.onNext(emptyMap()) expandedMessages.onNext(emptySet()) recentlySentMessages.onNext(emptyList()) + stateReset.onNext(Unit) } - val stateReset = PublishSubject.create<Unit>() + val stateReset = BehaviorSubject.create<Unit>() val backendWrapper = BehaviorSubject.createDefault(Observable.empty<Optional<Backend>>()) @@ -104,6 +101,12 @@ class QuasselViewModel : ViewModel() { it.orNull()?.error ?: Flowable.empty() } + val sslSession = session.flatMapSwitchMap(ISession::sslSession) + + val coreInfo = session.mapMapNullable(ISession::coreInfo).mapSwitchMap(CoreInfo::liveInfo) + val coreInfoClients = coreInfo.mapMap(CoreInfo.CoreData::sessionConnectedClientData) + .mapOrElse(emptyList()) + val networkConfig = session.mapMapNullable(ISession::networkConfig) val ignoreListManager = session.mapMapNullable(ISession::ignoreListManager)