Initial commit

This commit is contained in:
TomTom 2023-10-01 18:46:23 +02:00
commit 985af5f6b6
47 changed files with 1652 additions and 0 deletions

42
.gitignore vendored Normal file
View File

@ -0,0 +1,42 @@
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

3
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

18
.idea/gradle.xml Normal file
View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/api" />
<option value="$PROJECT_DIR$/common" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="ReplaceUntilWithRangeUntil" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
</profile>
</component>

6
.idea/kotlinc.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.9.0" />
</component>
</project>

11
.idea/misc.xml Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="ASK" />
<option name="description" value="" />
</component>
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="temurin-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

2
api/build.gradle Normal file
View File

@ -0,0 +1,2 @@
group = 'com.artillexstudios.axminions'
version = rootProject.version

View File

@ -0,0 +1,22 @@
package com.artillexstudios.axminions.api
import com.artillexstudios.axminions.api.config.Config
import com.artillexstudios.axminions.api.config.Messages
import com.artillexstudios.axminions.api.data.DataHandler
import java.io.File
interface AxMinionsAPI {
fun getAxMinionsDataFolder(): File
fun getMessages(): Messages
fun getConfig(): Config
fun getDataHandler(): DataHandler
companion object {
@JvmStatic
lateinit var INSTANCE: AxMinionsAPI
}
}

View File

@ -0,0 +1,61 @@
package com.artillexstudios.axminions.api.config
import com.artillexstudios.axapi.config.Config
import com.artillexstudios.axminions.api.AxMinionsAPI
import dev.dejvokep.boostedyaml.dvs.versioning.BasicVersioning
import dev.dejvokep.boostedyaml.settings.dumper.DumperSettings
import dev.dejvokep.boostedyaml.settings.general.GeneralSettings
import dev.dejvokep.boostedyaml.settings.loader.LoaderSettings
import dev.dejvokep.boostedyaml.settings.updater.UpdaterSettings
import java.io.File
import java.io.InputStream
class Config(file: File, stream: InputStream) {
companion object {
@JvmField
val AUTO_SAVE_MINUTES = AxMinionsAPI.INSTANCE.getConfig().get("autosave-minutes", 3L)
@JvmField
val MAX_LINKING_DISTANCE = AxMinionsAPI.INSTANCE.getConfig().get("max-linking-distance", 30)
@JvmField
val DEFAULT_MINION_LIMIT = AxMinionsAPI.INSTANCE.getConfig().get("default-minion-limit", 5)
@JvmField
val ALLOW_FLOATING_MINIONS = AxMinionsAPI.INSTANCE.getConfig().get("allow-floating-minions", false)
@JvmField
val ONLY_OWNER_BREAK = AxMinionsAPI.INSTANCE.getConfig().get("only-owner-break", true)
@JvmField
val DISPLAY_WARNINGS = AxMinionsAPI.INSTANCE.getConfig().get("display-warnings", true)
@JvmField
val CAN_BREAK_TOOLS = AxMinionsAPI.INSTANCE.getConfig().get("can-break-tools", true)
@JvmField
val USE_DURABILITY = AxMinionsAPI.INSTANCE.getConfig().get("use-durability", true)
@JvmField
val DATABASE_TYPE = AxMinionsAPI.INSTANCE.getConfig().get("database.type", "H2")
@JvmField
val STACKER_HOOK = AxMinionsAPI.INSTANCE.getConfig().get("hooks.stacker", "none")
@JvmField
val ECONOMY_HOOK = AxMinionsAPI.INSTANCE.getConfig().get("hooks.economy", "Vault")
@JvmField
val PRICES_HOOK = AxMinionsAPI.INSTANCE.getConfig().get("hooks.prices", "ShopGUIPlus")
}
private val config = Config(
file,
stream,
GeneralSettings.builder().setUseDefaults(false).build(),
LoaderSettings.builder().setAutoUpdate(true).build(),
DumperSettings.DEFAULT,
UpdaterSettings.builder().setVersioning(BasicVersioning("config-version")).build()
)
fun <T> get(route: String?, default: T): T {
return this.config.get(route, default)
}
fun <T> get(route: String?): T {
return this.config.get(route)
}
fun reload() {
config.reload()
}
}

View File

