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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,20 @@ import kotlin.jvm.optionals.getOrNull
data class Operator(
val name: String,
val url: String,
val anonymity: String?,
val popularity: String?,
val anonymity: OperatorRating?,
val popularity: OperatorRating?,
val services: Set<OperatorService>?,
val protocols: Set<String>,
val protocols: Set<OperatorProtocol>,
val policies: OperatorPolicies,
val additionalOperators: Set<String>?,
) {
constructor(
name: String,
url: String,
anonymity: Optional<String>,
popularity: Optional<String>,
anonymity: Optional<OperatorRating>,
popularity: Optional<OperatorRating>,
services: Optional<Set<OperatorService>>,
protocols: Set<String>,
protocols: Set<OperatorProtocol>,
policies: OperatorPolicies,
additionalOperators: Optional<Set<String>>,
) : this(
Expand All @@ -64,10 +64,10 @@ data class Operator(
instance.group(
Codec.STRING.fieldOf("name").forGetter(Operator::name),
Codec.STRING.fieldOf("url").forGetter(Operator::url),
Codec.STRING.optionalFieldOf("anonymity").forNullableGetter(Operator::anonymity),
Codec.STRING.optionalFieldOf("popularity").forNullableGetter(Operator::popularity),
OperatorRating.CODEC.optionalFieldOf("anonymity").forNullableGetter(Operator::anonymity),
OperatorRating.CODEC.optionalFieldOf("popularity").forNullableGetter(Operator::popularity),
OperatorService.CODEC.setOf().optionalFieldOf("services").forNullableGetter(Operator::services),
Codec.STRING.setOf().fieldOf("protocols").forGetter(Operator::protocols),
OperatorProtocol.CODEC.setOf().fieldOf("protocols").forGetter(Operator::protocols),
OperatorPolicies.CODEC.optionalFieldOf("policies", OperatorPolicies.UNKNOWN).forGetter(Operator::policies),
Codec.STRING.setOf().optionalFieldOf("additional_operators").forNullableGetter(Operator::additionalOperators),
).apply(instance, ::Operator)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2026 ElectroPlay
* SPDX-License-Identifier: MPL-2.0
*/

package ru.epserv.proxycheck.v3.api.model.response

import com.mojang.serialization.Codec
import org.jetbrains.annotations.ApiStatus

/**
* A protocol an operator offers their services through.
*
* Operator protocols are not standardized. New ones may be introduced (and existing ones may be
* removed) within the same API version, which is the reason why [OperatorProtocol] is not an enum
* class.
*
* @property id operator protocol identifier
* @since 1.0.0
* @author metabrix
* @see [OperatorProtocol.fromId]
*/
@ConsistentCopyVisibility
@ApiStatus.AvailableSince("1.0.0")
data class OperatorProtocol private constructor(val id: String) {
companion object {
private val cache = mutableMapOf<String, OperatorProtocol>()

fun fromId(id: String): OperatorProtocol {
return synchronized(cache) { cache.getOrPut(id) { OperatorProtocol(id) } }
}

@ApiStatus.Internal
val CODEC: Codec<OperatorProtocol> = Codec.STRING.xmap(::fromId, OperatorProtocol::id)

val OPENVPN = fromId("OpenVPN")

val WIREGUARD = fromId("Wireguard")

val ONION_ROUTING = fromId("Onion Routing")

val IPSEC = fromId("IPSec")

val SSH2 = fromId("SSH2")

val PPTP = fromId("PPTP")

val L2TP = fromId("L2TP")

val SOCKS5 = fromId("SOCKS5")

val IKEV2 = fromId("IKEv2")

val HTTP = fromId("HTTP")

val HTTPS = fromId("HTTPS")

val SOCKS4 = fromId("SOCKS4")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2026 ElectroPlay
* SPDX-License-Identifier: MPL-2.0
*/

package ru.epserv.proxycheck.v3.api.model.response

import com.mojang.serialization.Codec
import com.mojang.serialization.DataResult
import org.jetbrains.annotations.ApiStatus

/**
* Value for [Operator.anonymity] and [Operator.popularity] fields.
*
* @property id string representation of the rating
* @since 1.0.0
* @author metabrix
*/
@ApiStatus.AvailableSince("1.0.0")
enum class OperatorRating(val id: String) {
LOW("low"),
MEDIUM("medium"),
HIGH("high"),
;

companion object {
private val values = entries.associateBy { it.id }

@ApiStatus.Internal
val CODEC: Codec<OperatorRating> = Codec.STRING.comapFlatMap(
{ value -> values[value]?.let { DataResult.success(it) } ?: DataResult.error { "Unknown operator rating: $value" } },
{ it.id },
)
}
}