Compare commits
2 Commits
20b3b43394
...
3fc97ff6ea
Author | SHA1 | Date | |
---|---|---|---|
3fc97ff6ea | |||
3c999daebc |
@ -1,69 +0,0 @@
|
||||
@file:OptIn(DelicateCoroutinesApi::class)
|
||||
package org.muellerssoftware.openproximitychat.common
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import org.bitlet.weupnp.GatewayDevice
|
||||
import org.bitlet.weupnp.GatewayDiscover
|
||||
|
||||
data class MappedPort(val port: Int, val protocol: String)
|
||||
|
||||
object UPnPManager {
|
||||
private var gateway: GatewayDevice? = null
|
||||
private val mappedPorts = mutableMapOf<Int, MappedPort>()
|
||||
private var discoveryJob: Job = Job()
|
||||
|
||||
init {
|
||||
runBlocking {
|
||||
discoveryJob = GlobalScope.launch {
|
||||
startGatewayDiscover()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun startGatewayDiscover() {
|
||||
val gatewayDiscoverer = GatewayDiscover()
|
||||
for (i in 0..9) {
|
||||
Logging.info("Searching for UPnP gateway... (Attempt ${i + 1})")
|
||||
gatewayDiscoverer.discover()
|
||||
gateway = GatewayDevice()
|
||||
if (gatewayDiscoverer.validGateway != null) {
|
||||
gateway = gatewayDiscoverer.validGateway
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (gateway == null) {
|
||||
Logging.error("No UPnP gateway found!")
|
||||
}
|
||||
else {
|
||||
Logging.info("UPnP gateway found: ${gateway!!.friendlyName}")
|
||||
val ports = mappedPorts.toMutableMap()
|
||||
mappedPorts.clear()
|
||||
|
||||
ports.map {
|
||||
mapPort(it.key, it.value.port, it.value.protocol)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun mapPort(port: Int, protocol: String = "TCP") {
|
||||
mapPort(port, port, protocol)
|
||||
}
|
||||
|
||||
fun mapPort(internalPort: Int, externalPort: Int, protocol: String = "TCP") {
|
||||
if (gateway == null) {
|
||||
mappedPorts[internalPort] = MappedPort(externalPort, protocol)
|
||||
}
|
||||
|
||||
val succeeded = gateway?.addPortMapping(externalPort, internalPort, gateway!!.localAddress.hostAddress, "TCP", "OpenProximityChat mapped port")
|
||||
if (succeeded == true) {
|
||||
mappedPorts[internalPort] = MappedPort(externalPort, protocol)
|
||||
}
|
||||
}
|
||||
|
||||
fun unMapAll() {
|
||||
mappedPorts.map {
|
||||
gateway?.deletePortMapping(it.value.port, it.value.protocol)
|
||||
}
|
||||
}
|
||||
}
|
@ -25,7 +25,6 @@ object VoiceServer {
|
||||
var handshook = mutableMapOf<UUID, InetAddress>()
|
||||
|
||||
init {
|
||||
UPnPManager.mapPort(localAddress.port)
|
||||
|
||||
runBlocking {
|
||||
startServer()
|
||||
@ -75,7 +74,6 @@ object VoiceServer {
|
||||
|
||||
fun exit() {
|
||||
Logging.info("VoiceServer exiting...")
|
||||
UPnPManager.unMapAll()
|
||||
if (recieverJob.isActive) {
|
||||
runBlocking {
|
||||
recieverJob.cancelAndJoin()
|
||||
|
@ -1,10 +1,16 @@
|
||||
@file:UseSerializers(UUIDAsStringSerializer::class, InstantAsStringSerializer::class)
|
||||
@file:UseSerializers(
|
||||
org.muellerssoftware.openproximitychat.common.UUIDSerializer::class,
|
||||
InstantAsStringSerializer::class
|
||||
)
|
||||
|
||||
package org.muellerssoftware.openproximitychat.tracker
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.UseSerializers
|
||||
import org.h2.security.SHA3
|
||||
import org.jetbrains.exposed.dao.UUIDEntity
|
||||
import org.jetbrains.exposed.dao.UUIDEntityClass
|
||||
import org.jetbrains.exposed.dao.id.EntityID
|
||||
import org.jetbrains.exposed.dao.id.UUIDTable
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
@ -26,6 +32,46 @@ class Client(
|
||||
var sampledClients: List<UUID>
|
||||
)
|
||||
|
||||
class ClientEntity(id: EntityID<UUID>): UUIDEntity(id) {
|
||||
companion object : UUIDEntityClass<ClientEntity>(Clients)
|
||||
|
||||
var uuid by Clients.id
|
||||
var name by Clients.name
|
||||
var timeout by Clients.timeout
|
||||
var ip by Clients.ip
|
||||
var port by Clients.port
|
||||
var passwordHash by Clients.passwordHash
|
||||
var sampledClient1 by Clients.sampledClient1
|
||||
var sampledClient2 by Clients.sampledClient2
|
||||
var sampledClient3 by Clients.sampledClient3
|
||||
var sampledClient4 by Clients.sampledClient4
|
||||
var sampledClient5 by Clients.sampledClient5
|
||||
var sampledClient6 by Clients.sampledClient6
|
||||
var sampledClient7 by Clients.sampledClient7
|
||||
var sampledClient8 by Clients.sampledClient8
|
||||
|
||||
fun toClient(): Client {
|
||||
return Client(
|
||||
uuid.value,
|
||||
name,
|
||||
timeout,
|
||||
ip,
|
||||
port,
|
||||
passwordHash,
|
||||
listOfNotNull(
|
||||
sampledClient1,
|
||||
sampledClient2,
|
||||
sampledClient3,
|
||||
sampledClient4,
|
||||
sampledClient5,
|
||||
sampledClient6,
|
||||
sampledClient7,
|
||||
sampledClient8
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object Clients: UUIDTable() {
|
||||
var name = varchar("name", 16)
|
||||
var ip = varchar("ip", 21)
|
||||
@ -92,9 +138,9 @@ object DatabaseHandler {
|
||||
return pw
|
||||
}
|
||||
|
||||
private fun checkTimeout(client: Client): Client? {
|
||||
private fun checkTimeout(client: ClientEntity): ClientEntity? {
|
||||
if (client.timeout < Instant.now()) {
|
||||
removeClient(client.uuid)
|
||||
client.delete()
|
||||
return null
|
||||
}
|
||||
|
||||
@ -102,29 +148,15 @@ object DatabaseHandler {
|
||||
}
|
||||
|
||||
fun getClient(name: String): Client? {
|
||||
val client = transaction {
|
||||
Clients.select { Clients.name eq name }.map {
|
||||
Client(it[Clients.id].value, it[Clients.name], it[Clients.timeout], it[Clients.ip], it[Clients.port], it[Clients.passwordHash], listOf(
|
||||
it[Clients.sampledClient1],it[Clients.sampledClient2],it[Clients.sampledClient3],it[Clients.sampledClient4],
|
||||
it[Clients.sampledClient5],it[Clients.sampledClient6],it[Clients.sampledClient7],it[Clients.sampledClient8]
|
||||
))
|
||||
}.firstOrNull()
|
||||
} ?: return null
|
||||
|
||||
return checkTimeout(client)
|
||||
return transaction {
|
||||
ClientEntity.find { Clients.name eq name }.firstOrNull()
|
||||
}?.let { checkTimeout(it) }?.toClient()
|
||||
}
|
||||
|
||||
fun getClient(id: UUID): Client? {
|
||||
val client = transaction {
|
||||
Clients.select { Clients.id eq id }.map {
|
||||
Client(it[Clients.id].value, it[Clients.name], it[Clients.timeout], it[Clients.ip], it[Clients.port], it[Clients.passwordHash], listOf(
|
||||
it[Clients.sampledClient1],it[Clients.sampledClient2],it[Clients.sampledClient3],it[Clients.sampledClient4],
|
||||
it[Clients.sampledClient5],it[Clients.sampledClient6],it[Clients.sampledClient7],it[Clients.sampledClient8]
|
||||
))
|
||||
}.firstOrNull()
|
||||
} ?: return null
|
||||
|
||||
return checkTimeout(client)
|
||||
return transaction {
|
||||
ClientEntity.find { Clients.id eq id }.firstOrNull()
|
||||
}?.let { checkTimeout(it) }?.toClient()
|
||||
}
|
||||
|
||||
fun doHeartbeat(id: UUID): String {
|
||||
@ -148,9 +180,11 @@ object DatabaseHandler {
|
||||
}
|
||||
|
||||
fun checkCredentials(id: UUID, passwordHash: String): Boolean {
|
||||
val client = getClient(id) ?: return false
|
||||
val client = transaction {
|
||||
ClientEntity.find { Clients.id eq id }.firstOrNull()
|
||||
}?.let { checkTimeout(it) }
|
||||
|
||||
return if (checkTimeout(client) != null) {
|
||||
return if (client != null) {
|
||||
client.passwordHash == passwordHash
|
||||
} else {
|
||||
false
|
||||
|
@ -6,6 +6,7 @@ import io.ktor.server.application.*
|
||||
import io.ktor.utils.io.core.*
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.selects.select
|
||||
import org.jetbrains.exposed.sql.and
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import org.jetbrains.exposed.sql.update
|
||||
import org.muellerssoftware.openproximitychat.common.Logging
|
||||
@ -35,7 +36,7 @@ fun Application.puncher() {
|
||||
}
|
||||
|
||||
transaction {
|
||||
Clients.update({ Clients.id eq uuid }) {
|
||||
Clients.update({ Clients.id eq uuid and (Clients.port eq null) }) {
|
||||
it[ip] = address.toJavaAddress().toString()
|
||||
}.run {
|
||||
if (this == 0) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
@file:UseSerializers(UUIDAsStringSerializer::class)
|
||||
@file:UseSerializers(org.muellerssoftware.openproximitychat.common.UUIDSerializer::class)
|
||||
|
||||
package org.muellerssoftware.openproximitychat.tracker
|
||||
|
||||
|
@ -1,27 +0,0 @@
|
||||
package org.muellerssoftware.openproximitychat.tracker
|
||||
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializer
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import java.util.*
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
@Serializer(forClass = UUID::class)
|
||||
object UUIDAsStringSerializer: KSerializer<UUID> {
|
||||
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("UUIDAsStringSerializer", PrimitiveKind.STRING)
|
||||
|
||||
override fun serialize(encoder: Encoder, value: UUID) {
|
||||
val string = value.toString()
|
||||
encoder.encodeString(string)
|
||||
}
|
||||
|
||||
override fun deserialize(decoder: Decoder): UUID {
|
||||
val string = decoder.decodeString()
|
||||
return UUID.fromString(string)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user