@ -0,0 +1,48 @@
package com.artillexstudios.axminions.api.config
import com.artillexstudios.axapi.config.Config
import com.artillexstudios.axapi.utils.StringUtils
import com.artillexstudios.axminions.api.AxMinionsAPI
import dev.dejvokep.boostedyaml.dvs.versioning.BasicVersioning
import dev.dejvokep.boostedyaml.settings.dumper.DumperSettings
import dev.dejvokep.boostedyaml.settings.general.GeneralSettings
import dev.dejvokep.boostedyaml.settings.loader.LoaderSettings
import dev.dejvokep.boostedyaml.settings.updater.UpdaterSettings
import java.io.File
import java.io.InputStream
class Messages(file: File, stream: InputStream) {
companion object {
@JvmField
var PREFIX = AxMinionsAPI.INSTANCE.getMessages().get<String>("prefix")
@JvmField
var NO_CONTAINER_WARNING = AxMinionsAPI.INSTANCE.getMessages().get<String>("warnings.no-container")
@JvmField
var NO_TOOL_WARNING = AxMinionsAPI.INSTANCE.getMessages().get<String>("warnings.no-tool")
@JvmField
var NO_WATER_NEARBY_WARNING = AxMinionsAPI.INSTANCE.getMessages().get<String>("warnings.no-water-nearby")
@JvmField
var CONTAINER_FULL_WARNING = AxMinionsAPI.INSTANCE.getMessages().get<String>("warnings.container-full")
}
private val config = Config(
file,
stream,
GeneralSettings.builder().setUseDefaults(false).build(),
LoaderSettings.builder().setAutoUpdate(true).build(),
DumperSettings.DEFAULT,
UpdaterSettings.builder().setVersioning(BasicVersioning("config-version")).build()
)
fun <T> get(route: String?): T {
return this.config.get(route)
}
fun getFormatted(route: String?): String {
return StringUtils.formatToString(this.config.get(route))
}
fun reload() {
config.reload()
}
}

View File

@ -0,0 +1,22 @@
package com.artillexstudios.axminions.api.data
import com.artillexstudios.axminions.api.minions.Minion
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
import java.util.UUID
interface DataHandler {
fun getType(): String
fun setup()
fun loadMinionsOfType(minionType: MinionType)
fun saveMinion(minion: Minion)
fun deleteMinion(minion: Minion)
fun getMinionAmount(uuid: UUID): Int
fun disable()
}

View File

@ -0,0 +1,3 @@
package com.artillexstudios.axminions.api.exception
class MinionTypeAlreadyRegisteredException(message: String? = null, cause: Throwable? = null) : RuntimeException(message, cause)

View File

@ -0,0 +1,8 @@
package com.artillexstudios.axminions.api.minions
enum class Direction(val yaw: Float) {
NORTH(180f),
WEST(90f),
SOUTH(0f),
EAST(-90f);
}

View File

@ -0,0 +1,75 @@
package com.artillexstudios.axminions.api.minions
import com.artillexstudios.axapi.entity.impl.PacketEntity
import com.artillexstudios.axapi.hologram.Hologram
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
import com.artillexstudios.axminions.api.warnings.Warning
import org.bukkit.Location
import org.bukkit.OfflinePlayer
import org.bukkit.entity.Player
import org.bukkit.inventory.Inventory
import org.bukkit.inventory.ItemStack
import java.util.UUID
interface Minion {
fun getType(): MinionType
fun spawn()
fun tick()
fun getLocation(): Location
fun updateInventory(inventory: Inventory)
fun openInventory(player: Player)
fun getAsItem(): ItemStack
fun getLevel(): Int
fun storeData(key: String, value: String?)
fun setWarning(warning: Warning?)
fun getWarning(): Warning?
fun setWarningHologram(hologram: Hologram?)
fun getWarningHologram(): Hologram?
fun getOwner(): OfflinePlayer?
fun getOwnerUUID(): UUID
fun setTool(tool: ItemStack)
fun getTool(): ItemStack?
fun getEntity(): PacketEntity
fun setLevel(level: Int)
fun getData(key: String): String?
fun hasData(key: String): Boolean
fun getNextAction(): Int
fun getRange(): Double
fun resetAnimation()
fun animate()
fun setLinkedChest(location: Location?)
fun getLinkedChest(): Location?
fun serializeExtraData(): String
fun setDirection(direction: Direction)
fun getDirection(): Direction
}

View File

@ -0,0 +1,42 @@
package com.artillexstudios.axminions.api.minions.miniontype
import com.artillexstudios.axapi.config.Config
import com.artillexstudios.axminions.api.AxMinionsAPI
import com.artillexstudios.axminions.api.minions.Minion
import org.bukkit.Location
import java.io.File
import java.io.InputStream
abstract class MinionType(private val name: String, private val defaults: InputStream) {
private lateinit var config: Config
fun load() {
config = Config(File(AxMinionsAPI.INSTANCE.getAxMinionsDataFolder(), "$name.yml"), defaults)
AxMinionsAPI.INSTANCE.getDataHandler().loadMinionsOfType(this)
}
fun getName(): String {
return this.name
}
open fun shouldRun(minion: Minion): Boolean {
return true
}
private fun isChunkLoaded(location: Location): Boolean {
return location.world?.isChunkLoaded(location.blockX shr 4, location.blockZ shr 4) ?: return false
}
fun tick(minion: Minion) {
if (!isChunkLoaded(minion.getLocation())) return
if (!shouldRun(minion)) return
run(minion)
}
fun getConfig(): Config {
return this.config
}
abstract fun run(minion: Minion)
}

