Utilisation et contraintes

ServiceLoader découvre l’extension via META-INF/services/dev.nebulastorage.api.NebulaExtension. Enregistrez adaptateurs et sources de recettes sans accéder à un monde. Dans serverStarted, liez les requêtes au joueur authentifié ; ne les conservez pas après serverStopped.

  1. DécouvrirLire capacités et recettes
  2. PlanifierRéserver les ressources exactes
  3. ExécuterTransférer au vrai propriétaire
  4. ReprendreLire le reçu sauvegardé
La découverte ne modifie rien. Seule l’exécution transfère la propriété ; la reprise ne recrée jamais une entrée consommée.

NebulaExtension

NebulaExtension
package dev.nebulastorage.api

import dev.nebulastorage.api.production.ProductionCapabilityId
import dev.nebulastorage.api.production.ProductionMachine
import dev.nebulastorage.api.production.ProductionRecipeOffer
import dev.nebulastorage.api.resource.ResourceKey
import dev.nebulastorage.api.resource.ResourceTypeId
import java.util.UUID

/** Discovered once through META-INF/services. Registration must not access a running world. */
interface NebulaExtension {
    fun register(registrar: NebulaRegistrar)
    fun serverStarted(queries: NebulaNetworkQueries) {}
    fun serverStopped() {}
}

interface NebulaRegistrar {
    fun hardwareAdapter(id: String, adapter: dev.nebulastorage.api.hardware.NebulaHardwareAdapter)
    fun resourceType(type: NebulaResourceType)
    fun capability(id: ProductionCapabilityId)
    fun capability(id: ProductionCapabilityId, requirements: dev.nebulastorage.api.production.ProductionRequirements) {
        throw UnsupportedOperationException("This Nebula runtime does not support production requirements")
    }
    fun machineAdapter(id: String, adapter: NebulaMachineAdapter)
    fun recipeSource(id: String, source: NebulaRecipeSource)
    fun observer(observer: NebulaObserver)
}

interface NebulaResourceType {
    val id: ResourceTypeId
    val unit: String
    /** Capacity allocated in newly created Storage Cores; zero means this type needs another storage provider. */
    val defaultStorageCapacity: Long get() = 0
    /** Validates canonical identity without mutating state; an unsupported key must return false. */
    fun accepts(key: ResourceKey): Boolean
}

fun interface NebulaMachineAdapter {
    /** Returns null when the exact installed item is unsupported. The returned machine must retain [instance]. */
    fun adapt(instance: UUID, item: ResourceKey): ProductionMachine?
}

interface NebulaRecipeSource {
    /** Increment after recipes or their constraints change. Queried on the server thread. */
    val revision: Long get() = 0
    fun discover(capabilities: Set<ProductionCapabilityId>): List<ProductionRecipeOffer>
}

fun interface NebulaObserver {
    /** Null observes public historical networks only. An authenticated actor is rechecked for each event. */
    fun actor(): UUID? = null
    /** Called on the server thread after mutation. Queries are read-only and must not be retained across server lifetimes. */
    fun onEvent(event: NebulaEvent, queries: NebulaNetworkQueries)
}

sealed interface NebulaEvent {
    data class NetworkChanged(val network: UUID, val online: Boolean) : NebulaEvent
    data class ResourcesChanged(val network: UUID) : NebulaEvent
    data class MachinesChanged(val network: UUID, val count: Int) : NebulaEvent
    data class JobChanged(val network: UUID, val job: PublicJob) : NebulaEvent
}

/** Creation time is Unix milliseconds, or zero when migrated from a format without a timestamp. Produced amount excludes initial stock. */
data class PublicJob @JvmOverloads constructor(val id: UUID, val state: String, val completedSteps: Int, val totalSteps: Int,
                                              val createdAtMillis: Long = 0, val producedAmount: Long = 0)
data class PublicNetwork(val id: UUID, val online: Boolean, val machineCount: Int, val energyStored: Long, val energyCapacity: Long)

interface NebulaNetworkQueries {
    /** Resolves every query against current permissions. The server extension must supply the authenticated actor, never a client-claimed UUID. */
    fun forPlayer(actor: UUID): NebulaNetworkQueries { throw UnsupportedOperationException("This runtime does not expose actor-scoped queries") }
    fun configuration(): NebulaConfiguration { throw UnsupportedOperationException("This Nebula runtime does not expose balancing configuration") }
    fun at(dimension: String, x: Int, y: Int, z: Int): PublicNetwork?
    fun resources(network: UUID): Map<ResourceKey, Long>
    fun jobs(network: UUID): List<PublicJob>
}
Source

src/main/kotlin/dev/nebulastorage/api/NebulaExtension.kt; editorial/fr.json

43b4d12d69e6033c24fa8c39dac383ef2429b446