Skip to content

Commit

Permalink
Initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Polyana committed Nov 27, 2023
1 parent 09cfd83 commit 69db983
Show file tree
Hide file tree
Showing 105 changed files with 2,504 additions and 133 deletions.
4 changes: 0 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ bin/

*.DS_Store

# fabric

run/

# java

hs_err_*.log
Expand Down
35 changes: 35 additions & 0 deletions api/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
plugins {
id("maven-publish")
kotlin("jvm")
kotlin("plugin.serialization")
}

kotlin {
explicitApi()
}

val kotlinVersion: String by rootProject
val kotlinCoroutinesVersion: String by rootProject
val kotlinSerializationVersion: String by rootProject
val atomicFuVersion: String by rootProject
val kotlinDatetimeVersion: String by rootProject

dependencies {
implementation("net.kyori:adventure-api:4.14.0")
implementation("net.kyori:adventure-text-minimessage:4.14.0")
api("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
api("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinCoroutinesVersion")
api("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:$kotlinCoroutinesVersion")
api("org.jetbrains.kotlinx:kotlinx-serialization-core:$kotlinSerializationVersion")
api("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinSerializationVersion")
api("org.jetbrains.kotlinx:kotlinx-serialization-cbor:$kotlinSerializationVersion")
api("org.jetbrains.kotlinx:atomicfu:$atomicFuVersion")
api("org.jetbrains.kotlinx:kotlinx-datetime:$kotlinDatetimeVersion")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
testImplementation("io.mockk:mockk:1.13.8")
}

tasks.test {
useJUnitPlatform()
}
36 changes: 36 additions & 0 deletions api/src/main/kotlin/br/com/gamemods/minecity/api/MineCity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package br.com.gamemods.minecity.api

import br.com.gamemods.minecity.api.annotation.internal.InternalMineCityApi
import br.com.gamemods.minecity.api.service.namedplayer.NamedPlayerService

private lateinit var currentInstance: MineCity

/**
* Interface that allows other mods to interact with MineCity.
*/
public interface MineCity {
/**
* The current platform implementation
*/
public val platform: MineCityPlatform

/**
* Allows to get the player name and UUIDs with easy
*/
public val players: NamedPlayerService

/**
* This companion object allows MineCity interface to be used directly in kotlin delegating all API calls to
* the instance that is set at [instance].
*
* @property instance Access to the MineCity API implementation, must be modified only by MineCity itself, can be accessed freely.
*/
public companion object: MineCity by currentInstance {
public var instance: MineCity
get() = currentInstance
@InternalMineCityApi
set(value) {
currentInstance = value
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package br.com.gamemods.minecity.api

import br.com.gamemods.minecity.api.client.MineCityClient
import br.com.gamemods.minecity.api.server.MineCityServer

/**
* Platform specific implementations needed to run MineCity
*/
public interface MineCityPlatform {
/**
* The platform MineCity API implementation.
*/
public val core: MineCity

/**
* `null` if this is not running on a client instance or the client was not laded.
*/
public val client: MineCityClient?

/**
* `null` if this is running on a client that is connected to a server and not hosting it.
*/
public val server: MineCityServer?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package br.com.gamemods.minecity.api.annotation

/**
* Indicates that the annotated element has behavior that varies depending on the currently running platform.
*/
@Retention(value = AnnotationRetention.BINARY)
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPEALIAS, AnnotationTarget.PROPERTY,
AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.CONSTRUCTOR
)
@RequiresOptIn(
level = RequiresOptIn.Level.WARNING, message = "This API behaves differently depending on the Minecraft platform, take care."
)
public annotation class PlatformDependent
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package br.com.gamemods.minecity.api.annotation.internal

/**
* Indicates that the annotated element should only be used by MineCity implementation, not API users.
*/
@Retention(value = AnnotationRetention.BINARY)
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPEALIAS, AnnotationTarget.PROPERTY,
AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.CONSTRUCTOR
)
@RequiresOptIn(
level = RequiresOptIn.Level.ERROR, message = "This is an internal MineCity API that " +
"should not be used from outside of br.com.gamemods.minecity. No compatibility guarantees are provided. " +
"It is recommended to report your use-case of internal API to MineCity2 issue tracker, " +
"so stable API could be provided instead"
)
public annotation class InternalMineCityApi
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package br.com.gamemods.minecity.api.annotation.internal

/**
* Indicates that the annotated element should only be used by MineCity Mixin, not API users.
*/
@Retention(value = AnnotationRetention.BINARY)
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPEALIAS, AnnotationTarget.PROPERTY,
AnnotationTarget.PROPERTY_SETTER
)
@RequiresOptIn(
level = RequiresOptIn.Level.ERROR, message = "This is an internal MineCity Mixin that " +
"should not be used from outside of br.com.gamemods.minecity's mixins. No compatibility guarantees are provided. " +
"It is recommended to report your use-case of internal API to MineCity2 issue tracker, " +
"so stable API could be provided instead"
)
public annotation class InternalMineCityMixin
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package br.com.gamemods.minecity.api.annotation.side

/**
* Indicates that the annotated element must be executed only on client side and might crash on server.
*/
@Retention(value = AnnotationRetention.BINARY)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER)
@RequiresOptIn(
level = RequiresOptIn.Level.ERROR, message = "Make sure this is being executed on client side"
)
public annotation class ClientSideOnly
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package br.com.gamemods.minecity.api.annotation.side

/**
* Indicates that the annotated element must be executed only on server side and might crash on client.
*/
@Retention(value = AnnotationRetention.BINARY)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER)
@RequiresOptIn(
level = RequiresOptIn.Level.ERROR, message = "Make sure this is being executed on server side"
)
public annotation class ServerSideOnly
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package br.com.gamemods.minecity.api.annotation.threading