View File

@ -0,0 +1,26 @@
package com.artillexstudios.axminions.api.minions.miniontype
import com.artillexstudios.axminions.api.exception.MinionTypeAlreadyRegisteredException
import java.util.Collections
object MinionTypes {
private val TYPES = hashMapOf<String, MinionType>()
fun register(type: MinionType): MinionType {
if (TYPES.containsKey(type.getName())) {
throw MinionTypeAlreadyRegisteredException("A minion with type ${type.getName()} has already been registered!")
}
TYPES[type.getName()] = type
type.load()
return type
}
fun unregister(key: String) {
TYPES.remove(key)
}
fun getMinionTypes(): Map<String, MinionType> {
return Collections.unmodifiableMap(TYPES)
}
}

View File

@ -0,0 +1,23 @@
package com.artillexstudios.axminions.api.warnings
import com.artillexstudios.axapi.hologram.HologramFactory
import com.artillexstudios.axminions.api.minions.Minion
import net.kyori.adventure.text.Component
abstract class Warning(private val name: String) {
fun getName(): String {
return this.name
}
abstract fun getContent(): Component
fun display(minion: Minion) {
if (minion.getWarning() == null) {
val hologram = HologramFactory.get()
.spawnHologram(minion.getLocation().add(0.0, 0.15, 0.0), minion.getLocation().toString())
hologram.addLine(getContent())
minion.setWarning(this)
}
}
}

View File

@ -0,0 +1,37 @@
package com.artillexstudios.axminions.api.warnings
import com.artillexstudios.axminions.api.minions.Minion
import com.artillexstudios.axminions.api.warnings.impl.WarningContainerFull
import com.artillexstudios.axminions.api.warnings.impl.WarningNoContainer
import com.artillexstudios.axminions.api.warnings.impl.WarningNoTool
import com.artillexstudios.axminions.api.warnings.impl.WarningNoWaterNearby
object Warnings {
private val WARNINGS = hashMapOf<String, Warning>()
@JvmField
val CONTAINER_FULL = register(WarningContainerFull())
@JvmField
val NO_CONTAINER = register(WarningNoContainer())
@JvmField
val NO_TOOL = register(WarningNoTool())
@JvmField
val NO_WATER_NEARBY = register(WarningNoWaterNearby())
@JvmStatic
fun register(warning: Warning): Warning {
WARNINGS[warning.getName()] = warning
return warning
}
@JvmStatic
fun remove(minion: Minion) {
minion.getWarningHologram()?.remove()
minion.setWarningHologram(null)
minion.setWarning(null)
}
}

View File

@ -0,0 +1,13 @@
package com.artillexstudios.axminions.api.warnings.impl
import com.artillexstudios.axapi.utils.StringUtils
import com.artillexstudios.axminions.api.config.Messages
import com.artillexstudios.axminions.api.warnings.Warning
import net.kyori.adventure.text.Component
class WarningContainerFull : Warning("container_full") {
override fun getContent(): Component {
return StringUtils.format(Messages.CONTAINER_FULL_WARNING)
}
}

View File

@ -0,0 +1,13 @@
package com.artillexstudios.axminions.api.warnings.impl
import com.artillexstudios.axapi.utils.StringUtils
import com.artillexstudios.axminions.api.config.Messages
import com.artillexstudios.axminions.api.warnings.Warning
import net.kyori.adventure.text.Component
class WarningNoContainer : Warning("no_container") {
override fun getContent(): Component {
return StringUtils.format(Messages.NO_CONTAINER_WARNING)
}
}

View File

@ -0,0 +1,13 @@
package com.artillexstudios.axminions.api.warnings.impl
import com.artillexstudios.axapi.utils.StringUtils
import com.artillexstudios.axminions.api.config.Messages
import com.artillexstudios.axminions.api.warnings.Warning
import net.kyori.adventure.text.Component
class WarningNoTool : Warning("no_tool") {
override fun getContent(): Component {
return StringUtils.format(Messages.NO_TOOL_WARNING)
}
}

View File

@ -0,0 +1,13 @@
package com.artillexstudios.axminions.api.warnings.impl
import com.artillexstudios.axapi.utils.StringUtils
import com.artillexstudios.axminions.api.config.Messages
import com.artillexstudios.axminions.api.warnings.Warning
import net.kyori.adventure.text.Component
class WarningNoWaterNearby : Warning("no_water_nearby") {
override fun getContent(): Component {
return StringUtils.format(Messages.NO_WATER_NEARBY_WARNING)
}
}

79
build.gradle Normal file
View File

