Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • api-redesign
  • main
  • 0.10.0
  • 0.10.1
  • 0.10.2
  • 0.7.0
  • 0.8.0
  • 0.8.1
  • 0.9.0
  • 0.9.1
  • 0.9.2
11 results

Target

Select target project
  • justJanne/libquassel
1 result
Select Git revision
  • api-redesign
  • main
  • 0.10.0
  • 0.10.1
  • 0.10.2
  • 0.7.0
  • 0.8.0
  • 0.8.1
  • 0.9.0
  • 0.9.1
  • 0.9.2
11 results
Show changes
Showing
with 0 additions and 2569 deletions
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.common
import de.justjanne.libquassel.irc.HostmaskHelper
import de.justjanne.libquassel.protocol.models.types.QtType
import de.justjanne.libquassel.protocol.session.Session
import de.justjanne.libquassel.protocol.syncables.StatefulSyncableObject
import de.justjanne.libquassel.protocol.syncables.state.IrcUserState
import de.justjanne.libquassel.protocol.syncables.stubs.IrcUserStub
import de.justjanne.libquassel.protocol.util.update
import de.justjanne.libquassel.protocol.variant.QVariantMap
import de.justjanne.libquassel.protocol.variant.indexed
import de.justjanne.libquassel.protocol.variant.into
import de.justjanne.libquassel.protocol.variant.qVariant
import org.threeten.bp.Instant
import org.threeten.bp.OffsetDateTime
import org.threeten.bp.ZoneOffset
import org.threeten.bp.temporal.Temporal
open class IrcUser(
session: Session? = null,
state: IrcUserState
) : StatefulSyncableObject<IrcUserState>(session, "IrcUser", state),
IrcUserStub {
init {
renameObject(state().identifier())
}
override fun fromVariantMap(properties: QVariantMap) =
fromVariantMap(properties, null)
fun fromVariantMap(properties: QVariantMap, index: Int?) {
state.update {
copy(
nick = properties["nick"].indexed(index).into(nick),
user = properties["user"].indexed(index).into(user),
host = properties["host"].indexed(index).into(host),
realName = properties["realName"].indexed(index).into(realName),
account = properties["account"].indexed(index).into(account),
away = properties["away"].indexed(index).into(away),
awayMessage = properties["awayMessage"].indexed(index).into(awayMessage),
idleTime = properties["idleTime"].indexed(index).into(idleTime.atOffset(ZoneOffset.UTC)).toInstant(),
loginTime = properties["loginTime"].indexed(index).into(loginTime.atOffset(ZoneOffset.UTC)).toInstant(),
server = properties["server"].indexed(index).into(server),
ircOperator = properties["ircOperator"].indexed(index).into(ircOperator),
lastAwayMessageTime = properties["lastAwayMessageTime"].indexed(index).into<OffsetDateTime>()?.toInstant()
?: properties["lastAwayMessage"].indexed(index).into<Int>()?.toLong()
?.let(Instant::ofEpochSecond)
?: lastAwayMessageTime,
whoisServiceReply = properties["whoisServiceReply"].indexed(index).into(whoisServiceReply),
suserHost = properties["suserHost"].indexed(index).into(suserHost),
encrypted = properties["encrypted"].indexed(index).into(encrypted),
channels = properties["channels"].indexed(index).into(channels),
userModes = properties["userModes"].indexed(index).into(userModes),
)
}
renameObject(state().identifier())
initialized = true
}
override fun toVariantMap() = mapOf(
"nick" to qVariant(nick(), QtType.QString),
"user" to qVariant(user(), QtType.QString),
"host" to qVariant(host(), QtType.QString),
"realName" to qVariant(realName(), QtType.QString),
"account" to qVariant(account(), QtType.QString),
"away" to qVariant(isAway(), QtType.Bool),
"awayMessage" to qVariant(awayMessage(), QtType.QString),
"idleTime" to qVariant(idleTime().atOffset(ZoneOffset.UTC), QtType.QDateTime),
"loginTime" to qVariant(loginTime().atOffset(ZoneOffset.UTC), QtType.QDateTime),
"server" to qVariant(server(), QtType.QString),
"ircOperator" to qVariant(ircOperator(), QtType.QString),
"lastAwayMessage" to qVariant(lastAwayMessageTime().epochSecond.toInt(), QtType.Int),
"lastAwayMessageTime" to qVariant(lastAwayMessageTime().atOffset(ZoneOffset.UTC), QtType.QDateTime),
"whoisServiceReply" to qVariant(whoisServiceReply(), QtType.QString),
"suserHost" to qVariant(suserHost(), QtType.QString),
"encrypted" to qVariant(isEncrypted(), QtType.Bool),
"channels" to qVariant(channels().toList(), QtType.QStringList),
"userModes" to qVariant(userModes().joinToString(), QtType.QString)
)
override fun updateHostmask(mask: String) {
state.update {
val (_, user, host) = HostmaskHelper.split(mask)
copy(user = user, host = host)
}
super.updateHostmask(mask)
}
override fun addUserModes(modes: String) {
state.update {
copy(userModes = userModes + modes.toSet())
}
super.addUserModes(modes)
}
override fun removeUserModes(modes: String) {
state.update {
copy(userModes = userModes - modes.toSet())
}
super.removeUserModes(modes)
}
override fun setUser(user: String) {
state.update {
copy(user = user)
}
super.setUser(user)
}
override fun setHost(host: String) {
state.update {
copy(host = host)
}
super.setHost(host)
}
override fun setNick(nick: String) {
val network = session?.network(network())
network?.ircUserNickChanged(nick(), nick)
state.update {
copy(nick = nick)
}
renameObject(state().identifier())
super.setNick(nick)
}
override fun setRealName(realName: String) {
state.update {
copy(realName = realName)
}
super.setRealName(realName)
}
override fun setAccount(account: String) {
state.update {
copy(account = account)
}
super.setAccount(account)
}
override fun setAway(away: Boolean) {
state.update {
copy(away = away)
}
super.setAway(away)
}
override fun setAwayMessage(awayMessage: String) {
state.update {
copy(awayMessage = awayMessage)
}
super.setAwayMessage(awayMessage)
}
override fun setIdleTime(idleTime: Temporal) {
state.update {
copy(idleTime = Instant.from(idleTime))
}
super.setIdleTime(idleTime)
}
override fun setLoginTime(loginTime: Temporal) {
state.update {
copy(loginTime = Instant.from(loginTime))
}
super.setLoginTime(loginTime)
}
override fun setIrcOperator(ircOperator: String) {
state.update {
copy(ircOperator = ircOperator)
}
super.setIrcOperator(ircOperator)
}
override fun setLastAwayMessage(lastAwayMessage: Int) {
state.update {
copy(lastAwayMessageTime = Instant.ofEpochSecond(lastAwayMessage.toLong()))
}
super.setLastAwayMessage(lastAwayMessage)
}
override fun setLastAwayMessageTime(lastAwayMessageTime: Temporal) {
state.update {
copy(lastAwayMessageTime = Instant.from(lastAwayMessageTime))
}
super.setLastAwayMessageTime(lastAwayMessageTime)
}
override fun setWhoisServiceReply(whoisServiceReply: String) {
state.update {
copy(whoisServiceReply = whoisServiceReply)
}
super.setWhoisServiceReply(whoisServiceReply)
}
override fun setSuserHost(suserHost: String) {
state.update {
copy(suserHost = suserHost)
}
super.setSuserHost(suserHost)
}
override fun setEncrypted(encrypted: Boolean) {
state.update {
copy(encrypted = encrypted)
}
super.setEncrypted(encrypted)
}
override fun setServer(server: String) {
state.update {
copy(server = server)
}
super.setServer(server)
}
override fun setUserModes(modes: String) {
state.update {
copy(userModes = modes.toSet())
}
super.setUserModes(modes)
}
fun joinChannel(channel: IrcChannel, skipChannelJoin: Boolean = false) {
if (state().channels.contains(channel.name())) {
return
}
state.update {
copy(channels = channels + channel.name())
}
if (!skipChannelJoin) {
channel.joinIrcUser(this)
}
super.joinChannel(channel.name())
}
override fun joinChannel(channelname: String) {
val network = session?.network(network()) ?: return
val channel = network.newIrcChannel(channelname)
joinChannel(channel)
}
fun partChannel(channel: IrcChannel) {
val network = session?.network(network())
state.update {
copy(channels = channels - channel.name())
}
channel.part(nick())
super.partChannel(channel.name())
if (channels().isEmpty() && network?.isMe(this) != true) {
quit()
}
}
override fun quit() {
val network = session?.network(network())
for (channel in channels()) {
network?.ircChannel(channel)
?.part(nick())
}
state.update {
copy(channels = emptySet())
}
network?.removeIrcUser(this)
session?.proxy?.stopSynchronize(this)
super.quit()
}
fun network() = state().network
fun nick() = state().nick
fun user() = state().user
fun verifiedUser() = state().verifiedUser()
fun host() = state().host
fun realName() = state().realName
fun account() = state().account
fun hostMask() = state().hostMask()
fun isAway() = state().away
fun awayMessage() = state().awayMessage
fun server() = state().server
fun idleTime() = state().idleTime
fun loginTime() = state().loginTime
fun ircOperator() = state().ircOperator
fun lastAwayMessageTime() = state().lastAwayMessageTime
fun whoisServiceReply() = state().whoisServiceReply
fun suserHost() = state().suserHost
fun isEncrypted() = state().encrypted
fun userModes() = state().userModes
fun channels() = state().channels
}
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.common
import de.justjanne.libquassel.irc.HostmaskHelper
import de.justjanne.libquassel.protocol.models.QStringList
import de.justjanne.libquassel.protocol.models.ids.IdentityId
import de.justjanne.libquassel.protocol.models.network.ConnectionState
import de.justjanne.libquassel.protocol.models.network.NetworkInfo
import de.justjanne.libquassel.protocol.models.network.NetworkServer
import de.justjanne.libquassel.protocol.models.types.QtType
import de.justjanne.libquassel.protocol.models.types.QuasselType
import de.justjanne.libquassel.protocol.serializers.qt.StringSerializerUtf8
import de.justjanne.libquassel.protocol.session.Session
import de.justjanne.libquassel.protocol.syncables.StatefulSyncableObject
import de.justjanne.libquassel.protocol.syncables.state.IrcChannelState
import de.justjanne.libquassel.protocol.syncables.state.IrcUserState
import de.justjanne.libquassel.protocol.syncables.state.NetworkState
import de.justjanne.libquassel.protocol.syncables.stubs.NetworkStub
import de.justjanne.libquassel.protocol.util.collections.transpose
import de.justjanne.libquassel.protocol.util.update
import de.justjanne.libquassel.protocol.variant.QVariantList
import de.justjanne.libquassel.protocol.variant.QVariantMap
import de.justjanne.libquassel.protocol.variant.into
import de.justjanne.libquassel.protocol.variant.qVariant
import java.nio.ByteBuffer
open class Network(
session: Session? = null,
state: NetworkState
) : StatefulSyncableObject<NetworkState>(session, "Network", state),
NetworkStub {
init {
renameObject(state().identifier())
}
override fun fromVariantMap(properties: QVariantMap) {
state.update {
copy(
networkName = properties["networkName"].into(networkName),
currentServer = properties["currentServer"].into(currentServer),
myNick = properties["myNick"].into(myNick),
latency = properties["latency"].into(latency),
codecForServer = properties["codecForServer"].into<ByteBuffer>()
?.let(StringSerializerUtf8::deserializeRaw)
?: codecForServer,
codecForEncoding = properties["codecForEncoding"].into<ByteBuffer>()
?.let(StringSerializerUtf8::deserializeRaw)
?: codecForEncoding,
codecForDecoding = properties["codecForDecoding"].into<ByteBuffer>()
?.let(StringSerializerUtf8::deserializeRaw)
?: codecForDecoding,
identity = properties["identityId"]
.into(identity),
connected = properties["isConnected"]
.into(connected),
connectionState = ConnectionState.of(
properties["connectionState"].into(connectionState.value)
) ?: ConnectionState.Disconnected,
useRandomServer = properties["useRandomServer"]
.into(useRandomServer),
perform = properties["perform"]
.into(perform),
useAutoIdentify = properties["useAutoIdentify"]
.into(useAutoIdentify),
autoIdentifyService = properties["autoIdentifyService"]
.into(autoIdentifyService),
autoIdentifyPassword = properties["autoIdentifyPassword"]
.into(autoIdentifyPassword),
useSasl = properties["useSasl"]
.into(useSasl),
saslAccount = properties["saslAccount"]
.into(saslAccount),
saslPassword = properties["saslPassword"]
.into(saslPassword),
useAutoReconnect = properties["useAutoReconnect"]
.into(useAutoReconnect),
autoReconnectInterval = properties["autoReconnectInterval"]
.into(autoReconnectInterval),
autoReconnectRetries = properties["autoReconnectRetries"]
.into(autoReconnectRetries),
unlimitedReconnectRetries = properties["unlimitedReconnectRetries"]
.into(unlimitedReconnectRetries),
rejoinChannels = properties["rejoinChannels"]
.into(rejoinChannels),
useCustomMessageRate = properties["useCustomMessageRate"]
.into(useCustomMessageRate),
messageRateBurstSize = properties["msgRateBurstSize"]
.into(messageRateBurstSize),
messageRateDelay = properties["msgRateMessageDelay"]
.into(messageRateDelay),
unlimitedMessageRate = properties["unlimitedMessageRate"]
.into(unlimitedMessageRate),
skipCaps = properties["skipCaps"]
.into<QStringList>()
?.filterNotNull()
?.toSet()
.orEmpty(),
serverList = properties["ServerList"].into<QVariantList>()
?.mapNotNull { it.into<NetworkServer>() }
.orEmpty(),
supports = properties["Supports"].into<QVariantMap>()
?.mapValues { (_, value) -> value.into<String>() }
.orEmpty(),
caps = properties["Caps"].into<QVariantMap>()?.mapValues { (_, value) ->
value.into<String>()
}.orEmpty(),
capsEnabled = properties["CapsEnabled"].into<QVariantList>()
?.mapNotNull { it.into<String>() }
?.toSet()
.orEmpty(),
ircUsers = properties["IrcUsersAndChannels"].into<QVariantMap>()
?.get("Users")?.into<QVariantMap>()
?.let { user ->
user["nick"].into<QVariantList>()?.withIndex()?.map { (index, value) ->
newIrcUser(value.into(""), user, index)
}
}
?.associateBy { caseMapper().toLowerCase(it.nick()) }
.orEmpty(),
ircChannels = properties["IrcUsersAndChannels"].into<QVariantMap>()
?.get("Channels")?.into<QVariantMap>()
?.let { channel ->
channel["name"].into<QVariantList>()?.withIndex()?.map { (index, value) ->
newIrcChannel(value.into(""), channel, index)
}
}
?.associateBy { caseMapper().toLowerCase(it.name()) }
.orEmpty()
)
}
initialized = true
}
override fun toVariantMap() = mapOf(
"networkName" to qVariant(networkName(), QtType.QString),
"currentServer" to qVariant(currentServer(), QtType.QString),
"myNick" to qVariant(myNick(), QtType.QString),
"latency" to qVariant(latency(), QtType.Int),
"codecForServer" to qVariant(
StringSerializerUtf8.serializeRaw(codecForServer()),
QtType.QByteArray
),
"codecForEncoding" to qVariant(
StringSerializerUtf8.serializeRaw(codecForEncoding()),
QtType.QByteArray
),
"codecForDecoding" to qVariant(
StringSerializerUtf8.serializeRaw(codecForDecoding()),
QtType.QByteArray
),
"identityId" to qVariant(identity(), QuasselType.IdentityId),
"isConnected" to qVariant(isConnected(), QtType.Bool),
"connectionState" to qVariant(connectionState().value, QtType.Int),
"useRandomServer" to qVariant(useRandomServer(), QtType.Bool),
"perform" to qVariant(perform(), QtType.QStringList),
"useAutoIdentify" to qVariant(useAutoIdentify(), QtType.Bool),
"autoIdentifyService" to qVariant(autoIdentifyService(), QtType.QString),
"autoIdentifyPassword" to qVariant(autoIdentifyPassword(), QtType.QString),
"useSasl" to qVariant(useSasl(), QtType.Bool),
"saslAccount" to qVariant(saslAccount(), QtType.QString),
"saslPassword" to qVariant(saslPassword(), QtType.QString),
"useAutoReconnect" to qVariant(useAutoReconnect(), QtType.Bool),
"autoReconnectInterval" to qVariant(autoReconnectInterval(), QtType.UInt),
"autoReconnectRetries" to qVariant(autoReconnectRetries(), QtType.UShort),
"unlimitedReconnectRetries" to qVariant(unlimitedReconnectRetries(), QtType.Bool),
"rejoinChannels" to qVariant(rejoinChannels(), QtType.Bool),
"useCustomMessageRate" to qVariant(useCustomMessageRate(), QtType.Bool),
"msgRateBurstSize" to qVariant(messageRateBurstSize(), QtType.UInt),
"msgRateMessageDelay" to qVariant(messageRateDelay(), QtType.UInt),
"unlimitedMessageRate" to qVariant(unlimitedMessageRate(), QtType.Bool),
"skipCaps" to qVariant(skipCaps().toList(), QtType.QStringList),
"Supports" to qVariant(
supports().mapValues { (_, value) -> qVariant(value, QtType.QString) },
QtType.QVariantMap
),
"ServerList" to qVariant(
serverList().map { qVariant(it, QuasselType.NetworkServer) },
QtType.QVariantList
),
"Caps" to qVariant(
caps().mapValues { (_, value) -> qVariant(value, QtType.QString) },
QtType.QVariantMap
),
"CapsEnabled" to qVariant(
capsEnabled().map { qVariant(it, QtType.QString) },
QtType.QVariantList
),
"IrcUsersAndChannels" to qVariant(
mapOf(
"Users" to qVariant(
ircUsers().map { it.toVariantMap() }.transpose(),
QtType.QVariantMap
),
"Channels" to qVariant(
ircChannels().map { it.toVariantMap() }.transpose(),
QtType.QVariantMap
),
),
QtType.QVariantMap
)
)
fun networkId() = state().networkId
fun networkName() = state().networkName
fun isConnected() = state().connected
fun connectionState() = state().connectionState
fun currentServer() = state().currentServer
fun myNick() = state().myNick
fun latency() = state().latency
fun identity() = state().identity
fun nicks() = state().ircUsers.keys
fun channels() = state().ircChannels.keys
fun caps() = state().caps
fun capsEnabled() = state().capsEnabled
fun serverList() = state().serverList
fun useRandomServer() = state().useRandomServer
fun perform() = state().perform
fun useAutoIdentify() = state().useAutoIdentify
fun autoIdentifyService() = state().autoIdentifyService
fun autoIdentifyPassword() = state().autoIdentifyPassword
fun useSasl() = state().useSasl
fun saslAccount() = state().saslAccount
fun saslPassword() = state().saslPassword
fun useAutoReconnect() = state().useAutoReconnect
fun autoReconnectInterval() = state().autoReconnectInterval
fun autoReconnectRetries() = state().autoReconnectRetries
fun unlimitedReconnectRetries() = state().unlimitedReconnectRetries
fun rejoinChannels() = state().rejoinChannels
fun useCustomMessageRate() = state().useCustomMessageRate
fun messageRateBurstSize() = state().messageRateBurstSize
fun messageRateDelay() = state().messageRateDelay
fun unlimitedMessageRate() = state().unlimitedMessageRate
fun prefixes() = state().prefixes
fun prefixModes() = state().prefixModes
fun channelModes() = state().channelModes
fun supports() = state().supports
fun supports(key: String) = state().supports(key)
fun supportValue(key: String) = state().supportValue(key)
fun capAvailable(capability: String) = state().capAvailable(capability)
fun capEnabled(capability: String) = state().capEnabled(capability)
fun capValue(capability: String) = state().capValue(capability)
fun skipCaps() = state().skipCaps
fun isSaslSupportLikely(mechanism: String) = state().isSaslSupportLikely(mechanism)
fun ircUser(nickName: String) = state().ircUser(nickName)
fun ircUsers() = state().ircUsers.values
fun ircUserCount() = state().ircUsers.size
fun ircChannel(name: String) = state().ircChannel(name)
fun ircChannels() = state().ircChannels.values
fun ircChannelCount() = state().ircChannels.size
fun codecForServer() = state().codecForServer
fun codecForEncoding() = state().codecForEncoding
fun codecForDecoding() = state().codecForDecoding
fun caseMapper() = state().caseMapper()
fun networkInfo() = NetworkInfo(
networkName = networkName(),
networkId = networkId(),
identity = identity(),
codecForServer = codecForServer(),
codecForEncoding = codecForEncoding(),
codecForDecoding = codecForDecoding(),
serverList = serverList(),
useRandomServer = useRandomServer(),
perform = perform(),
useAutoIdentify = useAutoIdentify(),
autoIdentifyService = autoIdentifyService(),
autoIdentifyPassword = autoIdentifyPassword(),
useSasl = useSasl(),
saslAccount = saslAccount(),
saslPassword = saslPassword(),
useAutoReconnect = useAutoReconnect(),
autoReconnectInterval = autoReconnectInterval(),
autoReconnectRetries = autoReconnectRetries(),
unlimitedReconnectRetries = unlimitedReconnectRetries(),
rejoinChannels = rejoinChannels(),
useCustomMessageRate = useCustomMessageRate(),
messageRateBurstSize = messageRateBurstSize(),
messageRateDelay = messageRateDelay(),
unlimitedMessageRate = unlimitedMessageRate()
)
override fun addIrcUser(hostmask: String) {
newIrcUser(hostmask)
}
override fun addIrcChannel(channel: String) {
newIrcChannel(channel)
}
fun newIrcUser(
hostMask: String,
properties: QVariantMap = emptyMap(),
index: Int? = null
): IrcUser {
val (nick, ident, host) = HostmaskHelper.split(hostMask)
val ircUser = ircUser(nick)
if (ircUser != null) {
return ircUser
}
val user = IrcUser(
session,
IrcUserState(
network = networkId(),
nick = nick,
user = ident,
host = host
)
)
if (properties.isNotEmpty()) {
user.fromVariantMap(properties, index)
user.initialized = true
}
session?.proxy?.synchronize(user)
state.update {
copy(ircUsers = ircUsers + Pair(caseMapper().toLowerCase(nick), user))
}
return user
}
fun newIrcChannel(
name: String,
properties: QVariantMap = emptyMap(),
index: Int? = null
): IrcChannel {
val ircChannel = ircChannel(name)
if (ircChannel != null) {
return ircChannel
}
val channel = IrcChannel(
session,
IrcChannelState(
network = networkId(),
name = name
)
)
if (properties.isNotEmpty()) {
channel.fromVariantMap(properties, index)
channel.initialized = true
}
session?.proxy?.synchronize(channel)
state.update {
copy(ircChannels = ircChannels + Pair(caseMapper().toLowerCase(name), channel))
}
return channel
}
fun removeIrcUser(user: IrcUser) {
state.update {
copy(ircUsers = ircUsers - caseMapper().toLowerCase(user.nick()))
}
}
fun removeIrcChannel(channel: IrcChannel) {
state.update {
copy(ircChannels = ircChannels - caseMapper().toLowerCase(channel.name()))
}
}
fun me() = state().me()
fun isMe(user: IrcUser) = state().isMe(user)
fun channelModeType(mode: Char) = state().channelModeType(mode)
override fun addSupport(param: String, value: String) {
state.update {
copy(
supports = supports + Pair(
caseMapper().toUpperCase(param),
value
)
)
}
super.addSupport(param, value)
}
override fun removeSupport(param: String) {
state.update {
copy(supports = supports - caseMapper().toUpperCase(param))
}
super.removeSupport(param)
}
override fun addCap(capability: String, value: String) {
state.update {
copy(
caps = caps + Pair(
caseMapper().toLowerCase(capability),
value
)
)
}
super.addCap(capability, value)
}
override fun acknowledgeCap(capability: String) {
state.update {
copy(capsEnabled = capsEnabled + caseMapper().toLowerCase(capability))
}
super.acknowledgeCap(capability)
}
override fun removeCap(capability: String) {
state.update {
copy(
caps = caps - caseMapper().toLowerCase(capability),
capsEnabled = capsEnabled - caseMapper().toLowerCase(capability),
)
}
super.removeCap(capability)
}
override fun clearCaps() {
state.update {
copy(caps = emptyMap(), capsEnabled = emptySet())
}
super.clearCaps()
}
override fun setSkipCaps(skipCaps: QStringList) {
state.update {
copy(skipCaps = skipCaps.filterNotNull().toSet())
}
super.setSkipCaps(skipCaps)
}
fun ircUserNickChanged(old: String, new: String) {
val oldNick = caseMapper().toLowerCase(old)
val newNick = caseMapper().toLowerCase(new)
val user = state().ircUsers[oldNick]
if (user != null) {
state.update {
copy(ircUsers = ircUsers - oldNick + Pair(newNick, user))
}
}
}
override fun setIdentity(identityId: IdentityId) {
state.update {
copy(identity = identityId)
}
super.setIdentity(identityId)
}
override fun setMyNick(myNick: String?) {
state.update {
copy(myNick = myNick)
}
super.setMyNick(myNick)
}
override fun setLatency(latency: Int) {
state.update {
copy(latency = latency)
}
super.setLatency(latency)
}
override fun setNetworkName(networkName: String) {
state.update {
copy(networkName = networkName)
}
super.setNetworkName(networkName)
}
override fun setCurrentServer(currentServer: String?) {
state.update {
copy(currentServer = currentServer)
}
super.setCurrentServer(currentServer)
}
override fun setConnected(isConnected: Boolean) {
state.update {
if (isConnected) {
copy(connected = true)
} else {
session?.let {
ircChannels.values.forEach(it.proxy::stopSynchronize)
ircUsers.values.forEach(it.proxy::stopSynchronize)
}
copy(
connected = false,
myNick = "",
currentServer = "",
ircChannels = emptyMap(),
ircUsers = emptyMap()
)
}
}
super.setConnected(isConnected)
}
override fun setConnectionState(connectionState: Int) {
state.update {
copy(
connectionState = ConnectionState.of(connectionState)
?: ConnectionState.Disconnected
)
}
super.setConnectionState(connectionState)
}
override fun setServerList(serverList: QVariantList) {
state.update {
copy(
serverList = serverList.mapNotNull {
it.into<NetworkServer>()
}
)
}
super.setServerList(serverList)
}
override fun setUseRandomServer(useRandomServer: Boolean) {
state.update {
copy(useRandomServer = useRandomServer)
}
super.setUseRandomServer(useRandomServer)
}
override fun setPerform(perform: QStringList) {
state.update {
copy(perform = perform.map { it ?: "" })
}
super.setPerform(perform)
}
override fun setUseAutoIdentify(useAutoIdentify: Boolean) {
state.update {
copy(useAutoIdentify = useAutoIdentify)
}
super.setUseAutoIdentify(useAutoIdentify)
}
override fun setAutoIdentifyPassword(autoIdentifyPassword: String) {
state.update {
copy(autoIdentifyPassword = autoIdentifyPassword)
}
super.setAutoIdentifyPassword(autoIdentifyPassword)
}
override fun setAutoIdentifyService(autoIdentifyService: String) {
state.update {
copy(autoIdentifyService = autoIdentifyService)
}
super.setAutoIdentifyService(autoIdentifyService)
}
override fun setUseSasl(useSasl: Boolean) {
state.update {
copy(useSasl = useSasl)
}
super.setUseSasl(useSasl)
}
override fun setSaslAccount(saslAccount: String) {
state.update {
copy(saslAccount = saslAccount)
}
super.setSaslAccount(saslAccount)
}
override fun setSaslPassword(saslPassword: String) {
state.update {
copy(saslPassword = saslPassword)
}
super.setSaslPassword(saslPassword)
}
override fun setUseAutoReconnect(useAutoReconnect: Boolean) {
state.update {
copy(useAutoReconnect = useAutoReconnect)
}
super.setUseAutoReconnect(useAutoReconnect)
}
override fun setAutoReconnectInterval(autoReconnectInterval: UInt) {
state.update {
copy(autoReconnectInterval = autoReconnectInterval)
}
super.setAutoReconnectInterval(autoReconnectInterval)
}
override fun setAutoReconnectRetries(autoReconnectRetries: UShort) {
state.update {
copy(autoReconnectRetries = autoReconnectRetries)
}
super.setAutoReconnectRetries(autoReconnectRetries)
}
override fun setUnlimitedReconnectRetries(unlimitedReconnectRetries: Boolean) {
state.update {
copy(unlimitedReconnectRetries = unlimitedReconnectRetries)
}
super.setUnlimitedReconnectRetries(unlimitedReconnectRetries)
}
override fun setRejoinChannels(rejoinChannels: Boolean) {
state.update {
copy(rejoinChannels = rejoinChannels)
}
super.setRejoinChannels(rejoinChannels)
}
override fun setUseCustomMessageRate(useCustomMessageRate: Boolean) {
state.update {
copy(useCustomMessageRate = useCustomMessageRate)
}
super.setUseCustomMessageRate(useCustomMessageRate)
}
override fun setMessageRateBurstSize(messageRateBurstSize: UInt) {
state.update {
copy(messageRateBurstSize = messageRateBurstSize)
}
super.setMessageRateBurstSize(messageRateBurstSize)
}
override fun setMessageRateDelay(messageRateDelay: UInt) {
state.update {
copy(messageRateDelay = messageRateDelay)
}
super.setMessageRateDelay(messageRateDelay)
}
override fun setUnlimitedMessageRate(unlimitedMessageRate: Boolean) {
state.update {
copy(unlimitedMessageRate = unlimitedMessageRate)
}
super.setUnlimitedMessageRate(unlimitedMessageRate)
}
override fun setCodecForServer(codecForServer: ByteBuffer) {
state.update {
copy(codecForServer = StringSerializerUtf8.deserializeRaw(codecForServer))
}
super.setCodecForServer(codecForServer)
}
override fun setCodecForEncoding(codecForEncoding: ByteBuffer) {
state.update {
copy(codecForEncoding = StringSerializerUtf8.deserializeRaw(codecForEncoding))
}
super.setCodecForEncoding(codecForEncoding)
}
override fun setCodecForDecoding(codecForDecoding: ByteBuffer) {
state.update {
copy(codecForDecoding = StringSerializerUtf8.deserializeRaw(codecForDecoding))
}
super.setCodecForDecoding(codecForDecoding)
}
}
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.common
import de.justjanne.libquassel.protocol.models.types.QtType
import de.justjanne.libquassel.protocol.session.Session
import de.justjanne.libquassel.protocol.syncables.StatefulSyncableObject
import de.justjanne.libquassel.protocol.syncables.state.NetworkConfigState
import de.justjanne.libquassel.protocol.syncables.stubs.NetworkConfigStub
import de.justjanne.libquassel.protocol.util.update
import de.justjanne.libquassel.protocol.variant.QVariantMap
import de.justjanne.libquassel.protocol.variant.into
import de.justjanne.libquassel.protocol.variant.qVariant
open class NetworkConfig(
session: Session? = null,
state: NetworkConfigState = NetworkConfigState()
) : StatefulSyncableObject<NetworkConfigState>(session, "NetworkConfig", state),
NetworkConfigStub {
init {
renameObject("GlobalNetworkConfig")
}
override fun fromVariantMap(properties: QVariantMap) {
state.update {
copy(
pingTimeoutEnabled = properties["pingTimeoutEnabled"].into(pingTimeoutEnabled),
pingInterval = properties["pingInterval"].into(pingInterval),
maxPingCount = properties["maxPingCount"].into(maxPingCount),
autoWhoEnabled = properties["autoWhoEnabled"].into(autoWhoEnabled),
autoWhoInterval = properties["autoWhoInterval"].into(autoWhoInterval),
autoWhoNickLimit = properties["autoWhoNickLimit"].into(autoWhoNickLimit),
autoWhoDelay = properties["autoWhoDelay"].into(autoWhoDelay),
standardCtcp = properties["standardCtcp"].into(standardCtcp),
)
}
initialized = true
}
override fun toVariantMap() = mapOf(
"pingTimeoutEnabled" to qVariant(pingTimeoutEnabled(), QtType.Bool),
"pingInterval" to qVariant(pingInterval(), QtType.Int),
"maxPingCount" to qVariant(maxPingCount(), QtType.Int),
"autoWhoEnabled" to qVariant(autoWhoEnabled(), QtType.Bool),
"autoWhoInterval" to qVariant(autoWhoInterval(), QtType.Int),
"autoWhoNickLimit" to qVariant(autoWhoNickLimit(), QtType.Int),
"autoWhoDelay" to qVariant(autoWhoDelay(), QtType.Int),
"standardCtcp" to qVariant(standardCtcp(), QtType.Bool)
)
fun pingTimeoutEnabled() = state().pingTimeoutEnabled
fun pingInterval() = state().pingInterval
fun maxPingCount() = state().maxPingCount
fun autoWhoEnabled() = state().autoWhoEnabled
fun autoWhoInterval() = state().autoWhoInterval
fun autoWhoNickLimit() = state().autoWhoNickLimit
fun autoWhoDelay() = state().autoWhoDelay
fun standardCtcp() = state().standardCtcp
override fun setAutoWhoDelay(delay: Int) {
state.update {
copy(autoWhoDelay = delay)
}
super.setAutoWhoDelay(delay)
}
override fun setAutoWhoEnabled(enabled: Boolean) {
state.update {
copy(autoWhoEnabled = enabled)
}
super.setAutoWhoEnabled(enabled)
}
override fun setAutoWhoInterval(interval: Int) {
state.update {
copy(autoWhoInterval = interval)
}
super.setAutoWhoInterval(interval)
}
override fun setAutoWhoNickLimit(limit: Int) {
state.update {
copy(autoWhoNickLimit = limit)
}
super.setAutoWhoNickLimit(limit)
}
override fun setMaxPingCount(count: Int) {
state.update {
copy(maxPingCount = count)
}
super.setMaxPingCount(count)
}
override fun setPingInterval(interval: Int) {
state.update {
copy(pingInterval = interval)
}
super.setPingInterval(interval)
}
override fun setPingTimeoutEnabled(enabled: Boolean) {
state.update {
copy(pingTimeoutEnabled = enabled)
}
super.setPingTimeoutEnabled(enabled)
}
override fun setStandardCtcp(enabled: Boolean) {
state.update {
copy(standardCtcp = enabled)
}
super.setStandardCtcp(enabled)
}
}
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.invoker
interface InvokerRegistry {
val clientInvokers: Map<String, Invoker>
val coreInvokers: Map<String, Invoker>
}
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.state
import de.justjanne.libquassel.protocol.models.BufferInfo
import de.justjanne.libquassel.protocol.models.alias.Alias
import de.justjanne.libquassel.protocol.models.alias.Command
import de.justjanne.libquassel.protocol.util.expansion.Expansion
data class AliasManagerState(
val aliases: List<Alias> = emptyList()
) {
fun indexOf(name: String?) = aliases.map(Alias::name).indexOf(name)
fun contains(name: String?) = aliases.map(Alias::name).contains(name)
fun processInput(
info: BufferInfo,
networkState: NetworkState?,
message: String
) = mutableListOf<Command>().also {
processInput(info, networkState, message, it)
}
fun processInput(
info: BufferInfo,
networkState: NetworkState?,
message: String,
previousCommands: MutableList<Command>
) {
val (command, arguments) = determineMessageCommand(message)
if (command == null) {
// If no command is found, this means the message should be treated as
// pure text. To ensure this won’t be unescaped twice it’s sent with /SAY.
previousCommands.add(Command(info, "/SAY $arguments"))
} else {
val found = aliases.firstOrNull { it.name.equals(command, true) }
if (found != null) {
expand(found.expansion, info, networkState, arguments, previousCommands)
} else {
previousCommands.add(Command(info, message))
}
}
}
fun expand(
expansion: String,
bufferInfo: BufferInfo,
networkState: NetworkState?,
arguments: String,
previousCommands: MutableList<Command>
) {
val params =
if (arguments.isBlank()) emptyList()
else arguments.split(Regex(" "))
previousCommands.add(
Command(
bufferInfo,
expansion.split(';')
.map(String::trimStart)
.map(Expansion.Companion::parse)
.joinToString(";") {
it.joinToString("") {
when (it) {
is Expansion.Constant -> when (it.field) {
Expansion.ConstantField.CHANNEL ->
bufferInfo.bufferName
Expansion.ConstantField.NICK ->
networkState?.myNick
Expansion.ConstantField.NETWORK ->
networkState?.networkName
}
is Expansion.Parameter ->
if (it.index == 0) arguments
else params.getOrNull(it.index - 1)?.let { param ->
when (it.field) {
Expansion.ParameterField.HOSTNAME ->
networkState?.ircUser(param)?.host()
Expansion.ParameterField.VERIFIED_IDENT ->
networkState?.ircUser(param)?.verifiedUser()
Expansion.ParameterField.IDENT ->
networkState?.ircUser(param)?.user()
Expansion.ParameterField.ACCOUNT ->
networkState?.ircUser(param)?.account()
null -> param
} ?: "*"
} ?: it.source
is Expansion.ParameterRange ->
params.subList(it.from - 1, it.to ?: params.size)
.joinToString(" ")
is Expansion.Text ->
it.source
} ?: it.source
}
}
)
)
}
companion object {
internal fun determineMessageCommand(message: String) = when {
// Only messages starting with a forward slash are commands
!message.startsWith("/") ->
Pair(null, message)
// If a message starts with //, we consider that an escaped slash
message.startsWith("//") ->
Pair(null, message.substring(1))
// If the first word of a message contains more than one slash, it is
// usually a regex of format /[a-z][a-z0-9]*/g, or a path of format
// /usr/bin/powerline-go. In that case we also pass it right through
message.substringBefore(' ').indexOf('/', 1) != -1 ->
Pair(null, message)
// If the first word is purely a /, we won’t consider it a command either
message.substringBefore(' ') == "/" ->
Pair(null, message)
// Otherwise we treat the first word as a command, and all further words as
// arguments
else -> Pair(
message.trimStart('/').substringBefore(' '),
message.substringAfter(' ', missingDelimiterValue = "")
)
}
}
}
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.state
import de.justjanne.libquassel.protocol.models.BufferInfo
import de.justjanne.libquassel.protocol.models.flags.BufferTypes
import de.justjanne.libquassel.protocol.models.flags.MessageTypes
import de.justjanne.libquassel.protocol.models.ids.BufferId
import de.justjanne.libquassel.protocol.models.ids.MsgId
import de.justjanne.libquassel.protocol.models.ids.NetworkId
data class BufferSyncerState(
val activities: Map<BufferId, MessageTypes> = emptyMap(),
val highlightCounts: Map<BufferId, Int> = emptyMap(),
val lastSeenMsg: Map<BufferId, MsgId> = emptyMap(),
val markerLines: Map<BufferId, MsgId> = emptyMap(),
val bufferInfos: Map<BufferId, BufferInfo> = emptyMap()
) {
fun where(
bufferName: String? = null,
bufferId: BufferId? = null,
networkId: NetworkId? = null,
type: BufferTypes? = null,
groupId: Int? = null,
networkState: NetworkState? = null
) = bufferInfos.values.asSequence()
.filter {
bufferName == null ||
networkState == null ||
networkState.caseMapper().equalsIgnoreCase(it.bufferName, bufferName)
}
.filter { bufferId == null || it.bufferId == bufferId }
.filter { networkId == null || it.networkId == networkId }
.filter { type == null || it.type == type }
.filter { groupId == null || it.groupId == groupId }
fun find(
bufferName: String? = null,
bufferId: BufferId? = null,
networkId: NetworkId? = null,
type: BufferTypes? = null,
groupId: Int? = null,
networkState: NetworkState? = null
) = where(bufferName, bufferId, networkId, type, groupId, networkState).firstOrNull()
fun all(
bufferName: String? = null,
bufferId: BufferId? = null,
networkId: NetworkId? = null,
type: BufferTypes? = null,
groupId: Int? = null,
networkState: NetworkState? = null
) = where(bufferName, bufferId, networkId, type, groupId, networkState).toList()
}
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.state
import de.justjanne.libquassel.protocol.models.BufferActivity
import de.justjanne.libquassel.protocol.models.flags.BufferType
import de.justjanne.libquassel.protocol.models.flags.BufferTypes
import de.justjanne.libquassel.protocol.models.ids.BufferId
import de.justjanne.libquassel.protocol.models.ids.NetworkId
data class BufferViewConfigState(
val bufferViewId: Int,
val bufferViewName: String = "",
val networkId: NetworkId = NetworkId(0),
val addNewBuffersAutomatically: Boolean = true,
val sortAlphabetically: Boolean = true,
val hideInactiveBuffers: Boolean = false,
val hideInactiveNetworks: Boolean = false,
val disableDecoration: Boolean = false,
val allowedBufferTypes: BufferTypes = BufferType.all,
val minimumActivity: BufferActivity? = null,
val showSearch: Boolean = false,
val buffers: List<BufferId> = emptyList(),
val removedBuffers: Set<BufferId> = emptySet(),
val hiddenBuffers: Set<BufferId> = emptySet(),
) {
fun identifier() = "$bufferViewId"
}
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.state
import de.justjanne.libquassel.protocol.syncables.common.BufferViewConfig
data class BufferViewManagerState(
val bufferViewConfigs: Map<Int, BufferViewConfig> = emptyMap()
) {
fun contains(bufferViewId: Int) = bufferViewConfigs.containsKey(bufferViewId)
fun bufferViewConfig(bufferViewId: Int) = bufferViewConfigs[bufferViewId]
fun bufferViewConfigs() = bufferViewConfigs.values
}
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.state
import de.justjanne.libquassel.protocol.models.ids.IdentityId
import org.bouncycastle.cert.X509CertificateHolder
import org.bouncycastle.openssl.PEMKeyPair
import org.bouncycastle.openssl.PEMParser
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter
import java.security.PrivateKey
import java.security.cert.Certificate
import java.security.cert.CertificateFactory
data class CertManagerState(
val identityId: IdentityId,
val privateKeyPem: String = "",
val certificatePem: String = "",
) {
val privateKey = readPrivateKey(privateKeyPem)
val certificate = readCertificate(certificatePem)
fun identifier() = "${identityId.id}"
private fun readPrivateKey(pem: String): PrivateKey? {
if (pem.isBlank()) {
return null
}
try {
val keyPair = PEMParser(pem.reader()).readObject() as? PEMKeyPair
?: return null
return JcaPEMKeyConverter().getPrivateKey(keyPair.privateKeyInfo)
} catch (t: Throwable) {
return null
}
}
private fun readCertificate(pem: String): Certificate? {
if (pem.isBlank()) {
return null
}
try {
val certificate = PEMParser(pem.reader()).readObject() as? X509CertificateHolder
?: return null
return CertificateFactory.getInstance("X.509")
.generateCertificate(certificate.encoded.inputStream())
} catch (t: Throwable) {
return null
}
}
}
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.state
import de.justjanne.libquassel.protocol.models.ConnectedClient
import org.threeten.bp.Instant
data class CoreInfoState(
val version: String = "",
val versionDate: Instant? = null,
val startTime: Instant = Instant.EPOCH,
val connectedClientCount: Int = 0,
val connectedClients: List<ConnectedClient> = emptyList()
)
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.state
import de.justjanne.libquassel.protocol.models.dcc.DccIpDetectionMode
import de.justjanne.libquassel.protocol.models.dcc.DccPortSelectionMode
import java.net.InetAddress
data class DccConfigState(
val dccEnabled: Boolean = false,
val outgoingIp: InetAddress = InetAddress.getLocalHost(),
val ipDetectionMode: DccIpDetectionMode = DccIpDetectionMode.Automatic,
val portSelectionMode: DccPortSelectionMode = DccPortSelectionMode.Automatic,
val minPort: UShort = 1024u,
val maxPort: UShort = 32767u,
val chunkSize: Int = 16,
val sendTimeout: Int = 180,
val usePassiveDcc: Boolean = false,
val useFastSend: Boolean = false
)
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.state
import de.justjanne.libquassel.irc.IrcFormat
import de.justjanne.libquassel.irc.IrcFormatDeserializer
import de.justjanne.libquassel.protocol.models.flags.MessageFlag
import de.justjanne.libquassel.protocol.models.flags.MessageFlags
import de.justjanne.libquassel.protocol.models.flags.MessageType
import de.justjanne.libquassel.protocol.models.flags.MessageTypes
import de.justjanne.libquassel.protocol.models.rules.HighlightNickType
import de.justjanne.libquassel.protocol.models.rules.HighlightRule
import de.justjanne.libquassel.protocol.util.expression.ExpressionMatch
data class HighlightRuleManagerState(
val rules: List<HighlightRule> = emptyList(),
val highlightNickType: HighlightNickType = HighlightNickType.CurrentNick,
val highlightNickCaseSensitive: Boolean = false
) {
fun match(
message: String,
sender: String,
type: MessageTypes,
flags: MessageFlags,
bufferName: String,
currentNick: String,
identityNicks: List<String>
): Boolean {
val messageContent = IrcFormatDeserializer.parse(message)
.map(IrcFormat.Span::content)
.joinToString()
if (!type.contains(MessageType.Action) &&
!type.contains(MessageType.Notice) &&
!type.contains(MessageType.Plain)
) {
return false
}
if (flags.contains(MessageFlag.Self)) {
return false
}
val matchingRules = rules.asSequence()
.filter { it.isEnabled }
.filter { it.channelMatch.match(bufferName, true) }
.filter { it.senderMatch.match(sender, true) }
.filter { it.contentMatch.match(messageContent, true) }
.toList()
if (matchingRules.any(HighlightRule::isInverse)) {
return false
}
if (matchingRules.isNotEmpty()) {
return true
}
val nicks = when (highlightNickType) {
HighlightNickType.NoNick -> return false
HighlightNickType.CurrentNick -> listOf(currentNick)
HighlightNickType.AllNicks -> identityNicks + currentNick
}.filter(String::isNotBlank)
if (nicks.isNotEmpty() && ExpressionMatch(
nicks.joinToString("\n"),
ExpressionMatch.MatchMode.MatchMultiPhrase,
highlightNickCaseSensitive
).match(messageContent)
) {
return true
}
return false
}
fun indexOf(id: Int): Int = rules.indexOfFirst { it.id == id }
fun contains(id: Int) = rules.any { it.id == id }
fun isEmpty() = rules.isEmpty()
fun count() = rules.size
}
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.state
import de.justjanne.bitflags.of
import de.justjanne.libquassel.protocol.models.flags.MessageType
import de.justjanne.libquassel.protocol.models.flags.MessageTypes
import de.justjanne.libquassel.protocol.models.rules.IgnoreRule
import de.justjanne.libquassel.protocol.models.rules.IgnoreType
import de.justjanne.libquassel.protocol.models.rules.ScopeType
import de.justjanne.libquassel.protocol.models.rules.StrictnessType
data class IgnoreListManagerState(
val rules: List<IgnoreRule> = emptyList()
) {
fun indexOf(ignoreRule: String?): Int = rules.indexOfFirst { it.ignoreRule == ignoreRule }
fun contains(ignoreRule: String?) = rules.any { it.ignoreRule == ignoreRule }
fun isEmpty() = rules.isEmpty()
fun count() = rules.size
fun matchingRules(sender: String) = rules.filter {
it.type == IgnoreType.SenderIgnore && it.ignoreMatch.match(sender)
}
fun match(
msgContents: String,
msgSender: String,
msgType: MessageTypes,
network: String,
bufferName: String
): StrictnessType {
if ((MessageType.of(MessageType.Plain, MessageType.Notice, MessageType.Action) intersect msgType).isEmpty()) {
return StrictnessType.UnmatchedStrictness
}
return rules.asSequence().filter {
it.isEnabled && it.type != IgnoreType.CtcpIgnore
}.filter {
it.scope == ScopeType.GlobalScope ||
it.scope == ScopeType.NetworkScope && it.scopeMatch.match(network) ||
it.scope == ScopeType.ChannelScope && it.scopeMatch.match(bufferName)
}.filter {
val content = if (it.type == IgnoreType.MessageIgnore) msgContents else msgSender
it.ignoreMatch.match(content)
}.map {
it.strictness
}.maxByOrNull {
it.value
} ?: StrictnessType.UnmatchedStrictness
}
}
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.state
import de.justjanne.libquassel.protocol.models.ids.NetworkId
import de.justjanne.libquassel.protocol.models.network.ChannelModeType
import de.justjanne.libquassel.protocol.models.network.ChannelModes
data class IrcChannelState(
val network: NetworkId,
val name: String,
val topic: String = "",
val password: String = "",
val encrypted: Boolean = false,
val channelModes: ChannelModes = ChannelModes(),
val userModes: Map<String, Set<Char>> = emptyMap()
) {
fun identifier() = "${network.id}/$name"
fun channelModeString() = channelModes.modeString()
fun ircUsers(networkState: NetworkState?) = networkState?.let { network ->
userModes.keys.mapNotNull(network::ircUser)
}.orEmpty()
fun userCount() = userModes.size
fun userModes(nick: String) = userModes[nick]
fun hasMode(networkState: NetworkState?, mode: Char) = when (networkState?.channelModeType(mode)) {
ChannelModeType.A_CHANMODE ->
channelModes.a.contains(mode)
ChannelModeType.B_CHANMODE ->
channelModes.b.contains(mode)
ChannelModeType.C_CHANMODE ->
channelModes.c.contains(mode)
ChannelModeType.D_CHANMODE ->
channelModes.d.contains(mode)
else ->
false
}
fun modeValue(networkState: NetworkState?, mode: Char) = when (networkState?.channelModeType(mode)) {
ChannelModeType.B_CHANMODE ->
channelModes.b[mode] ?: ""
ChannelModeType.C_CHANMODE ->
channelModes.c[mode] ?: ""
else ->
""
}
fun modeValues(networkState: NetworkState?, mode: Char) = when (networkState?.channelModeType(mode)) {
ChannelModeType.A_CHANMODE ->
channelModes.a[mode].orEmpty()
else ->
emptySet()
}
}
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.state
data class NetworkConfigState(
val pingTimeoutEnabled: Boolean = true,
val pingInterval: Int = 30,
val maxPingCount: Int = 6,
val autoWhoEnabled: Boolean = true,
val autoWhoInterval: Int = 90,
val autoWhoNickLimit: Int = 200,
val autoWhoDelay: Int = 5,
val standardCtcp: Boolean = false
)
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.state
import de.justjanne.libquassel.irc.IrcCapability
import de.justjanne.libquassel.irc.IrcCaseMapper
import de.justjanne.libquassel.irc.IrcISupport
import de.justjanne.libquassel.protocol.models.ids.IdentityId
import de.justjanne.libquassel.protocol.models.ids.NetworkId
import de.justjanne.libquassel.protocol.models.network.ChannelModeType
import de.justjanne.libquassel.protocol.models.network.ConnectionState
import de.justjanne.libquassel.protocol.models.network.NetworkServer
import de.justjanne.libquassel.protocol.syncables.common.IrcChannel
import de.justjanne.libquassel.protocol.syncables.common.IrcUser
import java.util.Locale
data class NetworkState(
val networkId: NetworkId,
val identity: IdentityId = IdentityId(-1),
val myNick: String? = "",
val latency: Int = 0,
val networkName: String = "<not initialized>",
val currentServer: String? = "",
val connected: Boolean = false,
val connectionState: ConnectionState = ConnectionState.Disconnected,
val ircUsers: Map<String, IrcUser> = emptyMap(),
val ircChannels: Map<String, IrcChannel> = emptyMap(),
val supports: Map<String, String?> = emptyMap(),
val caps: Map<String, String?> = emptyMap(),
val capsEnabled: Set<String> = emptySet(),
val skipCaps: Set<String> = emptySet(),
val serverList: List<NetworkServer> = emptyList(),
val useRandomServer: Boolean = false,
val perform: List<String> = emptyList(),
val useAutoIdentify: Boolean = false,
val autoIdentifyService: String = "",
val autoIdentifyPassword: String = "",
val useSasl: Boolean = false,
val saslAccount: String = "",
val saslPassword: String = "",
val useAutoReconnect: Boolean = false,
val autoReconnectInterval: UInt = 60u,
val autoReconnectRetries: UShort = 10u,
val unlimitedReconnectRetries: Boolean = false,
val rejoinChannels: Boolean = false,
val useCustomMessageRate: Boolean = false,
val messageRateBurstSize: UInt = 5u,
val messageRateDelay: UInt = 2200u,
val unlimitedMessageRate: Boolean = false,
val codecForServer: String = "UTF_8",
val codecForEncoding: String = "UTF_8",
val codecForDecoding: String = "UTF_8"
) {
val prefixes: List<Char>
val prefixModes: List<Char>
val channelModes: Map<ChannelModeType, Set<Char>>
init {
val (prefixes, prefixModes) = determinePrefixes()
this.prefixes = prefixes
this.prefixModes = prefixModes
this.channelModes = determineChannelModeTypes()
}
fun identifier() = "${networkId.id}"
fun caseMapper() = IrcCaseMapper[supportValue(IrcISupport.CASEMAPPING)]
fun supports(key: String) = supports.containsKey(key.uppercase(Locale.ROOT))
fun supportValue(key: String) = supports[key.uppercase(Locale.ROOT)]
fun capAvailable(capability: String) = caps.containsKey(capability.lowercase(Locale.ROOT))
fun capEnabled(capability: String) = capsEnabled.contains(capability.lowercase(Locale.ROOT))
fun capValue(capability: String) = caps[capability.lowercase(Locale.ROOT)] ?: ""
fun isSaslSupportLikely(mechanism: String): Boolean {
if (!capAvailable(IrcCapability.SASL)) {
return false
}
val capValue = capValue(IrcCapability.SASL)
return (capValue.isBlank() || capValue.contains(mechanism, ignoreCase = true))
}
fun ircUser(nickName: String) = ircUsers[caseMapper().toLowerCase(nickName)]
fun ircChannel(name: String) = ircChannels[caseMapper().toLowerCase(name)]
fun me() = myNick?.let(::ircUser)
fun isMe(user: IrcUser): Boolean {
return caseMapper().equalsIgnoreCase(user.nick(), myNick)
}
fun channelModeType(mode: Char): ChannelModeType? {
return channelModes.entries.find {
it.value.contains(mode)
}?.key
}
private fun determinePrefixes(): Pair<List<Char>, List<Char>> {
val defaultPrefixes = listOf('~', '&', '@', '%', '+')
val defaultPrefixModes = listOf('q', 'a', 'o', 'h', 'v')
val prefix = supportValue(IrcISupport.PREFIX)
?: return Pair(defaultPrefixes, defaultPrefixModes)
if (prefix.startsWith("(") && prefix.contains(")")) {
val (prefixModes, prefixes) = prefix.substringAfter('(')
.split(')', limit = 2)
.map(String::toList)
return Pair(prefixModes, prefixes)
} else if (prefix.isBlank()) {
return Pair(defaultPrefixes, defaultPrefixModes)
} else if ((prefix.toSet() intersect defaultPrefixes.toSet()).isNotEmpty()) {
val (prefixes, prefixModes) = defaultPrefixes.zip(defaultPrefixModes)
.filter { prefix.contains(it.first) }
.unzip()
return Pair(prefixes, prefixModes)
} else if ((prefix.toSet() intersect defaultPrefixModes.toSet()).isNotEmpty()) {
val (prefixes, prefixModes) = defaultPrefixes.zip(defaultPrefixModes)
.filter { prefix.contains(it.second) }
.unzip()
return Pair(prefixes, prefixModes)
}
return Pair(defaultPrefixes, defaultPrefixModes)
}
private fun determineChannelModeTypes(): Map<ChannelModeType, Set<Char>> {
val groups = supportValue(IrcISupport.CHANMODES)
?.split(',')
?.map(String::toSet)
.orEmpty()
return ChannelModeType.values().withIndex().map { (index, key) ->
key to groups.getOrNull(index).orEmpty()
}.toMap()
}
}
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.stubs
import de.justjanne.libquassel.annotations.ProtocolSide
import de.justjanne.libquassel.annotations.SyncedCall
import de.justjanne.libquassel.annotations.SyncedObject
import de.justjanne.libquassel.protocol.models.types.QtType
import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
import de.justjanne.libquassel.protocol.variant.QVariantMap
import de.justjanne.libquassel.protocol.variant.qVariant
@SyncedObject("AliasManager")
interface AliasManagerStub : StatefulSyncableStub {
@SyncedCall(target = ProtocolSide.CORE)
fun addAlias(name: String, expansion: String) {
sync(
target = ProtocolSide.CORE,
"addAlias",
qVariant(name, QtType.QString),
qVariant(expansion, QtType.QString)
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
override fun update(properties: QVariantMap) = super.update(properties)
@SyncedCall(target = ProtocolSide.CORE)
override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
}
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.stubs
import de.justjanne.libquassel.annotations.ProtocolSide
import de.justjanne.libquassel.annotations.SyncedCall
import de.justjanne.libquassel.annotations.SyncedObject
import de.justjanne.libquassel.protocol.models.ids.BufferId
import de.justjanne.libquassel.protocol.models.ids.MsgId
import de.justjanne.libquassel.protocol.models.types.QtType
import de.justjanne.libquassel.protocol.models.types.QuasselType
import de.justjanne.libquassel.protocol.syncables.SyncableStub
import de.justjanne.libquassel.protocol.variant.QVariantList
import de.justjanne.libquassel.protocol.variant.qVariant
@SyncedObject("BacklogManager")
interface BacklogManagerStub : SyncableStub {
/**
* Loads backlog for [bufferId], where the message id is >= [first] and < [last].
* If [first] or [last] is unset, the list will be unbounded in that direction.
*
* If a [limit] is set, the list will be truncated to the newest N messages.
*
* If both [first] and [last] are set, and the list of messages is not truncated by [limit],
* [additional] messages will be loaded before [last].
*/
@SyncedCall(target = ProtocolSide.CORE)
fun requestBacklog(
bufferId: BufferId,
first: MsgId = MsgId(-1),
last: MsgId = MsgId(-1),
limit: Int = -1,
additional: Int = 0
) {
sync(
target = ProtocolSide.CORE,
"requestBacklog",
qVariant(bufferId, QuasselType.BufferId),
qVariant(first, QuasselType.MsgId),
qVariant(last, QuasselType.MsgId),
qVariant(limit, QtType.Int),
qVariant(additional, QtType.Int),
)
}
/**
* Loads backlog for [bufferId], where the message id is >= [first] and < [last].
* If [first] or [last] is unset, the list will be unbounded in that direction.
*
* If a [limit] is set, the list will be truncated to the newest N messages.
*
* If both [first] and [last] are set, and the list of messages is not truncated by [limit],
* [additional] messages will be loaded before [last].
*
* Only messages matching [type] and [flags] will be returned and counted.
*/
@SyncedCall(target = ProtocolSide.CORE)
fun requestBacklogFiltered(
bufferId: BufferId,
first: MsgId = MsgId(-1),
last: MsgId = MsgId(-1),
limit: Int = -1,
additional: Int = 0,
type: Int = -1,
flags: Int = -1
) {
sync(
target = ProtocolSide.CORE,
"requestBacklogFiltered",
qVariant(bufferId, QuasselType.BufferId),
qVariant(first, QuasselType.MsgId),
qVariant(last, QuasselType.MsgId),
qVariant(limit, QtType.Int),
qVariant(additional, QtType.Int),
qVariant(type, QtType.Int),
qVariant(flags, QtType.Int),
)
}
/**
* Loads backlog for [bufferId], where the message id is >= [first] and < [last].
* If [first] or [last] is unset, the list will be unbounded in that direction.
*
* If a [limit] is set, the list will be truncated to the oldest N messages.
*
* Only messages matching [type] and [flags] will be returned and counted.
*/
@SyncedCall(target = ProtocolSide.CORE)
fun requestBacklogForward(
bufferId: BufferId,
first: MsgId = MsgId(-1),
last: MsgId = MsgId(-1),
limit: Int = -1,
type: Int = -1,
flags: Int = -1
) {
sync(
target = ProtocolSide.CORE,
"requestBacklogForward",
qVariant(bufferId, QuasselType.BufferId),
qVariant(first, QuasselType.MsgId),
qVariant(last, QuasselType.MsgId),
qVariant(limit, QtType.Int),
qVariant(type, QtType.Int),
qVariant(flags, QtType.Int),
)
}
/**
* Loads backlog for all buffers, where the message id is >= [first] and < [last].
* If [first] or [last] is unset, the list will be unbounded in that direction.
*
* If a [limit] is set, the list will be truncated to the newest N messages.
*
* If both [first] and [last] are set, and the list of messages is not truncated by [limit],
* [additional] messages will be loaded before [last].
*/
@SyncedCall(target = ProtocolSide.CORE)
fun requestBacklogAll(
first: MsgId = MsgId(-1),
last: MsgId = MsgId(-1),
limit: Int = -1,
additional: Int = 0
) {
sync(
target = ProtocolSide.CORE,
"requestBacklogAll",
qVariant(first, QuasselType.MsgId),
qVariant(last, QuasselType.MsgId),
qVariant(limit, QtType.Int),
qVariant(additional, QtType.Int),
)
}
/**
* Loads backlog for all buffers, where the message id is >= [first] and < [last].
* If [first] or [last] is unset, the list will be unbounded in that direction.
*
* If a [limit] is set, the list will be truncated to the newest N messages.
*
* If both [first] and [last] are set, and the list of messages is not truncated by [limit],
* [additional] messages will be loaded before [last].
*
* Only messages matching [type] and [flags] will be returned and counted.
*/
@SyncedCall(target = ProtocolSide.CORE)
fun requestBacklogAllFiltered(
first: MsgId = MsgId(-1),
last: MsgId = MsgId(-1),
limit: Int = -1,
additional: Int = 0,
type: Int = -1,
flags: Int = -1
) {
sync(
target = ProtocolSide.CORE,
"requestBacklogAll",
qVariant(first, QuasselType.MsgId),
qVariant(last, QuasselType.MsgId),
qVariant(limit, QtType.Int),
qVariant(additional, QtType.Int),
qVariant(type, QtType.Int),
qVariant(flags, QtType.Int),
)
}
/**
* Response to the corresponding [requestBacklog] call.
* [messages] contains the messages as `QVariant<Message>`
*/
@SyncedCall(target = ProtocolSide.CLIENT)
fun receiveBacklog(
bufferId: BufferId,
first: MsgId = MsgId(-1),
last: MsgId = MsgId(-1),
limit: Int = -1,
additional: Int = 0,
messages: QVariantList
) {
sync(
target = ProtocolSide.CLIENT,
"receiveBacklog",
qVariant(bufferId, QuasselType.BufferId),
qVariant(first, QuasselType.MsgId),
qVariant(last, QuasselType.MsgId),
qVariant(limit, QtType.Int),
qVariant(additional, QtType.Int),
qVariant(messages, QtType.QVariantList),
)
}
/**
* Response to the corresponding [requestBacklogFiltered] call.
* [messages] contains the messages as `QVariant<Message>`
*/
@SyncedCall(target = ProtocolSide.CLIENT)
fun receiveBacklogFiltered(
bufferId: BufferId,
first: MsgId = MsgId(-1),
last: MsgId = MsgId(-1),
limit: Int = -1,
additional: Int = 0,
type: Int = -1,
flags: Int = -1,
messages: QVariantList
) {
sync(
target = ProtocolSide.CLIENT,
"receiveBacklogFiltered",
qVariant(bufferId, QuasselType.BufferId),
qVariant(first, QuasselType.MsgId),
qVariant(last, QuasselType.MsgId),
qVariant(limit, QtType.Int),
qVariant(additional, QtType.Int),
qVariant(type, QtType.Int),
qVariant(flags, QtType.Int),
qVariant(messages, QtType.QVariantList),
)
}
/**
* Response to the corresponding [requestBacklogForward] call.
* [messages] contains the messages as `QVariant<Message>`
*/
@SyncedCall(target = ProtocolSide.CLIENT)
fun receiveBacklogForward(
bufferId: BufferId,
first: MsgId = MsgId(-1),
last: MsgId = MsgId(-1),
limit: Int = -1,
type: Int = -1,
flags: Int = -1,
messages: QVariantList
) {
sync(
target = ProtocolSide.CLIENT,
"receiveBacklogForward",
qVariant(bufferId, QuasselType.BufferId),
qVariant(first, QuasselType.MsgId),
qVariant(last, QuasselType.MsgId),
qVariant(limit, QtType.Int),
qVariant(type, QtType.Int),
qVariant(flags, QtType.Int),
qVariant(messages, QtType.QVariantList),
)
}
/**
* Response to the corresponding [requestBacklogAll] call.
* [messages] contains the messages as `QVariant<Message>`
*/
@SyncedCall(target = ProtocolSide.CLIENT)
fun receiveBacklogAll(
first: MsgId = MsgId(-1),
last: MsgId = MsgId(-1),
limit: Int = -1,
additional: Int = 0,
messages: QVariantList
) {
sync(
target = ProtocolSide.CLIENT,
"receiveBacklogAll",
qVariant(first, QuasselType.MsgId),
qVariant(last, QuasselType.MsgId),
qVariant(limit, QtType.Int),
qVariant(additional, QtType.Int),
qVariant(messages, QtType.QVariantList),
)
}
/**
* Response to the corresponding [requestBacklogAllFiltered] call.
* [messages] contains the messages as `QVariant<Message>`
*/
@SyncedCall(target = ProtocolSide.CLIENT)
fun receiveBacklogAllFiltered(
first: MsgId = MsgId(-1),
last: MsgId = MsgId(-1),
limit: Int = -1,
additional: Int = 0,
type: Int = -1,
flags: Int = -1,
messages: QVariantList
) {
sync(
target = ProtocolSide.CLIENT,
"receiveBacklogAllFiltered",
qVariant(first, QuasselType.MsgId),
qVariant(last, QuasselType.MsgId),
qVariant(limit, QtType.Int),
qVariant(additional, QtType.Int),
qVariant(type, QtType.Int),
qVariant(flags, QtType.Int),
qVariant(messages, QtType.QVariantList),
)
}
}
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.stubs
import de.justjanne.libquassel.annotations.ProtocolSide
import de.justjanne.libquassel.annotations.SyncedCall
import de.justjanne.libquassel.annotations.SyncedObject
import de.justjanne.libquassel.protocol.models.ids.BufferId
import de.justjanne.libquassel.protocol.models.ids.MsgId
import de.justjanne.libquassel.protocol.models.types.QtType
import de.justjanne.libquassel.protocol.models.types.QuasselType
import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
import de.justjanne.libquassel.protocol.variant.QVariantMap
import de.justjanne.libquassel.protocol.variant.qVariant
@SyncedObject("BufferSyncer")
interface BufferSyncerStub : StatefulSyncableStub {
@SyncedCall(target = ProtocolSide.CLIENT)
fun markBufferAsRead(buffer: BufferId) {
sync(
target = ProtocolSide.CLIENT,
"markBufferAsRead",
qVariant(buffer, QuasselType.BufferId),
)
}
@SyncedCall(target = ProtocolSide.CORE)
fun requestMarkBufferAsRead(buffer: BufferId) {
sync(
target = ProtocolSide.CORE,
"requestMarkBufferAsRead",
qVariant(buffer, QuasselType.BufferId),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun mergeBuffersPermanently(buffer: BufferId, buffer2: BufferId) {
sync(
target = ProtocolSide.CLIENT,
"mergeBuffersPermanently",
qVariant(buffer, QuasselType.BufferId),
qVariant(buffer2, QuasselType.BufferId),
)
}
@SyncedCall(target = ProtocolSide.CORE)
fun requestMergeBuffersPermanently(buffer: BufferId, buffer2: BufferId) {
sync(
target = ProtocolSide.CORE,
"requestMergeBuffersPermanently",
qVariant(buffer, QuasselType.BufferId),
qVariant(buffer2, QuasselType.BufferId),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun removeBuffer(buffer: BufferId) {
sync(
target = ProtocolSide.CLIENT,
"removeBuffer",
qVariant(buffer, QuasselType.BufferId),
)
}
@SyncedCall(target = ProtocolSide.CORE)
fun requestRemoveBuffer(buffer: BufferId) {
sync(
target = ProtocolSide.CORE,
"requestRemoveBuffer",
qVariant(buffer, QuasselType.BufferId),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun renameBuffer(buffer: BufferId, newName: String) {
sync(
target = ProtocolSide.CLIENT,
"renameBuffer",
qVariant(buffer, QuasselType.BufferId),
qVariant(newName, QtType.QString),
)
}
@SyncedCall(target = ProtocolSide.CORE)
fun requestRenameBuffer(buffer: BufferId, newName: String) {
sync(
target = ProtocolSide.CORE,
"requestRenameBuffer",
qVariant(buffer, QuasselType.BufferId),
qVariant(newName, QtType.QString),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun setMarkerLine(buffer: BufferId, msgId: MsgId) {
sync(
target = ProtocolSide.CLIENT,
"setMarkerLine",
qVariant(buffer, QuasselType.BufferId),
qVariant(msgId, QuasselType.MsgId),
)
}
@SyncedCall(target = ProtocolSide.CORE)
fun requestSetLastSeenMsg(buffer: BufferId, msgId: MsgId) {
sync(
target = ProtocolSide.CORE,
"requestSetLastSeenMsg",
qVariant(buffer, QuasselType.BufferId),
qVariant(msgId, QuasselType.MsgId),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun setLastSeenMsg(buffer: BufferId, msgId: MsgId) {
sync(
target = ProtocolSide.CLIENT,
"setLastSeenMsg",
qVariant(buffer, QuasselType.BufferId),
qVariant(msgId, QuasselType.MsgId),
)
}
@SyncedCall(target = ProtocolSide.CORE)
fun requestSetMarkerLine(buffer: BufferId, msgId: MsgId) {
sync(
target = ProtocolSide.CORE,
"requestSetMarkerLine",
qVariant(buffer, QuasselType.BufferId),
qVariant(msgId, QuasselType.MsgId),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun setBufferActivity(buffer: BufferId, types: Int) {
sync(
target = ProtocolSide.CLIENT,
"setBufferActivity",
qVariant(buffer, QuasselType.BufferId),
qVariant(types, QtType.Int),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun setHighlightCount(buffer: BufferId, count: Int) {
sync(
target = ProtocolSide.CLIENT,
"setHighlightCount",
qVariant(buffer, QuasselType.BufferId),
qVariant(count, QtType.Int),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun requestPurgeBufferIds() {
sync(
target = ProtocolSide.CLIENT,
"requestPurgeBufferIds"
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
override fun update(properties: QVariantMap) = super.update(properties)
@SyncedCall(target = ProtocolSide.CORE)
override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
}
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.syncables.stubs
import de.justjanne.libquassel.annotations.ProtocolSide
import de.justjanne.libquassel.annotations.SyncedCall
import de.justjanne.libquassel.annotations.SyncedObject
import de.justjanne.libquassel.protocol.models.ids.BufferId
import de.justjanne.libquassel.protocol.models.ids.NetworkId
import de.justjanne.libquassel.protocol.models.types.QtType
import de.justjanne.libquassel.protocol.models.types.QuasselType
import de.justjanne.libquassel.protocol.syncables.StatefulSyncableStub
import de.justjanne.libquassel.protocol.variant.QVariantMap
import de.justjanne.libquassel.protocol.variant.qVariant
@SyncedObject("BufferViewConfig")
interface BufferViewConfigStub : StatefulSyncableStub {
@SyncedCall(target = ProtocolSide.CLIENT)
fun addBuffer(buffer: BufferId, pos: Int) {
sync(
target = ProtocolSide.CLIENT,
"addBuffer",
qVariant(buffer, QuasselType.BufferId),
qVariant(pos, QtType.Int),
)
}
@SyncedCall(target = ProtocolSide.CORE)
fun requestAddBuffer(buffer: BufferId, pos: Int) {
sync(
target = ProtocolSide.CORE,
"requestAddBuffer",
qVariant(buffer, QuasselType.BufferId),
qVariant(pos, QtType.Int),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun moveBuffer(buffer: BufferId, pos: Int) {
sync(
target = ProtocolSide.CLIENT,
"moveBuffer",
qVariant(buffer, QuasselType.BufferId),
qVariant(pos, QtType.Int),
)
}
@SyncedCall(target = ProtocolSide.CORE)
fun requestMoveBuffer(buffer: BufferId, pos: Int) {
sync(
target = ProtocolSide.CORE,
"requestMoveBuffer",
qVariant(buffer, QuasselType.BufferId),
qVariant(pos, QtType.Int),
)
}
@SyncedCall(target = ProtocolSide.CLIENT, name = "removeBuffer")
fun hideBuffer(buffer: BufferId) {
sync(
target = ProtocolSide.CLIENT,
"removeBuffer",
qVariant(buffer, QuasselType.BufferId),
)
}
@SyncedCall(target = ProtocolSide.CORE)
fun requestHideBuffer(buffer: BufferId) {
sync(
target = ProtocolSide.CORE,
"requestRemoveBuffer",
qVariant(buffer, QuasselType.BufferId),
)
}
@SyncedCall(target = ProtocolSide.CLIENT, name = "removeBufferPermanently")
fun removeBuffer(buffer: BufferId) {
sync(
target = ProtocolSide.CLIENT,
"removeBufferPermanently",
qVariant(buffer, QuasselType.BufferId),
)
}
@SyncedCall(target = ProtocolSide.CORE)
fun requestRemoveBuffer(buffer: BufferId) {
sync(
target = ProtocolSide.CORE,
"requestRemoveBufferPermanently",
qVariant(buffer, QuasselType.BufferId),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun setBufferViewName(value: String) {
sync(
target = ProtocolSide.CLIENT,
"setBufferViewName",
qVariant(value, QtType.QString),
)
}
@SyncedCall(target = ProtocolSide.CORE)
fun requestSetBufferViewName(value: String) {
sync(
target = ProtocolSide.CORE,
"requestSetBufferViewName",
qVariant(value, QtType.QString),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun setAddNewBuffersAutomatically(value: Boolean) {
sync(
target = ProtocolSide.CLIENT,
"setAddNewBuffersAutomatically",
qVariant(value, QtType.Bool),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun setAllowedBufferTypes(value: Int) {
sync(
target = ProtocolSide.CLIENT,
"setAllowedBufferTypes",
qVariant(value, QtType.Int),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun setDisableDecoration(value: Boolean) {
sync(
target = ProtocolSide.CLIENT,
"setDisableDecoration",
qVariant(value, QtType.Bool),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun setHideInactiveBuffers(value: Boolean) {
sync(
target = ProtocolSide.CLIENT,
"setHideInactiveBuffers",
qVariant(value, QtType.Bool),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun setHideInactiveNetworks(value: Boolean) {
sync(
target = ProtocolSide.CLIENT,
"setHideInactiveNetworks",
qVariant(value, QtType.Bool),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun setMinimumActivity(value: Int) {
sync(
target = ProtocolSide.CLIENT,
"setMinimumActivity",
qVariant(value, QtType.Int),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun setNetworkId(value: NetworkId) {
sync(
target = ProtocolSide.CLIENT,
"setNetworkId",
qVariant(value, QuasselType.NetworkId),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun setShowSearch(value: Boolean) {
sync(
target = ProtocolSide.CLIENT,
"setShowSearch",
qVariant(value, QtType.Bool),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
fun setSortAlphabetically(value: Boolean) {
sync(
target = ProtocolSide.CLIENT,
"setSortAlphabetically",
qVariant(value, QtType.Bool),
)
}
@SyncedCall(target = ProtocolSide.CLIENT)
override fun update(properties: QVariantMap) = super.update(properties)
@SyncedCall(target = ProtocolSide.CORE)
override fun requestUpdate(properties: QVariantMap) = super.requestUpdate(properties)
}