/**
* Indicates that the annotated element can be executed outside the main server thread without problems.
*/
@Retention(value = AnnotationRetention.BINARY)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER)
public annotation class ASyncFriendly
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package br.com.gamemods.minecity.api.annotation.threading

/**
* Indicates that the annotated element must NOT be executed on the main server thread to prevent crashes, lag or bad behaviours.
*/
@Retention(value = AnnotationRetention.BINARY)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER)
@RequiresOptIn(
level = RequiresOptIn.Level.ERROR, message = "Make sure this is NOT being executed on the main server thread"
)
public annotation class AsyncOnly
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package br.com.gamemods.minecity.api.annotation.threading

/**
* Indicates that the annotated element can be executed only on the main server thread without problems.
*/
@Retention(value = AnnotationRetention.BINARY)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER)
public annotation class SyncFriendly
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package br.com.gamemods.minecity.api.annotation.threading

/**
* Indicates that the annotated element must be executed only on the main server thread to prevent crashes or bad behaviours.
*/
@Retention(value = AnnotationRetention.BINARY)
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER)
@RequiresOptIn(
level = RequiresOptIn.Level.ERROR, message = "Make sure this is being executed on the main server thread"
)
public annotation class SyncOnly
21 changes: 21 additions & 0 deletions api/src/main/kotlin/br/com/gamemods/minecity/api/claim/City.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package br.com.gamemods.minecity.api.claim

import br.com.gamemods.minecity.api.id.CityId
import br.com.gamemods.minecity.api.serializer.MiniComponent
import kotlinx.serialization.Serializable