@ -0,0 +1,79 @@
plugins {
id 'java-library'
id 'com.github.johnrengelman.shadow' version "8.1.1"
id 'maven-publish'
id 'java'
id 'org.jetbrains.kotlin.jvm' version '1.9.0'
}
group = 'com.artillexstudios.axminions'
version = '1.0-SNAPSHOT'
repositories {
mavenCentral()
maven {
url = uri('https://jitpack.io/')
}
}
dependencies {
implementation project(path: ":api")
}
allprojects {
apply plugin: 'org.jetbrains.kotlin.jvm'
apply plugin: 'java'
apply plugin: 'java-library'
apply plugin: 'com.github.johnrengelman.shadow'
kotlin {
jvmToolchain(17)
}
repositories {
mavenCentral()
mavenLocal()
maven {
url = uri('https://hub.spigotmc.org/nexus/content/repositories/snapshots/')
}
maven {
url = uri('https://repo.rosewooddev.io/repository/public/' )
}
maven {
url = uri('https://repo.bg-software.com/repository/api/' )
}
maven {
url = uri('https://jitpack.io/')
}
maven {
url = uri('https://repo.alessiodp.com/releases/')
}
}
dependencies {
compileOnly 'org.spigotmc:spigot-api:1.20.1-R0.1-SNAPSHOT'
compileOnly 'dev.rosewood:rosestacker:1.5.11'
compileOnly 'com.bgsoftware:WildStackerAPI:2023.2'
compileOnly 'com.github.MilkBowl:VaultAPI:1.7'
compileOnly 'com.h2database:h2:2.2.220'
compileOnly 'com.github.NEZNAMY:YamlAssist:1.0.5'
compileOnly 'com.github.brcdev-minecraft:shopgui-api:3.0.0'
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.9.0'
implementation 'com.github.Carleslc.Simple-YAML:Simple-Yaml:1.8.4'
implementation files('../libs/AxAPI-1.0-SNAPSHOT.jar')
}
shadowJar {
relocate("com.artillexstudios.axapi", "com.artillexstudios.axminions.libs.axapi")
}
}
kotlin {
jvmToolchain(17)
}

7
common/build.gradle Normal file
View File

@ -0,0 +1,7 @@
group = 'com.artillexstudios.axminions'
version = rootProject.version
dependencies {
implementation project(':api')
}

View File

@ -0,0 +1,20 @@
package com.artillexstudios.axminions
import com.artillexstudios.axapi.AxPlugin
import com.artillexstudios.axminions.api.AxMinionsAPI
import com.artillexstudios.axminions.api.AxMinionsAPIImpl
class AxMinionsPlugin : AxPlugin() {
companion object {
lateinit var INSTANCE: AxMinionsPlugin
}
override fun load() {
INSTANCE = this
AxMinionsAPI.INSTANCE = AxMinionsAPIImpl(this)
}
override fun enable() {
}
}

View File

@ -0,0 +1,28 @@
package com.artillexstudios.axminions.api
import com.artillexstudios.axminions.AxMinionsPlugin
import com.artillexstudios.axminions.api.config.Config
import com.artillexstudios.axminions.api.config.Messages
import com.artillexstudios.axminions.api.data.DataHandler
import java.io.File
class AxMinionsAPIImpl(private val plugin: AxMinionsPlugin) : AxMinionsAPI {
private val messages = Messages(File(getAxMinionsDataFolder(), "messages.yml"), plugin.getResource("messages.yml")!!)
private val config = Config(File(getAxMinionsDataFolder(), "config.yml"), plugin.getResource("config.yml")!!)
override fun getAxMinionsDataFolder(): File {
return plugin.dataFolder
}
override fun getMessages(): Messages {
return messages
}
override fun getConfig(): Config {
return config
}
override fun getDataHandler(): DataHandler {
TODO("Not yet implemented")
}
}

View File

