Skip to content

Commit

Permalink
Improve settings and properties (#577)
Browse files Browse the repository at this point in the history
* Fix xp rate modifier

* Fix music unlock command

* Fix tests for experience rate

* Add Settings closes #576

* Add settings reload event

* Convert properties to load via Settings

* Fix incorrect inject() usages

* Convert properties to Settings

* Fix left-over state effecting other tests

* Convert World variables to Settings

* Convert missed property loading

* Refactor game.properties

* Add shooting star respawn time settings and command

* Add global event message

* Add toggle for esse pouch degrading

* Add infinite run energy toggle

* Add bots random walk setting

* Add networked bots as dev setting

* Add lumbridge safe zone setting

* More organising and add a few startup configs

* Make home tile and exp rate settings dynamic

* Replace Main.name with server.name setting
  • Loading branch information
GregHib authored Jan 10, 2025
1 parent c4c2bb6 commit 30c01ae
Show file tree
Hide file tree
Showing 151 changed files with 1,009 additions and 634 deletions.
2 changes: 1 addition & 1 deletion cache/src/main/kotlin/world/gregs/voidps/cache/Cache.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ interface Cache {

companion object {
fun load(properties: Properties): Cache {
val live = properties.getProperty("live").toBoolean()
val live = properties.getProperty("server.live").toBoolean()
val loader = if (live) MemoryCache else FileCache
return loader.load(properties)
}
Expand Down
6 changes: 3 additions & 3 deletions cache/src/main/kotlin/world/gregs/voidps/cache/CacheLoader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import java.util.*
interface CacheLoader {

fun load(properties: Properties, xteas: Map<Int, IntArray>? = null): Cache {
val fileModulus = BigInteger(properties.getProperty("fileModulus"), 16)
val filePrivate = BigInteger(properties.getProperty("filePrivate"), 16)
val cachePath = properties.getProperty("cachePath")
val fileModulus = BigInteger(properties.getProperty("security.file.modulus"), 16)
val filePrivate = BigInteger(properties.getProperty("security.file.private"), 16)
val cachePath = properties.getProperty("storage.cache.path")
val threadUsage = properties.getProperty("threadUsage", "1.0").toDouble()
return load(cachePath, filePrivate, fileModulus, threadUsage = threadUsage)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ class VersionTableBuilderTest {

val properties = Properties()
properties.load(FileInputStream("../game/src/main/resources/private.properties"))
val exponent = BigInteger(properties.getProperty("gamePrivate"), 16)
val modulus = BigInteger(properties.getProperty("gameModulus"), 16)
val exponent = BigInteger(properties.getProperty("security.game.private"), 16)
val modulus = BigInteger(properties.getProperty("security.game.modulus"), 16)
val table = VersionTableBuilder(exponent, modulus, indexCount)
for (i in 0 until indexCount) {
val index = library.index(i)
Expand Down
8 changes: 4 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ services:
- ./data/saves/:/app/data/saves
environment:
storage: database
database_username: postgres
database_password: password
database_driver: org.postgresql.Driver
database_jdbc_url: jdbc:postgresql://db:5432/game?reWriteBatchedInserts=true
storage.database.username: postgres
storage.database.password: password
storage.database.driver: org.postgresql.Driver
storage.database.jdbcUrl: jdbc:postgresql://db:5432/game?reWriteBatchedInserts=true
ports:
- "43594:43594"
depends_on:
Expand Down
52 changes: 22 additions & 30 deletions engine/src/main/kotlin/world/gregs/voidps/engine/EngineModules.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import org.rsmod.game.pathfinder.PathFinder
import org.rsmod.game.pathfinder.StepValidator
import world.gregs.voidps.engine.client.PlayerAccountLoader
import world.gregs.voidps.engine.client.update.batch.ZoneBatchUpdates
import world.gregs.voidps.engine.data.AccountManager
import world.gregs.voidps.engine.data.SafeStorage
import world.gregs.voidps.engine.data.SaveQueue
import world.gregs.voidps.engine.data.*
import world.gregs.voidps.engine.data.definition.*
import world.gregs.voidps.engine.data.json.FileStorage
import world.gregs.voidps.engine.data.sql.DatabaseStorage
Expand All @@ -35,48 +33,42 @@ val engineModule = module {
// Entities
single { NPCs(get(), get(), get(), get()) }
single { Players() }
single { GameObjects(get(), get(), get(), get(), getProperty<String>("loadUnusedObjects") == "true").apply { get<ZoneBatchUpdates>().register(this) } }
single { GameObjects(get(), get(), get(), get(), Settings["development.loadAllObjects", false]).apply { get<ZoneBatchUpdates>().register(this) } }
single { FloorItems(get(), get()).apply { get<ZoneBatchUpdates>().register(this) } }
single { FloorItemTracking(get(), get(), get()) }
single { Hunting(get(), get(), get(), get(), get(), get()) }
single {
SaveQueue(get(), SafeStorage(File(getProperty<String>("storageFailDirectory"))))
}
single {
val homeTile = Tile(
x = getIntProperty("homeX", 0),
y = getIntProperty("homeY", 0),
level = getIntProperty("homeLevel", 0)
)
AccountManager(get(), get(), get(), get(), get(), get(), homeTile, get(), get(), get(), get())
SaveQueue(get(), SafeStorage(File(Settings["storage.players.errors"])))
}
single { AccountManager(get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) }
// IO
single { Yaml(YamlReaderConfiguration(2, 8, VERY_FAST_LOAD_FACTOR)) }
single { if (getProperty("storage", "") == "database") {
DatabaseStorage.connect(
getProperty("database_username"),
getProperty("database_password"),
getProperty("database_driver"),
getProperty("database_jdbc_url"),
getProperty("database_pool", "2").toInt(),
)
val definitions: ItemDefinitions = get()
DatabaseStorage { definitions.get(it) }
} else {
val saves = File(getProperty<String>("savePath"))
if (!saves.exists()) {
saves.mkdir()
single {
if (Settings["storage.type", "files"] == "database") {
DatabaseStorage.connect(
Settings["storage.database.username"],
Settings["storage.database.password"],
Settings["storage.database.driver"],
Settings["storage.database.jdbcUrl"],
Settings["storage.database.poolSize", 2],
)
DatabaseStorage()
} else {
val saves = File(Settings["storage.players.path"])
if (!saves.exists()) {
saves.mkdir()
}
FileStorage(get(), saves)
}
FileStorage(get(), saves, get(), getProperty("experienceRate", "1.0").toDouble())
} }
}
single { PlayerAccountLoader(get(), get(), get(), get(), get(), Contexts.Game) }
// Map
single { ZoneBatchUpdates() }
single { DynamicZones(get(), get(), get()) }
single(createdAtStart = true) { AreaDefinitions().load() }
// Network
single {
ConnectionQueue(getIntProperty("connectionPerTickCap", 1))
ConnectionQueue(Settings["network.maxLoginsPerTick", 1])
}
single(createdAtStart = true) { GameObjectCollisionAdd(get()) }
single(createdAtStart = true) { GameObjectCollisionRemove(get()) }
Expand Down
10 changes: 0 additions & 10 deletions engine/src/main/kotlin/world/gregs/voidps/engine/Koin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,6 @@ inline fun <reified T : Any> get(
noinline parameters: ParametersDefinition? = null
): T = getKoin().get(qualifier, parameters)

fun getIntProperty(key: String): Int = getKoin().getProperty<String>(key)!!.toInt()

fun getProperty(key: String): String = getKoin().getProperty(key)!!

fun getPropertyOrNull(key: String): String? = getKoin().getProperty(key)

fun getFloatProperty(key: String): Float = getKoin().getProperty(key)!!

fun getIntProperty(key: String, defaultValue: Int): Int = getKoin().getProperty<String>(key)?.toIntOrNull() ?: defaultValue

inline fun <reified T : Any> inject(
qualifier: Qualifier? = null,
noinline parameters: ParametersDefinition? = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import kotlinx.coroutines.withContext
import world.gregs.voidps.engine.data.AccountManager
import world.gregs.voidps.engine.data.AccountStorage
import world.gregs.voidps.engine.data.SaveQueue
import world.gregs.voidps.engine.data.Settings
import world.gregs.voidps.engine.data.definition.AccountDefinitions
import world.gregs.voidps.engine.entity.World
import world.gregs.voidps.engine.entity.character.player.Player
Expand Down Expand Up @@ -51,7 +52,7 @@ class PlayerAccountLoader(
client.disconnect(Response.ACCOUNT_ONLINE)
return null
}
val player = storage.load(username)?.toPlayer() ?: accounts.create(username, passwordHash)
val player = storage.load(username)?.toPlayer(Settings["world.experienceRate", 1.0]) ?: accounts.create(username, passwordHash)
logger.info { "Player $username loaded and queued for login." }
connect(player, client, displayMode)
return player.instructions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import world.gregs.voidps.engine.entity.character.mode.move.AreaEntered
import world.gregs.voidps.engine.entity.character.mode.move.AreaExited
import world.gregs.voidps.engine.entity.character.move.previousTile
import world.gregs.voidps.engine.entity.character.player.*
import world.gregs.voidps.engine.entity.character.player.skill.exp.Experience
import world.gregs.voidps.engine.entity.character.player.skill.level.PlayerLevels
import world.gregs.voidps.engine.inv.equipment
import world.gregs.voidps.engine.inv.restrict.ValidItemRestriction
Expand All @@ -34,16 +35,17 @@ class AccountManager(
private val accountDefinitions: AccountDefinitions,
private val collisionStrategyProvider: CollisionStrategyProvider,
private val variableDefinitions: VariableDefinitions,
private val homeTile: Tile,
private val saveQueue: SaveQueue,
private val connectionQueue: ConnectionQueue,
private val players: Players,
private val areaDefinitions: AreaDefinitions
) {
private val validItems = ValidItemRestriction(itemDefinitions)
private val homeTile: Tile
get() = Tile(Settings["world.home.x", 0], Settings["world.home.y", 0], Settings["world.home.level", 0])

fun create(name: String, passwordHash: String): Player {
return Player(tile = homeTile, accountName = name, passwordHash = passwordHash).apply {
return Player(tile = homeTile, accountName = name, passwordHash = passwordHash, experience = Experience(rate = Settings["world.experienceRate", 1.0])).apply {
this["creation"] = System.currentTimeMillis()
this["new_player"] = true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ data class PlayerSave(
val ignores: List<String>
) {

fun toPlayer(): Player {
fun toPlayer(rate: Double): Player {
return Player(
accountName = name,
passwordHash = password,
tile = tile,
experience = Experience(experience, blocked.toMutableSet()),
experience = Experience(experience, blocked.toMutableSet(), rate = rate),
levels = Levels(levels),
body = BodyParts(male, looks, colours),
variables = variables.toMutableMap(),
Expand Down
60 changes: 60 additions & 0 deletions engine/src/main/kotlin/world/gregs/voidps/engine/data/Settings.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package world.gregs.voidps.engine.data

import com.github.michaelbull.logging.InlineLogger
import java.io.File
import java.io.InputStream
import java.util.*

/**
* Class to load and reload game settings from .property files
*/
open class Settings {

protected val properties = Properties()

fun load(stream: InputStream): Properties {
properties.load(stream)
return properties
}

fun load(map: Map<String, String>): Properties {
properties.putAll(map)
return properties
}

fun load(properties: Properties): Properties {
this.properties.putAll(properties)
return this.properties
}

fun getOrNull(name: String): String? = properties.getProperty(name)

operator fun get(name: String): String = properties.getProperty(name)

operator fun get(name: String, default: String): String = properties.getProperty(name, default)

operator fun get(name: String, default: Int): Int = getOrNull(name)?.toIntOrNull() ?: default

operator fun get(name: String, default: Double): Double = getOrNull(name)?.toDoubleOrNull() ?: default

operator fun get(name: String, default: Boolean): Boolean = getOrNull(name)?.toBooleanStrictOrNull() ?: default

fun clear() {
properties.clear()
}

companion object : Settings() {
private const val PROPERTY_FILE_NAME = "game.properties"
private val logger = InlineLogger()

fun load(fileName: String = PROPERTY_FILE_NAME): Properties {
val file = File("./$fileName")
return if (file.exists()) {
Settings.load(file.inputStream())
} else {
logger.debug { "Property file not found; defaulting to internal." }
Settings.load(Settings::class.java.getResourceAsStream("/$fileName")!!)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package world.gregs.voidps.engine.data

import world.gregs.voidps.engine.entity.character.player.Player
import world.gregs.voidps.engine.event.Event
import world.gregs.voidps.engine.event.EventDispatcher
import world.gregs.voidps.engine.event.Events

object SettingsReload : Event {

override val notification: Boolean = true

override val size = 1

override fun parameter(dispatcher: EventDispatcher, index: Int) = when (index) {
0 -> "settings_reload"
else -> null
}
}

fun settingsReload(handler: suspend SettingsReload.(Player) -> Unit) {
Events.handle("settings_reload", handler = handler)
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package world.gregs.voidps.engine.data.definition

import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
import world.gregs.voidps.engine.data.Settings
import world.gregs.voidps.engine.data.config.AmmoDefinition
import world.gregs.voidps.engine.data.yaml.decode
import world.gregs.voidps.engine.get
import world.gregs.voidps.engine.getProperty
import world.gregs.voidps.engine.timedLoad
import world.gregs.yaml.Yaml

Expand All @@ -18,7 +18,7 @@ class AmmoDefinitions : DefinitionsDecoder<AmmoDefinition> {
override lateinit var ids: Map<String, Int>

@Suppress("UNCHECKED_CAST")
fun load(yaml: Yaml = get(), path: String = getProperty("ammoDefinitionsPath")): AmmoDefinitions {
fun load(yaml: Yaml = get(), path: String = Settings["definitions.ammoGroups"]): AmmoDefinitions {
timedLoad("ammo definition") {
decode(yaml, path) { id, key, extras ->
val items = extras?.get("items") as? List<String>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package world.gregs.voidps.engine.data.definition

import world.gregs.voidps.cache.definition.data.AnimationDefinition
import world.gregs.voidps.engine.data.Settings
import world.gregs.voidps.engine.get
import world.gregs.voidps.engine.getProperty
import world.gregs.voidps.engine.timedLoad
import world.gregs.yaml.Yaml

Expand All @@ -14,7 +14,7 @@ class AnimationDefinitions(

override fun empty() = AnimationDefinition.EMPTY

fun load(yaml: Yaml = get(), path: String = getProperty("animationDefinitionsPath")): AnimationDefinitions {
fun load(yaml: Yaml = get(), path: String = Settings["definitions.animations"]): AnimationDefinitions {
timedLoad("animation extra") {
decode(yaml, path)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package world.gregs.voidps.engine.data.definition
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
import world.gregs.voidps.engine.data.Settings
import world.gregs.voidps.engine.get
import world.gregs.voidps.engine.getProperty
import world.gregs.voidps.engine.timedLoad
import world.gregs.voidps.type.Area
import world.gregs.voidps.type.Zone
Expand Down Expand Up @@ -34,7 +34,7 @@ class AreaDefinitions(
}

@Suppress("UNCHECKED_CAST")
fun load(yaml: Yaml = get(), path: String = getProperty("areaPath")): AreaDefinitions {
fun load(yaml: Yaml = get(), path: String = Settings["map.areas"]): AreaDefinitions {
timedLoad("map area") {
val config = object : YamlReaderConfiguration(2, 2) {
override fun set(map: MutableMap<String, Any>, key: String, value: Any, indent: Int, parentMap: String?) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package world.gregs.voidps.engine.data.definition

import world.gregs.voidps.engine.data.Settings
import world.gregs.voidps.engine.data.config.CategoryDefinition
import world.gregs.voidps.engine.data.yaml.decode
import world.gregs.voidps.engine.get
import world.gregs.voidps.engine.getProperty
import world.gregs.voidps.engine.timedLoad
import world.gregs.yaml.Yaml

Expand All @@ -15,7 +15,7 @@ class CategoryDefinitions : DefinitionsDecoder<CategoryDefinition> {
override lateinit var definitions: Array<CategoryDefinition>
override lateinit var ids: Map<String, Int>

fun load(yaml: Yaml = get(), path: String = getProperty("categoryDefinitionsPath")): CategoryDefinitions {
fun load(yaml: Yaml = get(), path: String = Settings["definitions.categories"]): CategoryDefinitions {
timedLoad("category definition") {
decode(yaml, path) { id, key, _ ->
CategoryDefinition(id = id, stringId = key)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package world.gregs.voidps.engine.data.definition

import world.gregs.voidps.cache.definition.data.ClientScriptDefinition
import world.gregs.voidps.engine.data.Settings
import world.gregs.voidps.engine.data.yaml.decode
import world.gregs.voidps.engine.get
import world.gregs.voidps.engine.getProperty
import world.gregs.voidps.engine.timedLoad
import world.gregs.yaml.Yaml

Expand All @@ -12,7 +12,7 @@ class ClientScriptDefinitions : DefinitionsDecoder<ClientScriptDefinition> {
override lateinit var definitions: Array<ClientScriptDefinition>
override lateinit var ids: Map<String, Int>

fun load(yaml: Yaml = get(), path: String = getProperty("clientScriptDefinitionsPath")): ClientScriptDefinitions {
fun load(yaml: Yaml = get(), path: String = Settings["definitions.clientScripts"]): ClientScriptDefinitions {
timedLoad("client script definition") {
decode(yaml, path) { id, key, _ ->
ClientScriptDefinition(id = id, stringId = key)
Expand Down
Loading

0 comments on commit 30c01ae

Please sign in to comment.