Skip to content

Commit

Permalink
feat: create a property filter store
Browse files Browse the repository at this point in the history
  • Loading branch information
Z-Kris committed Aug 1, 2024
1 parent 796905a commit 7040319
Show file tree
Hide file tree
Showing 9 changed files with 640 additions and 0 deletions.
6 changes: 6 additions & 0 deletions proxy/src/main/kotlin/net/rsprox/proxy/ProxyService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import net.rsprox.proxy.config.BINARY_PATH
import net.rsprox.proxy.config.CACHES_DIRECTORY
import net.rsprox.proxy.config.CLIENTS_DIRECTORY
import net.rsprox.proxy.config.CONFIGURATION_PATH
import net.rsprox.proxy.config.FILTERS_DIRECTORY
import net.rsprox.proxy.config.JavConfig
import net.rsprox.proxy.config.ProxyProperties
import net.rsprox.proxy.config.ProxyProperty.Companion.BINARY_WRITE_INTERVAL_SECONDS
Expand All @@ -26,6 +27,7 @@ import net.rsprox.proxy.config.TEMP_CLIENTS_DIRECTORY
import net.rsprox.proxy.config.registerConnection
import net.rsprox.proxy.connection.ProxyConnectionContainer
import net.rsprox.proxy.downloader.NativeClientDownloader
import net.rsprox.proxy.filters.DefaultPropertyFilterSetStore
import net.rsprox.proxy.futures.asCompletableFuture
import net.rsprox.proxy.huffman.HuffmanProvider
import net.rsprox.proxy.plugin.PluginLoader
Expand All @@ -40,6 +42,7 @@ import net.rsprox.proxy.worlds.DynamicWorldListProvider
import net.rsprox.proxy.worlds.World
import net.rsprox.proxy.worlds.WorldListProvider
import net.rsprox.shared.SessionMonitor
import net.rsprox.shared.filters.PropertyFilterSetStore
import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters
import java.io.File
import java.io.IOException
Expand All @@ -65,6 +68,7 @@ public class ProxyService(
private lateinit var worldListProvider: WorldListProvider
private lateinit var operatingSystem: OperatingSystem
private lateinit var rsa: RSAPrivateCrtKeyParameters
private lateinit var filterSetStore: PropertyFilterSetStore
private var properties: ProxyProperties by Delegates.notNull()
private var availablePort: Int = -1
private val processes: MutableMap<Int, Process> = mutableMapOf()
Expand All @@ -77,9 +81,11 @@ public class ProxyService(
createConfigurationDirectories(CLIENTS_DIRECTORY)
createConfigurationDirectories(TEMP_CLIENTS_DIRECTORY)
createConfigurationDirectories(CACHES_DIRECTORY)
createConfigurationDirectories(FILTERS_DIRECTORY)
loadProperties()
HuffmanProvider.load()
this.rsa = loadRsa()
this.filterSetStore = DefaultPropertyFilterSetStore.load(FILTERS_DIRECTORY)
this.availablePort = properties.getProperty(PROXY_PORT_MIN)
this.bootstrapFactory = BootstrapFactory(allocator, properties)
val javConfig = loadJavConfig()
Expand Down
1 change: 1 addition & 0 deletions proxy/src/main/kotlin/net/rsprox/proxy/config/RSProx.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ internal val PLUGINS_DIRECTORY: Path = CONFIGURATION_PATH.resolve("plugins")
internal val TRANSCRIBERS_DIRECTORY: Path = CONFIGURATION_PATH.resolve("transcribers")
internal val TEMP_CLIENTS_DIRECTORY: Path = CLIENTS_DIRECTORY.resolve("temp")
internal val CACHES_DIRECTORY: Path = CONFIGURATION_PATH.resolve("caches")
internal val FILTERS_DIRECTORY: Path = CONFIGURATION_PATH.resolve("filters")
private val connections: MutableList<ConnectionInfo> = mutableListOf()

internal fun registerConnection(info: ConnectionInfo) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package net.rsprox.proxy.filters

import net.rsprox.cache.util.atomicWrite
import net.rsprox.shared.StreamDirection
import net.rsprox.shared.filters.PropertyFilter
import net.rsprox.shared.filters.PropertyFilterSet
import net.rsprox.shared.filters.ProtCategory
import java.nio.file.Path
import kotlin.io.path.readText

public class DefaultPropertyFilterSet(
private val path: Path,
private val creationTime: Long,
private var version: Int,
private var name: String,
private var active: Boolean,
private val filters: MutableMap<String, Boolean>,
) : PropertyFilterSet {
override fun getCreationTime(): Long {
return creationTime
}

override fun getName(): String {
return name
}

override fun setName(name: String) {
this.name = name
}

override fun get(filter: PropertyFilter): Boolean {
return filters[filter.name] ?: filter.enabled
}

override fun set(
filter: PropertyFilter,
enabled: Boolean,
) {
filters[filter.name] = enabled
save()
}

override fun set(
category: ProtCategory,
enabled: Boolean,
) {
for (filter in PropertyFilter.entries) {
if (filter.category == category) {
filters[filter.name] = enabled
}
}
save()
}

override fun set(
streamDirection: StreamDirection,
enabled: Boolean,
) {
for (filter in PropertyFilter.entries) {
if (filter.direction == streamDirection) {
filters[filter.name] = enabled
}
}
save()
}

override fun setAll(enabled: Boolean) {
for (filter in PropertyFilter.entries) {
filters[filter.name] = enabled
}
save()
}

override fun setDefaults() {
for (filter in PropertyFilter.entries) {
filters[filter.name] = filter.enabled
}
save()
}

public fun isActive(): Boolean {
return this.active
}

public fun setActive(active: Boolean) {
if (this.active == active) return
this.active = active
save()
}

private fun save() {
path.atomicWrite(buildString(this))
}

public companion object {
private const val DEFAULT_VERSION: Int = 0

public fun create(
rootPath: Path,
name: String,
): DefaultPropertyFilterSet {
val time = System.currentTimeMillis()
return DefaultPropertyFilterSet(
rootPath.resolve("filters-$time.txt"),
time,
DEFAULT_VERSION,
name,
true,
mutableMapOf(),
).apply {
setDefaults()
}
}

private fun buildString(propertyFilterSet: DefaultPropertyFilterSet): String {
val builder = StringBuilder()
builder.append("version=").append(propertyFilterSet.version).appendLine()
builder.append("creationtime=").append(propertyFilterSet.creationTime).appendLine()
builder.append("name=").append(propertyFilterSet.name).appendLine()
for ((k, v) in propertyFilterSet.filters) {
builder
.append(k)
.append('=')
.append(v)
.appendLine()
}
return builder.toString()
}

public fun load(path: Path): DefaultPropertyFilterSet {
val text = path.readText()
var version: Int = -1
var name: String? = null
var creationTime: Long = 0
var active: Boolean = false
val properties: MutableMap<String, Boolean> = mutableMapOf()
for (line in text.lineSequence()) {
if (line.startsWith("version=")) {
version = line.substringAfter("version=").toInt()
continue
}
if (line.startsWith("creationtime=")) {
creationTime = line.substringAfter("creationtime=").toLong()
continue
}
if (line.startsWith("name=")) {
name = line.substringAfter("name=")
continue
}
if (line.startsWith("active=")) {
active = line.substringAfter("active=").toBoolean()
continue
}
val signIndex = line.indexOf('=')
if (signIndex == -1) continue
val split = line.split('=')
if (split.size != 2) continue
val (filterName, filterValue) = split
if (filterName.isBlank()) continue
val booleanValue = filterValue.toBooleanStrictOrNull() ?: continue
properties[filterName] = booleanValue
}
check(version != -1) {
"Version not assigned"
}
check(name != null) {
"Name not assigned"
}
return DefaultPropertyFilterSet(
path,
creationTime,
version,
name,
active,
properties,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package net.rsprox.proxy.filters

import net.rsprox.shared.filters.PropertyFilterSet
import net.rsprox.shared.filters.PropertyFilterSetStore
import java.nio.file.Path

public class DefaultPropertyFilterSetStore(
private val rootPath: Path,
private val filterSets: MutableList<PropertyFilterSet> = mutableListOf(),
) : PropertyFilterSetStore {
override fun create(index: Int): PropertyFilterSet {
if (index == 0) {
throw IllegalArgumentException("Element cannot be created at index 0.")
}
for (filter in filterSets) {
if (filter is DefaultPropertyFilterSet) {
filter.setActive(false)
}
}
val filter = DefaultPropertyFilterSet.create(rootPath, "Unnamed")
filterSets += filter
return filter
}

override fun delete(index: Int): PropertyFilterSet? {
if (index == 0) throw IllegalArgumentException("Element at index 0 cannot be deleted.")
val element = filterSets.getOrNull(index) ?: return null
filterSets.removeAt(index)
return element
}

override fun get(index: Int): PropertyFilterSet? {
return filterSets.getOrNull(index)
}

override fun getActive(): PropertyFilterSet {
val activeFilter =
filterSets
.filterIsInstance<DefaultPropertyFilterSet>()
.find { it.isActive() }
return activeFilter ?: filterSets.first()
}

override fun setActive(index: Int) {
for (filter in filterSets) {
if (filter is DefaultPropertyFilterSet) {
filter.setActive(false)
}
}
val filterSet = filterSets.getOrNull(index) ?: return
if (filterSet is DefaultPropertyFilterSet) {
filterSet.setActive(true)
}
}

public companion object {
public fun load(path: Path): PropertyFilterSetStore {
val list: MutableList<PropertyFilterSet> = mutableListOf(UnmodifiablePropertyFilterSet())
val results = path.toFile().walkTopDown()
for (file in results) {
if (!file.isFile) continue
val set =
try {
DefaultPropertyFilterSet.load(file.toPath())
} catch (e: Exception) {
continue
}
list += set
}
return DefaultPropertyFilterSetStore(path, list)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package net.rsprox.proxy.filters

import net.rsprox.shared.StreamDirection
import net.rsprox.shared.filters.PropertyFilter
import net.rsprox.shared.filters.PropertyFilterSet
import net.rsprox.shared.filters.ProtCategory

public class UnmodifiablePropertyFilterSet : PropertyFilterSet {
override fun getCreationTime(): Long {
return Long.MIN_VALUE
}

override fun getName(): String {
return "Default"
}

override fun setName(name: String) {
}

override fun get(filter: PropertyFilter): Boolean {
return filter.enabled
}

override fun set(
filter: PropertyFilter,
enabled: Boolean,
) {
}

override fun set(
category: ProtCategory,
enabled: Boolean,
) {
}

override fun set(
streamDirection: StreamDirection,
enabled: Boolean,
) {
}

override fun setAll(enabled: Boolean) {
}

override fun setDefaults() {
}
}
Loading

0 comments on commit 7040319

Please sign in to comment.