@ -0,0 +1,123 @@
package com.artillexstudios.axminions.data
import com.artillexstudios.axapi.serializers.Serializers
import com.artillexstudios.axminions.AxMinionsPlugin
import com.artillexstudios.axminions.api.minions.Direction
import com.artillexstudios.axminions.api.minions.Minion
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
import com.artillexstudios.axminions.api.data.DataHandler
import com.artillexstudios.axminions.minions.MinionImpl
import org.bukkit.Bukkit
import org.bukkit.Location
import org.bukkit.Material
import org.bukkit.inventory.ItemStack
import org.h2.jdbc.JdbcConnection
import java.sql.Connection
import java.util.Properties
import java.util.UUID
class H2DataHandler : DataHandler {
private lateinit var connection: Connection
override fun getType(): String {
return "H2"
}
override fun setup() {
connection =
JdbcConnection("jdbc:h2:./${AxMinionsPlugin.INSTANCE.dataFolder}/data", Properties(), null, null, false)
connection.prepareStatement("CREATE TABLE IF NOT EXISTS `axminions_data`(`location` VARCHAR(256) NOT NULL, `owner` VARCHAR(36) NOT NULL, `linked-chest-location` VARCHAR(256) DEFAULT NULL, `extra_data` CLOB DEFAULT NULL, `direction` TINYINT NOT NULL DEFAULT '0', `type` VARCHAR(64) NOT NULL, `level` SMALLINT NOT NULL DEFAULT '1', `tool` CLOB DEFAULT NULL, PRIMARY KEY(`location`));")
.use { preparedStatement ->
preparedStatement.executeUpdate()
}
}
override fun loadMinionsOfType(minionType: MinionType) {
connection.prepareStatement("SELECT * FROM `axminions_data` WHERE `type` = ?;").use { preparedStatement ->
preparedStatement.setString(1, minionType.getName())
preparedStatement.executeQuery().use { resultSet ->
while (resultSet.next()) {
val location = resultSet.getString("location")
val owner = resultSet.getString("owner")
val direction = Direction.entries[resultSet.getInt("direction")]
val level = resultSet.getInt("level")
val tool = resultSet.getString("tool")
val linkedChest = resultSet.getString("linked-chest-location")
val extraData = resultSet.getString("extra_data")
val uuid = UUID.fromString(owner)
val ownerPlayer = Bukkit.getOfflinePlayer(uuid)
var linkedChestLocation: Location? = null
if (linkedChest != null) {
linkedChestLocation = Serializers.LOCATION.deserialize(linkedChest)
}
var itemStack = ItemStack(Material.AIR)
if (tool != null) {
itemStack = Serializers.ITEM_STACK.deserialize(tool)
}
MinionImpl(
Serializers.LOCATION.deserialize(location),
uuid,
ownerPlayer,
minionType,
level,
itemStack,
linkedChestLocation,
direction,
extraData
)
}
}
}
}
override fun saveMinion(minion: Minion) {
connection.prepareStatement("MERGE INTO `axminions_data`(`location`, `owner`, `linked-chest-location`, `extra_data`, `direction`, `type`, `level`, `tool`) KEY(`location`) VALUES(?,?,?,?,?,?,?,?);")
.use { preparedStatement ->
preparedStatement.setString(1, Serializers.LOCATION.serialize(minion.getLocation()))
preparedStatement.setString(2, minion.getOwnerUUID().toString())
preparedStatement.setString(
3,
when (minion.getLinkedChest()) {
null -> null
else -> Serializers.LOCATION.serialize(minion.getLinkedChest())
}
)
preparedStatement.setString(4, minion.serializeExtraData())
preparedStatement.setInt(5, minion.getDirection().ordinal)
preparedStatement.setString(6, minion.getType().getName())
preparedStatement.setInt(7, minion.getLevel())
preparedStatement.setString(8, Serializers.ITEM_STACK.serialize(minion.getTool()))
preparedStatement.executeUpdate()
}
}
override fun deleteMinion(minion: Minion) {
connection.prepareStatement("DELETE FROM `axminions_data` WHERE `location` = ?;").use { preparedStatement ->
preparedStatement.setString(1, Serializers.LOCATION.serialize(minion.getLocation()))
preparedStatement.executeUpdate()
}
}
override fun getMinionAmount(uuid: UUID): Int {
connection.prepareStatement("SELECT COUNT(`owner`) FROM `axminions_data` WHERE `owner` = ?;")
.use { preparedStatement ->
preparedStatement.setString(1, uuid.toString())
preparedStatement.executeQuery().use { resultSet ->
if (resultSet.next()) {
return resultSet.getInt(1)
}
}
}
return 0
}
override fun disable() {
connection.close()
}
}

View File