/**
* A city in MineCity represents a group of claims, cities may also have mayors and elections.
*
* @property id ID of this city
* @property name Visible name of this city
* @property parent If this city is child of another
* @property mayors A list of all mayors this city had, last on list is last on start time.
*/
@Serializable
public data class City(
val name: MiniComponent,
val id: CityId = CityId(),
val parent: CityId? = null,
val mayors: List<CityMayor> = emptyList(),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package br.com.gamemods.minecity.api.claim

import br.com.gamemods.minecity.api.serializer.UniqueId
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import kotlinx.serialization.Serializable
import kotlin.time.Duration

/**
* Data about a mayor of a city.
*
* @property playerId The player ID of the mayor
* @property votes How many votes did this mayor receive during election
* @property totalVotes How may votes were cast to all candidates of an election
* @property since Since when this player started to be a mayor
* @property until When this player stops being mayor
* @property electionDuration How long did the election last
* @property candidates How many candidates were available, including this mayor
* @property voters How many people could vote, may include this mayor
*/
@Serializable
public data class CityMayor(
val playerId: UniqueId,
val votes: Int = 0,
val totalVotes: Int = 0,
val candidates: Int = 0,
val voters: Int = 0,
val until: Instant? = null,
val electionDuration: Duration = Duration.ZERO,
val since: Instant = Clock.System.now(),
)
17 changes: 17 additions & 0 deletions api/src/main/kotlin/br/com/gamemods/minecity/api/claim/Claim.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package br.com.gamemods.minecity.api.claim

import br.com.gamemods.minecity.api.id.ClaimId
import br.com.gamemods.minecity.api.serializer.UniqueId
import kotlinx.serialization.Serializable

@Serializable
public data class Claim(
val id: ClaimId = ClaimId(),
val shape: Set<ClaimShape>,
val parentId: ClaimId? = null,
val owner: UniqueId? = null,
val rent: ClaimRentContract? = null,
val city: City? = null,
val isAdmin: Boolean = false,
val settings: ClaimSettings = ClaimSettings(),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package br.com.gamemods.minecity.api.claim

import br.com.gamemods.minecity.api.serializer.MiniComponent
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
public sealed class ClaimFlagValue {
public abstract val value: Any

@Serializable
@SerialName("component")
public data class MiniComponentValue(override val value: MiniComponent): ClaimFlagValue()

@Serializable
@SerialName("empty")
public data object Empty: ClaimFlagValue() {
override val value: Unit = Unit
}

@Serializable
@SerialName("string")
public data class StringValue(override val value: String): ClaimFlagValue()

@Serializable
@SerialName("boolean")
public data class BooleanValue(override val value: Boolean): ClaimFlagValue()

@Serializable
@SerialName("int")
public data class IntValue(override val value: Int): ClaimFlagValue()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package br.com.gamemods.minecity.api.claim

import br.com.gamemods.minecity.api.math.VirtualMoney
import br.com.gamemods.minecity.api.serializer.UniqueId
import kotlinx.datetime.Instant
import kotlinx.serialization.Serializable
import kotlin.time.Duration

/**
* Information about an active rent, used by claims that is rented to someone.
*
* @property rentedBy Who set this claim on rent
* @property rentedTo Who got the claim
* @property originalSettings Backup of how the claim settings were before the rent
* @property since The start time of the rent
* @property expiresAt When the current contract expires, the rent may be prolonged by [maxExpiredTolerance]
* @property maxExpiredTolerance How long after the [expiresAt] that the rent must still be active, charging an extra [expiredCharges].
* @property renewedAt The last time this rent was renewed on this contract
* @property renewals How many times this rent was renewed on this contract
* @property renewalPrice The price to pay for the next renewal
* @property totalPaidAmount The full amount paid since the start of the rent.
* @property expiredCharges The amount to be paid in case it's paid during the [maxExpiredTolerance]
*/
@Serializable
public data class ClaimRentContract(
val rentedBy: UniqueId,
val rentedTo: UniqueId,
val originalSettings: ClaimSettings,
val since: Instant,
val expiresAt: Instant,
val maxExpiredTolerance: Duration,
val originalPrice: VirtualMoney,
val totalPaidAmount: VirtualMoney,
val renewalPrice: VirtualMoney = originalPrice,
val expiredCharges: VirtualMoney? = null,
val renewals: Int = 0,
val renewedAt: Instant? = null,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package br.com.gamemods.minecity.api.claim

import br.com.gamemods.minecity.api.id.ClamFlagId
import br.com.gamemods.minecity.api.id.ClamPermissionId
import kotlinx.serialization.Serializable

/**
* Flags, permission and trust levels of a claim.
*
* @property defaultFlags The initial flags, used when calculating the effective flags
* @property defaultPermissions The initial permissions, used when calculating the effective permissions
* @property trustLevels The trust levels details
*/
@Serializable
public data class ClaimSettings(
val defaultFlags: Map<ClamFlagId, ClaimFlagValue> = emptyMap(),
val defaultPermissions: Map<ClamPermissionId, Boolean?> = emptyMap(),
val trustLevels: List<TrustLevel> = emptyList(),
)
Loading

0 comments on commit 69db983

Please sign in to comment.