@ -0,0 +1,205 @@
package com.artillexstudios.axminions.minions
import com.artillexstudios.axapi.entity.PacketEntityFactory
import com.artillexstudios.axapi.entity.impl.PacketArmorStand
import com.artillexstudios.axapi.entity.impl.PacketEntity
import com.artillexstudios.axapi.hologram.Hologram
import com.artillexstudios.axapi.utils.RotationType
import com.artillexstudios.axminions.api.minions.Direction
import com.artillexstudios.axminions.api.minions.Minion
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
import com.artillexstudios.axminions.api.warnings.Warning
import com.artillexstudios.axminions.utils.fastFor
import org.bukkit.Location
import org.bukkit.OfflinePlayer
import org.bukkit.enchantments.Enchantment
import org.bukkit.entity.EntityType
import org.bukkit.entity.Player
import org.bukkit.inventory.Inventory
import org.bukkit.inventory.ItemStack
import org.bukkit.util.EulerAngle
import java.util.UUID
import kotlin.math.roundToInt
class MinionImpl(
private val location: Location,
private val ownerUUID: UUID,
private val owner: OfflinePlayer,
private val type: MinionType,
private var level: Int,
private var tool: ItemStack?,
private var linkedChest: Location?,
private var direction: Direction,
savedExtraData: String
) : Minion {
private lateinit var entity: PacketArmorStand
private var nextAction = 0
private var range = 0.0
private var dirty = false
private var armTick = 2.0
private var warning: Warning? = null
private var hologram: Hologram? = null
private val extraData = hashMapOf<String, String>()
init {
spawn()
loadExtraData(savedExtraData)
}
override fun getType(): MinionType {
return this.type
}
override fun spawn() {
entity = PacketEntityFactory.get().spawnEntity(location, EntityType.ARMOR_STAND) as PacketArmorStand
entity.setHasBasePlate(false)
entity.setSmall(true)
}
override fun tick() {
if (dirty) {
dirty = false
range = type.getConfig().get("range", 0.0)
val efficiency = 1.0 - (getTool()?.getEnchantmentLevel(Enchantment.DIG_SPEED)?.div(10.0) ?: 0.1)
nextAction = (type.getConfig().get("speed", 0L) * efficiency).roundToInt()
}
type.tick(this)
animate()
}
override fun getLocation(): Location {
return this.location
}
override fun updateInventory(inventory: Inventory) {
TODO("Not yet implemented")
}
override fun openInventory(player: Player) {
TODO("Not yet implemented")
}
override fun getAsItem(): ItemStack {
TODO("Not yet implemented")
}
override fun getLevel(): Int {
return this.level
}
override fun storeData(key: String, value: String?) {
if (value == null) {
extraData.remove(key)
return
}
extraData[key] = value
}
override fun setWarning(warning: Warning?) {
this.warning = warning
}
override fun getWarning(): Warning? {
return this.warning
}
override fun setWarningHologram(hologram: Hologram?) {
this.hologram = hologram
}
override fun getWarningHologram(): Hologram? {
return this.hologram
}
override fun getOwner(): OfflinePlayer {
return this.owner
}
override fun getOwnerUUID(): UUID {
return this.ownerUUID
}
override fun setTool(tool: ItemStack) {
this.tool = tool
}
override fun getTool(): ItemStack? {
return this.tool
}
override fun getEntity(): PacketEntity {
return this.entity
}
override fun setLevel(level: Int) {
this.level = level
}
override fun getData(key: String): String? {
return extraData[key]
}
override fun hasData(key: String): Boolean {
return extraData.containsKey(key)
}
override fun getNextAction(): Int {
return this.nextAction
}
override fun getRange(): Double {
return this.range
}
override fun resetAnimation() {
armTick = 0.0
}
override fun animate() {
if (armTick >= 2) return
entity.setRotation(RotationType.RIGHT_ARM, EulerAngle(-2 + armTick, 0.0, 0.0))
armTick += 0.2
}
override fun setLinkedChest(location: Location?) {
this.linkedChest = location?.clone()
}
override fun getLinkedChest(): Location? {
return this.linkedChest
}
override fun serializeExtraData(): String {
val builder = StringBuilder()
for (data in extraData) {
builder.append(data.key)
builder.append("=")
builder.append(data.value)
builder.append("|")
}
return builder.toString()
}
override fun setDirection(direction: Direction) {
this.direction = direction
location.yaw = direction.yaw
entity.teleport(location)
}
override fun getDirection(): Direction {
return this.direction
}
private fun loadExtraData(data: String) {
data.split("|").fastFor { split ->
val secondSplit = split.split("=")
if (secondSplit.isNotEmpty()) {
extraData[secondSplit[0]] = secondSplit[1]
}
}
}
}

View File

@ -0,0 +1,15 @@
package com.artillexstudios.axminions.minions
object MinionTicker {
private var tick = 0L
fun tickAll() {
// Code to tick all
tick++
}
fun getTick(): Long {
return this.tick
}
}

View File

@ -0,0 +1,49 @@
package com.artillexstudios.axminions.minions.miniontype
import com.artillexstudios.axminions.AxMinionsPlugin
import com.artillexstudios.axminions.api.minions.Minion
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
import com.artillexstudios.axminions.api.warnings.Warnings
import com.artillexstudios.axminions.minions.MinionTicker
import org.bukkit.block.Container
import org.bukkit.entity.Item
class CollectorMinionType : MinionType("collector", AxMinionsPlugin.INSTANCE.getResource("minions/collector.yml")!!) {
override fun shouldRun(minion: Minion): Boolean {
return MinionTicker.getTick() % minion.getNextAction() == 0L
}
override fun run(minion: Minion) {
minion.resetAnimation()
if (minion.getLinkedChest() == null) {
Warnings.NO_CONTAINER.display(minion)
return
}
val state = minion.getLinkedChest()?.block?.state
if (state !is Container) {
Warnings.NO_CONTAINER.display(minion)
minion.setLinkedChest(null)
return
}
Warnings.remove(minion)
val entities = minion.getLocation().world?.getNearbyEntities(
minion.getLocation(),
minion.getRange(),
minion.getRange(),
minion.getRange()
)
entities?.filterIsInstance<Item>()?.forEach { item ->
if (state.inventory.firstEmpty() == -1) {
Warnings.CONTAINER_FULL.display(minion)
return
}
//TODO: Add to inventory and remove items
}
}
}

View File

@ -0,0 +1,12 @@
package com.artillexstudios.axminions.minions.miniontype
import com.artillexstudios.axminions.AxMinionsPlugin
import com.artillexstudios.axminions.api.minions.Minion
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
class FarmerMinionType : MinionType("farmer", AxMinionsPlugin.INSTANCE.getResource("minions/farmer.yml")!!) {
override fun run(minion: Minion) {
TODO("Not yet implemented")
}
}

View File

@ -0,0 +1,12 @@
package com.artillexstudios.axminions.minions.miniontype
import com.artillexstudios.axminions.AxMinionsPlugin
import com.artillexstudios.axminions.api.minions.Minion
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
class FisherMinionType : MinionType("fisher", AxMinionsPlugin.INSTANCE.getResource("minions/fisher.yml")!!) {
override fun run(minion: Minion) {
TODO("Not yet implemented")
}
}

View File

@ -0,0 +1,12 @@
package com.artillexstudios.axminions.minions.miniontype
import com.artillexstudios.axminions.AxMinionsPlugin
import com.artillexstudios.axminions.api.minions.Minion
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
class LumberMinionType : MinionType("lumber", AxMinionsPlugin.INSTANCE.getResource("minions/lumber.yml")!!) {
override fun run(minion: Minion) {
TODO("Not yet implemented")
}
}

View File

@ -0,0 +1,12 @@
package com.artillexstudios.axminions.minions.miniontype
import com.artillexstudios.axminions.AxMinionsPlugin
import com.artillexstudios.axminions.api.minions.Minion
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
class MinerMinionType : MinionType("miner", AxMinionsPlugin.INSTANCE.getResource("minions/miner.yml")!!) {
override fun run(minion: Minion) {
TODO("Not yet implemented")
}
}

View File

@ -0,0 +1,12 @@
package com.artillexstudios.axminions.minions.miniontype
import com.artillexstudios.axminions.AxMinionsPlugin
import com.artillexstudios.axminions.api.minions.Minion
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
class SellerMinionType : MinionType("seller", AxMinionsPlugin.INSTANCE.getResource("minions/seller.yml")!!) {
override fun run(minion: Minion) {
TODO("Not yet implemented")
}
}

View File

@ -0,0 +1,12 @@
package com.artillexstudios.axminions.minions.miniontype
import com.artillexstudios.axminions.AxMinionsPlugin
import com.artillexstudios.axminions.api.minions.Minion
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
class SlayerMinionType : MinionType("slayer", AxMinionsPlugin.INSTANCE.getResource("minions/slayer.yml")!!) {
override fun run(minion: Minion) {
TODO("Not yet implemented")
}
}

View File

@ -0,0 +1,15 @@
package com.artillexstudios.axminions.utils
inline fun <T> Array<T>.fastFor(action: (T) -> Unit) {
val indices = indices
for (i in indices) {
action(get(i))
}
}
inline fun <T> List<T>.fastFor(action: (T) -> Unit) {
val indices = indices
for (i in indices) {
action(get(i))
}
}

View File

@ -0,0 +1,47 @@
# How often should the plugin save all minions?
# The plugin saves changes live, this is only for updating minion stats in the database.
# For this change to take effect, you need to restart your server!
auto-save-minutes: 3
# How far the storage chest can be from the minion
max-linking-distance: 30
# The default amount of minions a player can have.
# This setting can be overwritten by setting the 'axminions.limit.<amount>' permission!
default-minion-limit: 5
# If we should allow floating minions to be created
allow-floating-minions: false
# If true, only the owner of this minion can break it
# If false, everyone, who can break blocks at said location can break this minion
# You should enable this, if you aren't using a supported protection plugin!
only-owner-break: true
# Should minions show holograms if they have an issue?
# (They won't complain about not having a girlfriend, though!)
# You can configure these messages in the messages.yml
display-warnings: true
# If set to true, the minion will not break the tool, it will just stay at 1 durability (and the minion will be stopped)
# If set to false, the minion can break the tool
can-break-tools: true
# If the minion should be able to take durability from it's held item
use-durability: true
database:
# Can be H2 and SQLite.
# For most setups, H2 is recommended
type: "H2"
hooks:
# Supported stacker plugins: WildStacker, RoseStacker, none
stacker: "none"
# Supported economy providers: Vault, PlayerPoints, custom
economy: "Vault"
# Supported prices providers: ShopGUIPlus, Essentials, EconomyShopGUI, CMI, custom
prices: "ShopGUIPlus"
# Do not change!
config-version: 1

View File

@ -0,0 +1,10 @@
prefix: "<gradient:#00aaff:#00ccff>AxMinions</gradient> <gray>»</gray> "
warnings:
no-container: "<#FF3333>⚠ <#FFAAAA>You must link the minion to a container </#FFAAAA>⚠"
no-tool: "<#FF3333>⚠ <#FFAAAA>The minion needs a tool </#FFAAAA>⚠"
no-water-nearby: "<#FF3333>⚠ <#FFAAAA>The minion needs water nearby </#FFAAAA>⚠"
container-full: "<#FF3333>⚠ <#FFAAAA>The container of this minion is full </#FFAAAA>⚠"
# Do not change!
config-version: 1

View File

@ -0,0 +1,131 @@
name: "<level_color>[<level>] <#FFEE00>Collector <white>Minion <gray>[<owner>]"
tool:
material:
- "WOODEN_SHOVEL"
- "STONE_SHOVEL"
- "GOLDEN_SHOVEL"
- "IRON_SHOVEL"
- "DIAMOND_SHOVEL"
- "NETHERITE_SHOVEL"
item:
material: "player_head"
texture: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvN2UzZDM2MzVjZTQxMWFiZjFlNGYzNzNkMTYxZDA3YjhjNDdlMzU5YjZjNTZmNzRiNDEzY2I0OTRhYzc0NmUyZCJ9fX0="
name: "<#FFEE00>Collector <white>Minion"
lore:
- ""
- " <gray>- <white>Collects all items around itself."
- ""
- "<#FFEE00>Statistics"
- " <#FFEE00>❙ <white>Level: <#FFEEAA><level>"
- " <#FFEE00>❙ <white>Collected items: <#FFEEAA><items>"
- ""
- "<#FFEE00><b>(!)</b> Place the minion and give it a shovel!"
gui:
upgrade:
material: "gold_ingot"
name: "<#00CCFF><b>Upgrade minion"
lore:
- ""
- " <gray>- <white>Level: <green><current_level> » <dark_green><next_level>"
- " <gray>- <white>Range: <green><current_range> » <dark_green><next_range>"
- " <gray>- <white>Speed: <green><current_speed> » <dark_green><next_speed>"
- ""
- "<#00CCFF>Requirements:"
- " <gray>- <white>Money: <#33FF33><price>$"
- " <gray>- <white>Collected items: <#33FF33><required_actions>"
- ""
- "<#00CCFF><b>(!)</b> Click here to upgrade your minion!"
statistics:
material: "paper"
name: "<#FFEE00><b>Statistics"
lore:
- ""
- " <gray>- <white>Collected items: <#FFEE00><statistic_collected>"
- ""
upgrades:
1:
range: 2
speed: 160
items:
helmet:
material: "player_head"
texture: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvN2UzZDM2MzVjZTQxMWFiZjFlNGYzNzNkMTYxZDA3YjhjNDdlMzU5YjZjNTZmNzRiNDEzY2I0OTRhYzc0NmUyZCJ9fX0="
chestplate:
material: "leather_chestplate"
color: "255, 230, 0"
glow: false
leggings:
material: "leather_leggings"
color: "255, 230, 0"
glow: false
boots:
material: "leather_boots"
color: "255, 230, 0"
glow: false
2:
range: 3
requirements:
money: 1000
actions: 100
3:
range: 4
speed: 140
requirements:
money: 3000
actions: 300
4:
range: 5
requirements:
money: 10000
actions: 1000
5:
range: 5
speed: 120
requirements:
money: 20000
actions: 3000
6:
range: 6
requirements:
money: 50000
actions: 6000
7:
range: 7
speed: 100
requirements:
money: 150000
actions: 10000
8:
range: 8
requirements:
money: 500000
actions: 17500
9:
range: 9
speed: 90
requirements:
money: 1000000
actions: 25000
10:
range: 10
speed: 80
requirements:
money: 5000000
actions: 50000
items:
chestplate:
material: LEATHER_CHESTPLATE
color: "255, 200, 0"
glow: true
leggings:
material: LEATHER_LEGGINGS
color: "255, 200, 0"
glow: true
boots:
material: LEATHER_BOOTS
color: "255, 200, 0"
glow: true

1
gradle.properties Normal file
View File

@ -0,0 +1 @@
kotlin.code.style=official

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

234
gradlew vendored Normal file
View File

@ -0,0 +1,234 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

89
gradlew.bat vendored Normal file
View File

@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

BIN
libs/AxAPI-1.0-SNAPSHOT.jar Normal file

Binary file not shown.

15
settings.gradle Normal file
View File

@ -0,0 +1,15 @@
pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
}
}
plugins {
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.5.0'
}
rootProject.name = 'AxMinions'
include 'api'
include 'common'