mirror of
https://github.com/Auxilor/EcoMenus.git
synced 2025-12-19 15:09:20 +00:00
Implemented pretty much the rest of the plugin
This commit is contained in:
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: Discord
|
||||||
|
url: https://discord.gg/ZcwpSsE/
|
||||||
|
about: Issues have moved to Discord, please join the server to get help!
|
||||||
11
.github/ISSUE_TEMPLATE/report-a-bug.md
vendored
Normal file
11
.github/ISSUE_TEMPLATE/report-a-bug.md
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
name: Report a Bug
|
||||||
|
about: Report an issue with the plugin
|
||||||
|
title: ''
|
||||||
|
labels: bug
|
||||||
|
assignees: ''
|
||||||
|
---
|
||||||
|
|
||||||
|
# Please report bugs on the discord!
|
||||||
|
|
||||||
|
[Join by clicking here](https://discord.gg/ZcwpSsE/)
|
||||||
33
.github/workflows/publish-release.yml
vendored
Normal file
33
.github/workflows/publish-release.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
name: Publish Packages
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
release:
|
||||||
|
types: [ created ]
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Checkout latest code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set up JDK 17
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: 17
|
||||||
|
|
||||||
|
- name: Change wrapper permissions
|
||||||
|
run: chmod +x ./gradlew
|
||||||
|
|
||||||
|
- name: Publish package
|
||||||
|
uses: gradle/gradle-build-action@v2
|
||||||
|
with:
|
||||||
|
arguments: publish
|
||||||
|
env:
|
||||||
|
MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
|
||||||
|
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
|
||||||
@@ -4,10 +4,12 @@ plugins {
|
|||||||
`maven-publish`
|
`maven-publish`
|
||||||
kotlin("jvm") version "1.7.10"
|
kotlin("jvm") version "1.7.10"
|
||||||
id("com.github.johnrengelman.shadow") version "8.0.0"
|
id("com.github.johnrengelman.shadow") version "8.0.0"
|
||||||
|
id("com.willfp.libreforge-gradle-plugin") version "1.0.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "com.willfp"
|
group = "com.willfp"
|
||||||
version = findProperty("version")!!
|
version = findProperty("version")!!
|
||||||
|
val libreforgeVersion = findProperty("libreforge-version")
|
||||||
|
|
||||||
base {
|
base {
|
||||||
archivesName.set(project.name)
|
archivesName.set(project.name)
|
||||||
@@ -38,7 +40,6 @@ allprojects {
|
|||||||
compileOnly("com.willfp:eco:6.63.0")
|
compileOnly("com.willfp:eco:6.63.0")
|
||||||
compileOnly("org.jetbrains:annotations:23.0.0")
|
compileOnly("org.jetbrains:annotations:23.0.0")
|
||||||
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:1.7.10")
|
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:1.7.10")
|
||||||
implementation("com.willfp:ecomponent:1.4.1")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
@@ -48,6 +49,7 @@ allprojects {
|
|||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
shadowJar {
|
shadowJar {
|
||||||
|
relocate("com.willfp.libreforge.loader", "com.willfp.ecomenus.libreforge.loader")
|
||||||
relocate("com.willfp.ecomponent", "com.willfp.ecomenus.ecomponent")
|
relocate("com.willfp.ecomponent", "com.willfp.ecomenus.ecomponent")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,6 +70,7 @@ allprojects {
|
|||||||
filesMatching(listOf("**plugin.yml", "**eco.yml")) {
|
filesMatching(listOf("**plugin.yml", "**eco.yml")) {
|
||||||
expand(
|
expand(
|
||||||
"version" to project.version,
|
"version" to project.version,
|
||||||
|
"libreforgeVersion" to libreforgeVersion,
|
||||||
"pluginName" to rootProject.name
|
"pluginName" to rootProject.name
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -77,17 +80,4 @@ allprojects {
|
|||||||
dependsOn(shadowJar)
|
dependsOn(shadowJar)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
|
||||||
clean {
|
|
||||||
doLast {
|
|
||||||
file("${rootDir}/bin").deleteRecursively()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shadowJar {
|
|
||||||
destinationDirectory.set(file("$rootDir/bin/"))
|
|
||||||
archiveFileName.set("${project.name} v${project.version}.jar")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,13 +3,19 @@ version = rootProject.version
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly("io.papermc.paper:paper-api:1.19.3-R0.1-SNAPSHOT")
|
compileOnly("io.papermc.paper:paper-api:1.19.3-R0.1-SNAPSHOT")
|
||||||
|
compileOnly("com.github.ben-manes.caffeine:caffeine:3.0.5")
|
||||||
|
|
||||||
|
implementation("com.willfp:ecomponent:1.4.1")
|
||||||
}
|
}
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
publications {
|
publications {
|
||||||
register("maven", MavenPublication::class) {
|
register<MavenPublication>("maven") {
|
||||||
from(components["java"])
|
groupId = project.group.toString()
|
||||||
|
version = project.version.toString()
|
||||||
artifactId = rootProject.name
|
artifactId = rootProject.name
|
||||||
|
|
||||||
|
artifact(rootProject.tasks.shadowJar.get().archiveFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +1,21 @@
|
|||||||
package com.willfp.ecomenus
|
package com.willfp.ecomenus
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin
|
|
||||||
import com.willfp.eco.core.command.impl.PluginCommand
|
import com.willfp.eco.core.command.impl.PluginCommand
|
||||||
import com.willfp.ecomenus.commands.CommandEcoMenus
|
import com.willfp.ecomenus.commands.CommandEcoMenus
|
||||||
import com.willfp.ecomenus.config.ConfigCategory
|
|
||||||
import com.willfp.ecomenus.menus.EcoMenus
|
import com.willfp.ecomenus.menus.EcoMenus
|
||||||
|
import com.willfp.libreforge.loader.LibreforgePlugin
|
||||||
|
import com.willfp.libreforge.loader.configs.ConfigCategory
|
||||||
|
|
||||||
class EcoMenusPlugin : EcoPlugin() {
|
class EcoMenusPlugin : LibreforgePlugin() {
|
||||||
private val categories = setOf<ConfigCategory>(
|
|
||||||
EcoMenus
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun handleEnable() {
|
|
||||||
for (category in categories) {
|
|
||||||
category.copyConfigs(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun handleReload() {
|
|
||||||
for (category in categories) {
|
|
||||||
category.reload(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun loadPluginCommands(): List<PluginCommand> {
|
override fun loadPluginCommands(): List<PluginCommand> {
|
||||||
return listOf(
|
return listOf(
|
||||||
CommandEcoMenus(this)
|
CommandEcoMenus(this)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun loadConfigCategories(): List<ConfigCategory> {
|
||||||
|
return listOf(
|
||||||
|
EcoMenus
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,6 @@ class DynamicMenuCommand(
|
|||||||
true
|
true
|
||||||
) {
|
) {
|
||||||
override fun onExecute(sender: Player, args: List<String>) {
|
override fun onExecute(sender: Player, args: List<String>) {
|
||||||
menu.menu.open(sender)
|
menu.open(sender)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package com.willfp.ecomenus.components
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
|
import com.willfp.eco.core.fast.fast
|
||||||
|
import com.willfp.eco.core.gui.menu.Menu
|
||||||
|
import com.willfp.eco.core.gui.menu.MenuLayer
|
||||||
|
import com.willfp.eco.core.gui.onClick
|
||||||
|
import com.willfp.eco.core.gui.slot
|
||||||
|
import com.willfp.eco.core.gui.slot.Slot
|
||||||
|
import com.willfp.eco.core.items.Items
|
||||||
|
import com.willfp.eco.core.placeholder.context.placeholderContext
|
||||||
|
import com.willfp.ecomenus.slots.SlotTypes
|
||||||
|
import com.willfp.libreforge.EmptyProvidedHolder
|
||||||
|
import com.willfp.libreforge.ViolationContext
|
||||||
|
import com.willfp.libreforge.conditions.Conditions
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.inventory.ClickType
|
||||||
|
|
||||||
|
class ConfigurableSlot(
|
||||||
|
private val plugin: EcoPlugin,
|
||||||
|
baseContext: ViolationContext,
|
||||||
|
private val config: Config
|
||||||
|
) : PositionedComponent {
|
||||||
|
override val row: Int = config.getInt("location.row")
|
||||||
|
override val column: Int = config.getInt("location.column")
|
||||||
|
|
||||||
|
override val layer = runCatching { enumValueOf<MenuLayer>(config.getString("layer")) }
|
||||||
|
.getOrElse { MenuLayer.MIDDLE }
|
||||||
|
|
||||||
|
val context = baseContext.with("slot at row ${row}, column $column")
|
||||||
|
|
||||||
|
private val conditions = Conditions.compile(
|
||||||
|
config.getSubsections("conditions"),
|
||||||
|
context.with("conditions")
|
||||||
|
)
|
||||||
|
|
||||||
|
private val showIfNotMet = config.getBool("show-if-not-met")
|
||||||
|
|
||||||
|
private val baseItem = Items.lookup(config.getString("item")).item
|
||||||
|
|
||||||
|
private val slot = slot({ player, _ ->
|
||||||
|
baseItem.clone().fast().apply {
|
||||||
|
if (config.has("lore")) {
|
||||||
|
this.lore = config.getFormattedStrings(
|
||||||
|
"lore", placeholderContext(
|
||||||
|
player = player
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!conditions.areMet(player, EmptyProvidedHolder)) {
|
||||||
|
this.lore = this.lore + conditions.getNotMetLines(player, EmptyProvidedHolder)
|
||||||
|
}
|
||||||
|
}.unwrap()
|
||||||
|
}) {
|
||||||
|
for (clickType in ClickType.values()) {
|
||||||
|
val section = "${clickType.name.lowercase().replace("_", "-")}-click"
|
||||||
|
val actions = config.getSubsections(section)
|
||||||
|
|
||||||
|
for (action in actions) {
|
||||||
|
val typeName = action.getString("type")
|
||||||
|
val type = SlotTypes[typeName] ?: continue
|
||||||
|
|
||||||
|
val function = type.create(
|
||||||
|
action,
|
||||||
|
plugin,
|
||||||
|
context.with("slot at row ${row}, column $column").with(section).with(typeName)
|
||||||
|
)?.toSlotAction() ?: continue
|
||||||
|
|
||||||
|
onClick(clickType, function)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSlotAt(row: Int, column: Int, player: Player, menu: Menu): Slot? {
|
||||||
|
if (!showIfNotMet && !conditions.areMet(player, EmptyProvidedHolder)) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return slot
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,9 @@ interface PositionedComponent : GUIComponent {
|
|||||||
val columnSize: Int
|
val columnSize: Int
|
||||||
get() = 1
|
get() = 1
|
||||||
|
|
||||||
|
val layer: MenuLayer
|
||||||
|
get() = MenuLayer.MIDDLE
|
||||||
|
|
||||||
override fun getRows() = rowSize
|
override fun getRows() = rowSize
|
||||||
override fun getColumns() = columnSize
|
override fun getColumns() = columnSize
|
||||||
}
|
}
|
||||||
@@ -23,16 +26,7 @@ interface PositionedComponent : GUIComponent {
|
|||||||
fun MenuBuilder.addComponent(
|
fun MenuBuilder.addComponent(
|
||||||
component: PositionedComponent
|
component: PositionedComponent
|
||||||
) = if (component.isEnabled) addComponent(
|
) = if (component.isEnabled) addComponent(
|
||||||
component.row,
|
component.layer,
|
||||||
component.column,
|
|
||||||
component
|
|
||||||
) else this
|
|
||||||
|
|
||||||
fun MenuBuilder.addComponent(
|
|
||||||
layer: MenuLayer,
|
|
||||||
component: PositionedComponent
|
|
||||||
) = if (component.isEnabled) addComponent(
|
|
||||||
layer,
|
|
||||||
component.row,
|
component.row,
|
||||||
component.column,
|
component.column,
|
||||||
component
|
component
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
package com.willfp.ecomenus.components.impl
|
|
||||||
|
|
||||||
import com.willfp.eco.core.config.interfaces.Config
|
|
||||||
import com.willfp.eco.core.gui.menu.Menu
|
|
||||||
import com.willfp.eco.core.gui.onLeftClick
|
|
||||||
import com.willfp.eco.core.gui.slot
|
|
||||||
import com.willfp.eco.core.items.Items
|
|
||||||
import com.willfp.eco.core.items.builder.ItemStackBuilder
|
|
||||||
import com.willfp.ecomenus.components.PositionedComponent
|
|
||||||
import org.bukkit.entity.Player
|
|
||||||
|
|
||||||
class BackButton(
|
|
||||||
config: Config,
|
|
||||||
goBack: (Player, Menu) -> Unit
|
|
||||||
) : PositionedComponent {
|
|
||||||
private val slot = slot(
|
|
||||||
ItemStackBuilder(Items.lookup(config.getString("item")))
|
|
||||||
.setDisplayName(config.getFormattedString("name"))
|
|
||||||
.build()
|
|
||||||
) {
|
|
||||||
onLeftClick { _, event, _, menu ->
|
|
||||||
goBack(event.whoClicked as Player, menu)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override val row: Int = config.getInt("location.row")
|
|
||||||
override val column: Int = config.getInt("location.column")
|
|
||||||
|
|
||||||
override val isEnabled = config.getBool("enabled")
|
|
||||||
|
|
||||||
override fun getSlotAt(row: Int, column: Int) = slot
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.willfp.ecomenus.components.impl
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
|
import com.willfp.eco.core.gui.menu.Menu
|
||||||
|
import com.willfp.eco.core.gui.page.PageChanger
|
||||||
|
import com.willfp.eco.core.items.Items
|
||||||
|
import com.willfp.ecomenus.components.PositionedComponent
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
|
class PositionedPageChanger(
|
||||||
|
direction: PageChanger.Direction,
|
||||||
|
config: Config,
|
||||||
|
) : PositionedComponent {
|
||||||
|
private val component = PageChanger(
|
||||||
|
Items.lookup(config.getString("item")).item,
|
||||||
|
direction
|
||||||
|
)
|
||||||
|
|
||||||
|
override val row: Int = config.getInt("location.row")
|
||||||
|
override val column: Int = config.getInt("location.column")
|
||||||
|
|
||||||
|
override val isEnabled = config.getBool("enabled")
|
||||||
|
|
||||||
|
override fun getSlotAt(row: Int, column: Int, player: Player, menu: Menu) =
|
||||||
|
component.getSlotAt(row, column, player, menu)
|
||||||
|
}
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
package com.willfp.ecomenus.config
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin
|
|
||||||
import com.willfp.eco.core.config.interfaces.Config
|
|
||||||
import com.willfp.eco.core.config.readConfig
|
|
||||||
import java.util.zip.ZipFile
|
|
||||||
|
|
||||||
abstract class ConfigCategory(
|
|
||||||
val directory: String
|
|
||||||
) {
|
|
||||||
abstract fun clear(plugin: EcoPlugin)
|
|
||||||
|
|
||||||
abstract fun acceptConfig(plugin: EcoPlugin, id: String, config: Config)
|
|
||||||
|
|
||||||
internal fun reload(plugin: EcoPlugin) {
|
|
||||||
this.clear(plugin)
|
|
||||||
|
|
||||||
for (config in this.fetchConfigs(plugin)) {
|
|
||||||
this.acceptConfig(plugin, config.id, config.config)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun copyConfigs(plugin: EcoPlugin) {
|
|
||||||
val folder = plugin.dataFolder.resolve(this.directory)
|
|
||||||
if (!folder.exists()) {
|
|
||||||
getDefaultConfigNames(plugin).forEach { configName ->
|
|
||||||
FoundConfig(configName, this.directory, plugin).copy()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getDefaultConfigNames(plugin: EcoPlugin): Collection<String> {
|
|
||||||
val files = mutableListOf<String>()
|
|
||||||
|
|
||||||
try {
|
|
||||||
ZipFile(plugin.file).use { zipFile ->
|
|
||||||
zipFile.entries().asSequence()
|
|
||||||
.filter { it.name.startsWith("${this.directory}/") }
|
|
||||||
.mapTo(files) { it.name.removePrefix("${this.directory}/") }
|
|
||||||
}
|
|
||||||
} catch (_: Exception) {
|
|
||||||
// Sometimes, ZipFile likes to completely fail. No idea why, but here's the 'solution'!
|
|
||||||
}
|
|
||||||
|
|
||||||
return files.filter { it.endsWith(".yml") }.map { it.removeSuffix(".yml") }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun fetchConfigs(plugin: EcoPlugin): Set<IdentifiedConfig> {
|
|
||||||
return plugin.dataFolder.resolve(directory)
|
|
||||||
.walk()
|
|
||||||
.filter { it.isFile && it.name.endsWith(".yml") && it.nameWithoutExtension != "_example" }
|
|
||||||
.map { file ->
|
|
||||||
val id = file.nameWithoutExtension
|
|
||||||
val config = file.readConfig()
|
|
||||||
IdentifiedConfig(config, id)
|
|
||||||
}.toSet()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package com.willfp.ecomenus.config
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin
|
|
||||||
import java.io.FileOutputStream
|
|
||||||
|
|
||||||
class FoundConfig(
|
|
||||||
name: String,
|
|
||||||
directory: String,
|
|
||||||
private val plugin: EcoPlugin
|
|
||||||
) {
|
|
||||||
private val source = plugin::class.java.classLoader
|
|
||||||
private val resourcePath = "$directory/$name.yml"
|
|
||||||
|
|
||||||
fun copy() {
|
|
||||||
val inputStream = source.getResourceAsStream(resourcePath) ?: return
|
|
||||||
val outFile = plugin.dataFolder.resolve(resourcePath)
|
|
||||||
|
|
||||||
if (!outFile.exists()) {
|
|
||||||
outFile.parentFile.mkdirs()
|
|
||||||
FileOutputStream(outFile).use { outStream ->
|
|
||||||
inputStream.copyTo(outStream)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inputStream.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
package com.willfp.ecomenus.config
|
|
||||||
|
|
||||||
import com.willfp.eco.core.config.interfaces.Config
|
|
||||||
|
|
||||||
internal data class IdentifiedConfig(
|
|
||||||
val config: Config,
|
|
||||||
val id: String
|
|
||||||
)
|
|
||||||
@@ -2,21 +2,44 @@ package com.willfp.ecomenus.menus
|
|||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin
|
import com.willfp.eco.core.EcoPlugin
|
||||||
import com.willfp.eco.core.config.interfaces.Config
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
|
import com.willfp.eco.core.gui.menu.Menu
|
||||||
import com.willfp.eco.core.registry.KRegistrable
|
import com.willfp.eco.core.registry.KRegistrable
|
||||||
import com.willfp.ecomenus.commands.DynamicMenuCommand
|
import com.willfp.ecomenus.commands.DynamicMenuCommand
|
||||||
|
import com.willfp.libreforge.EmptyProvidedHolder
|
||||||
|
import com.willfp.libreforge.ViolationContext
|
||||||
|
import com.willfp.libreforge.conditions.Conditions
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
class EcoMenu(
|
class EcoMenu(
|
||||||
private val plugin: EcoPlugin,
|
private val plugin: EcoPlugin,
|
||||||
override val id: String,
|
override val id: String,
|
||||||
val config: Config
|
val config: Config
|
||||||
) : KRegistrable {
|
) : KRegistrable {
|
||||||
val menu = buildMenu(plugin, config)
|
private val menu = buildMenu(plugin, this, config)
|
||||||
|
|
||||||
private val commandName = config.getStringOrNull("command")
|
private val commandName = config.getStringOrNull("command")
|
||||||
|
|
||||||
|
private val conditions = Conditions.compile(
|
||||||
|
config.getSubsections("conditions"),
|
||||||
|
ViolationContext(plugin, "Menu $id conditions")
|
||||||
|
)
|
||||||
|
|
||||||
|
private val cannotOpenMessages = config.getFormattedStrings("cannot-open-messages")
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (commandName != null) {
|
if (commandName != null) {
|
||||||
DynamicMenuCommand(plugin, this, commandName).register()
|
DynamicMenuCommand(plugin, this, commandName).register()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun open(player: Player, parent: Menu? = null) {
|
||||||
|
if (!conditions.areMet(player, EmptyProvidedHolder)) {
|
||||||
|
for (message in cannotOpenMessages) {
|
||||||
|
player.sendMessage(message)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.open(player, parent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
package com.willfp.ecomenus.menus
|
package com.willfp.ecomenus.menus
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin
|
|
||||||
import com.willfp.eco.core.config.interfaces.Config
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
import com.willfp.eco.core.registry.Registry
|
import com.willfp.eco.core.registry.Registry
|
||||||
import com.willfp.ecomenus.config.ConfigCategory
|
import com.willfp.libreforge.loader.LibreforgePlugin
|
||||||
|
import com.willfp.libreforge.loader.configs.ConfigCategory
|
||||||
|
|
||||||
object EcoMenus : ConfigCategory("menus") {
|
object EcoMenus : ConfigCategory("menu", "menus") {
|
||||||
private val registry = Registry<EcoMenu>()
|
private val registry = Registry<EcoMenu>()
|
||||||
|
|
||||||
override fun clear(plugin: EcoPlugin) {
|
override fun clear(plugin: LibreforgePlugin) {
|
||||||
registry.clear()
|
registry.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun acceptConfig(plugin: EcoPlugin, id: String, config: Config) {
|
override fun acceptConfig(plugin: LibreforgePlugin, id: String, config: Config) {
|
||||||
registry.register(EcoMenu(plugin, id, config))
|
registry.register(EcoMenu(plugin, id, config))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,15 +2,19 @@ package com.willfp.ecomenus.menus
|
|||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin
|
import com.willfp.eco.core.EcoPlugin
|
||||||
import com.willfp.eco.core.config.interfaces.Config
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
|
import com.willfp.eco.core.gui.addPage
|
||||||
import com.willfp.eco.core.gui.menu
|
import com.willfp.eco.core.gui.menu
|
||||||
import com.willfp.eco.core.gui.menu.Menu
|
import com.willfp.eco.core.gui.menu.Menu
|
||||||
import com.willfp.eco.core.gui.slot.ConfigSlot
|
import com.willfp.eco.core.gui.page.PageChanger
|
||||||
import com.willfp.eco.core.gui.slot.FillerMask
|
import com.willfp.eco.core.gui.slot.FillerMask
|
||||||
import com.willfp.eco.core.gui.slot.MaskItems
|
import com.willfp.eco.core.gui.slot.MaskItems
|
||||||
|
import com.willfp.ecomenus.components.ConfigurableSlot
|
||||||
|
import com.willfp.ecomenus.components.PositionedComponent
|
||||||
import com.willfp.ecomenus.components.addComponent
|
import com.willfp.ecomenus.components.addComponent
|
||||||
import com.willfp.ecomenus.components.impl.BackButton
|
import com.willfp.ecomenus.components.impl.PositionedPageChanger
|
||||||
import com.willfp.ecomenus.components.impl.CloseButton
|
|
||||||
import com.willfp.ecomponent.menuStateVar
|
import com.willfp.ecomponent.menuStateVar
|
||||||
|
import com.willfp.libreforge.ConfigViolation
|
||||||
|
import com.willfp.libreforge.ViolationContext
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import java.util.Stack
|
import java.util.Stack
|
||||||
|
|
||||||
@@ -32,7 +36,7 @@ fun Menu.open(
|
|||||||
fun Menu.close(player: Player) =
|
fun Menu.close(player: Player) =
|
||||||
this.previousMenus[player].popOrNull()?.open(player) ?: player.closeInventory()
|
this.previousMenus[player].popOrNull()?.open(player) ?: player.closeInventory()
|
||||||
|
|
||||||
fun buildMenu(plugin: EcoPlugin, config: Config): Menu {
|
fun buildMenu(plugin: EcoPlugin, menu: EcoMenu, config: Config): Menu {
|
||||||
val mask = FillerMask(
|
val mask = FillerMask(
|
||||||
MaskItems.fromItemNames(config.getStrings("mask.materials")),
|
MaskItems.fromItemNames(config.getStrings("mask.materials")),
|
||||||
*config.getStrings("mask.pattern").toTypedArray()
|
*config.getStrings("mask.pattern").toTypedArray()
|
||||||
@@ -44,26 +48,35 @@ fun buildMenu(plugin: EcoPlugin, config: Config): Menu {
|
|||||||
setMask(mask)
|
setMask(mask)
|
||||||
|
|
||||||
addComponent(
|
addComponent(
|
||||||
CloseButton(
|
PositionedPageChanger(
|
||||||
plugin.configYml.getSubsection("stats-gui.close")
|
PageChanger.Direction.FORWARDS,
|
||||||
|
config.getSubsection("forwards-arrow")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
addComponent(
|
addComponent(
|
||||||
BackButton(
|
PositionedPageChanger(
|
||||||
plugin.configYml.getSubsection("stats-gui.back")
|
PageChanger.Direction.BACKWARDS,
|
||||||
) { player, menu ->
|
config.getSubsection("backwards-arrow")
|
||||||
menu.close(player)
|
)
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Implement Slots
|
for (page in config.getSubsections("pages")) {
|
||||||
for (test in plugin.configYml.getSubsections("stats-gui.custom-slots")) {
|
addPage(page.getInt("page")) {
|
||||||
setSlot(
|
for (slotConfig in config.getSubsections("slots")) {
|
||||||
test.getInt("row"),
|
val slot = ConfigurableSlot(
|
||||||
test.getInt("column"),
|
plugin,
|
||||||
ConfigSlot(test)
|
ViolationContext(plugin, "menu ${menu.id}"),
|
||||||
)
|
slotConfig
|
||||||
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
addComponent(slot)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
slot.context.log(ConfigViolation("location", "The location of the slot is invalid!"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.willfp.ecomenus.slots
|
||||||
|
|
||||||
|
import com.willfp.eco.core.gui.menu.Menu
|
||||||
|
import com.willfp.eco.core.gui.slot.Slot
|
||||||
|
import com.willfp.ecomponent.SlotAction
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent
|
||||||
|
|
||||||
|
interface SlotFunction {
|
||||||
|
fun execute(player: Player, event: InventoryClickEvent, slot: Slot, menu: Menu)
|
||||||
|
|
||||||
|
fun toSlotAction(): SlotAction = this::execute
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.willfp.ecomenus.slots
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
|
import com.willfp.eco.core.gui.slot.SlotBuilder
|
||||||
|
import com.willfp.eco.core.registry.KRegistrable
|
||||||
|
import com.willfp.ecomponent.SlotAction
|
||||||
|
import com.willfp.libreforge.ViolationContext
|
||||||
|
|
||||||
|
abstract class SlotType(override val id: String) : KRegistrable {
|
||||||
|
abstract fun create(config: Config, plugin: EcoPlugin, context: ViolationContext): SlotFunction?
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.willfp.ecomenus.slots
|
||||||
|
|
||||||
|
import com.willfp.eco.core.registry.Registry
|
||||||
|
import com.willfp.ecomenus.slots.impl.SlotTypeClose
|
||||||
|
import com.willfp.ecomenus.slots.impl.SlotTypeCommand
|
||||||
|
import com.willfp.ecomenus.slots.impl.SlotTypeConsoleCommand
|
||||||
|
import com.willfp.ecomenus.slots.impl.SlotTypeEffects
|
||||||
|
import com.willfp.ecomenus.slots.impl.SlotTypeMenu
|
||||||
|
|
||||||
|
object SlotTypes : Registry<SlotType>() {
|
||||||
|
init {
|
||||||
|
register(SlotTypeCommand)
|
||||||
|
register(SlotTypeConsoleCommand)
|
||||||
|
register(SlotTypeMenu)
|
||||||
|
register(SlotTypeClose)
|
||||||
|
register(SlotTypeEffects)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.willfp.ecomenus.slots.impl
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
|
import com.willfp.eco.core.gui.menu.Menu
|
||||||
|
import com.willfp.eco.core.gui.slot.Slot
|
||||||
|
import com.willfp.ecomenus.menus.EcoMenu
|
||||||
|
import com.willfp.ecomenus.menus.EcoMenus
|
||||||
|
import com.willfp.ecomenus.menus.close
|
||||||
|
import com.willfp.ecomenus.menus.open
|
||||||
|
import com.willfp.ecomenus.slots.SlotFunction
|
||||||
|
import com.willfp.ecomenus.slots.SlotType
|
||||||
|
import com.willfp.libreforge.ViolationContext
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent
|
||||||
|
|
||||||
|
object SlotTypeClose : SlotType("close") {
|
||||||
|
override fun create(config: Config, plugin: EcoPlugin, context: ViolationContext): SlotFunction {
|
||||||
|
return object : SlotFunction {
|
||||||
|
override fun execute(player: Player, event: InventoryClickEvent, slot: Slot, menu: Menu) {
|
||||||
|
menu.close(player)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.willfp.ecomenus.slots.impl
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
|
import com.willfp.eco.core.gui.menu.Menu
|
||||||
|
import com.willfp.eco.core.gui.slot.Slot
|
||||||
|
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
|
||||||
|
import com.willfp.eco.core.placeholder.context.placeholderContext
|
||||||
|
import com.willfp.ecomenus.slots.SlotFunction
|
||||||
|
import com.willfp.ecomenus.slots.SlotType
|
||||||
|
import com.willfp.libreforge.ViolationContext
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.command.CommandSender
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent
|
||||||
|
|
||||||
|
object SlotTypeCommand : SlotType("command") {
|
||||||
|
override fun create(config: Config, plugin: EcoPlugin, context: ViolationContext): SlotFunction {
|
||||||
|
val commands = config.getStrings("commands")
|
||||||
|
|
||||||
|
return CommandSlotFunction(commands)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CommandSlotFunction(
|
||||||
|
private val commands: List<String>,
|
||||||
|
private val sender: CommandSender? = null
|
||||||
|
) : SlotFunction {
|
||||||
|
override fun execute(player: Player, event: InventoryClickEvent, slot: Slot, menu: Menu) {
|
||||||
|
for (command in commands) {
|
||||||
|
Bukkit.dispatchCommand(
|
||||||
|
sender ?: player,
|
||||||
|
PlaceholderManager.translatePlaceholders(
|
||||||
|
command, placeholderContext(
|
||||||
|
player = player
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.willfp.ecomenus.slots.impl
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
|
import com.willfp.eco.core.gui.menu.Menu
|
||||||
|
import com.willfp.eco.core.gui.slot.Slot
|
||||||
|
import com.willfp.ecomenus.slots.SlotFunction
|
||||||
|
import com.willfp.ecomenus.slots.SlotType
|
||||||
|
import com.willfp.libreforge.ViolationContext
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent
|
||||||
|
|
||||||
|
object SlotTypeConsoleCommand : SlotType("console_command") {
|
||||||
|
override fun create(config: Config, plugin: EcoPlugin, context: ViolationContext): SlotFunction {
|
||||||
|
val commands = config.getStrings("commands")
|
||||||
|
|
||||||
|
return CommandSlotFunction(commands, Bukkit.getConsoleSender())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package com.willfp.ecomenus.slots.impl
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
|
import com.willfp.eco.core.gui.menu.Menu
|
||||||
|
import com.willfp.eco.core.gui.slot.Slot
|
||||||
|
import com.willfp.ecomenus.slots.SlotFunction
|
||||||
|
import com.willfp.ecomenus.slots.SlotType
|
||||||
|
import com.willfp.libreforge.ViolationContext
|
||||||
|
import com.willfp.libreforge.effects.Chain
|
||||||
|
import com.willfp.libreforge.effects.Effects
|
||||||
|
import com.willfp.libreforge.effects.executors.ChainExecutors
|
||||||
|
import com.willfp.libreforge.triggers.DispatchedTrigger
|
||||||
|
import com.willfp.libreforge.triggers.Trigger
|
||||||
|
import com.willfp.libreforge.triggers.TriggerData
|
||||||
|
import com.willfp.libreforge.triggers.TriggerParameter
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent
|
||||||
|
|
||||||
|
object SlotTypeEffects : SlotType("effects") {
|
||||||
|
override fun create(config: Config, plugin: EcoPlugin, context: ViolationContext): SlotFunction? {
|
||||||
|
val chain = Effects.compileChain(
|
||||||
|
config.getSubsections("effects"),
|
||||||
|
ChainExecutors.getByID(config.getString("run-type")),
|
||||||
|
context
|
||||||
|
) ?: return null
|
||||||
|
|
||||||
|
return SlotFunctionEffects(chain)
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SlotFunctionEffects(
|
||||||
|
private val chain: Chain
|
||||||
|
) : SlotFunction {
|
||||||
|
override fun execute(player: Player, event: InventoryClickEvent, slot: Slot, menu: Menu) {
|
||||||
|
chain.trigger(
|
||||||
|
DispatchedTrigger(
|
||||||
|
player,
|
||||||
|
TriggerClickSlot,
|
||||||
|
TriggerData(
|
||||||
|
player = player
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private object TriggerClickSlot : Trigger("click_slot") {
|
||||||
|
override val parameters = setOf(
|
||||||
|
TriggerParameter.PLAYER
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.willfp.ecomenus.slots.impl
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
|
import com.willfp.eco.core.gui.menu.Menu
|
||||||
|
import com.willfp.eco.core.gui.slot.Slot
|
||||||
|
import com.willfp.ecomenus.menus.EcoMenu
|
||||||
|
import com.willfp.ecomenus.menus.EcoMenus
|
||||||
|
import com.willfp.ecomenus.menus.open
|
||||||
|
import com.willfp.ecomenus.slots.SlotFunction
|
||||||
|
import com.willfp.ecomenus.slots.SlotType
|
||||||
|
import com.willfp.libreforge.ViolationContext
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent
|
||||||
|
|
||||||
|
object SlotTypeMenu : SlotType("menu") {
|
||||||
|
override fun create(config: Config, plugin: EcoPlugin, context: ViolationContext): SlotFunction? {
|
||||||
|
val ecoMenu = EcoMenus[config.getString("menu")] ?: return null
|
||||||
|
|
||||||
|
return object : SlotFunction {
|
||||||
|
override fun execute(player: Player, event: InventoryClickEvent, slot: Slot, menu: Menu) {
|
||||||
|
ecoMenu.open(player, menu)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
|
environment:
|
||||||
|
- name: libreforge version
|
||||||
|
value: ${libreforgeVersion}
|
||||||
|
|
||||||
options:
|
options:
|
||||||
bstats-id: 0
|
bstats-id: 0
|
||||||
resource-id: 0
|
resource-id: 0
|
||||||
|
|||||||
@@ -1,13 +1,20 @@
|
|||||||
|
# The ID of the menu is the name of the .yml file,
|
||||||
|
# for example help.yml has the ID of help
|
||||||
|
# You can place menus anywhere in this folder,
|
||||||
|
# including in subfolders if you want to organize your menu configs
|
||||||
|
# _example.yml is not loaded.
|
||||||
|
|
||||||
# The title of the GUI
|
# The title of the GUI
|
||||||
title: "Example GUI"
|
title: "Example GUI"
|
||||||
|
|
||||||
command: examplemenu # (Optional) The command to open the GUI, if not set, there will be no command.
|
# (Optional) The command to open the GUI, if not set, there will be no command.
|
||||||
|
command: examplemenu
|
||||||
|
|
||||||
mask:
|
mask:
|
||||||
# The way the mask works is by having a list of materials
|
# The way the mask works is by having a list of materials
|
||||||
# And then a pattern to use those materials.
|
# And then a pattern to use those materials.
|
||||||
|
|
||||||
# The size of the GUI is the size of the mask.
|
# The size of the GUI is determined by the size of the mask.
|
||||||
|
|
||||||
# The pattern is the rows in the GUI
|
# The pattern is the rows in the GUI
|
||||||
# Each line must be 9 long, and the amount of rows should be the amount of rows in the GUI
|
# Each line must be 9 long, and the amount of rows should be the amount of rows in the GUI
|
||||||
@@ -27,14 +34,66 @@ mask:
|
|||||||
- "211111112"
|
- "211111112"
|
||||||
- "211101112"
|
- "211101112"
|
||||||
|
|
||||||
# Options for the close item
|
|
||||||
close:
|
|
||||||
item: barrier
|
|
||||||
name: "&cClose"
|
|
||||||
enabled: false
|
|
||||||
location:
|
|
||||||
row: 6
|
|
||||||
column: 5
|
|
||||||
|
|
||||||
# Custom GUI slots; see here for a how-to: https://plugins.auxilor.io/all-plugins/custom-gui-slots
|
# Read https://plugins.auxilor.io/effects/configuring-a-condition
|
||||||
custom-slots: [ ]
|
# The conditions required to open the GUI
|
||||||
|
conditions: [ ]
|
||||||
|
|
||||||
|
# The messages to send when the conditions are not met
|
||||||
|
cannot-open-messages:
|
||||||
|
- "&cYou cannot open this menu!"
|
||||||
|
|
||||||
|
# Options for the page arrows
|
||||||
|
# If on the first page, the backwards arrow will not be shown,
|
||||||
|
# and if on the last page, the forwards arrow will not be shown.
|
||||||
|
forwards-arrow:
|
||||||
|
item: arrow name:"&fNext Page"
|
||||||
|
enabled: true
|
||||||
|
location:
|
||||||
|
row: 3
|
||||||
|
column: 6
|
||||||
|
|
||||||
|
backwards-arrow:
|
||||||
|
item: arrow name:"&fPrevious Page"
|
||||||
|
enabled: true
|
||||||
|
location:
|
||||||
|
row: 3
|
||||||
|
column: 4
|
||||||
|
|
||||||
|
pages:
|
||||||
|
- page: 1
|
||||||
|
slots:
|
||||||
|
- item: barrier name:"&cClose"
|
||||||
|
lore: [ ]
|
||||||
|
location:
|
||||||
|
row: 6
|
||||||
|
column: 5
|
||||||
|
# (Optional) You can specify the layer of the slot.
|
||||||
|
# The layer can be any of: lower, middle, upper, or top (defaults to middle)
|
||||||
|
# This is useful if you want to have a slot on top of another slot, and
|
||||||
|
# have the upper slot show if some conditions are met.
|
||||||
|
layer: middle
|
||||||
|
|
||||||
|
# Read https://plugins.auxilor.io/effects/configuring-a-condition
|
||||||
|
# The conditions required to click the item
|
||||||
|
conditions: [ ]
|
||||||
|
|
||||||
|
# If the item should be shown if the conditions are not met
|
||||||
|
show-if-not-met: true
|
||||||
|
|
||||||
|
left-click:
|
||||||
|
- type: effects
|
||||||
|
effects:
|
||||||
|
- id: send_message
|
||||||
|
args:
|
||||||
|
message: "&cYou clicked the close button!"
|
||||||
|
|
||||||
|
- type: command
|
||||||
|
commands: [ ]
|
||||||
|
|
||||||
|
- type: menu
|
||||||
|
menu: other_example_menu
|
||||||
|
|
||||||
|
- item: console_command
|
||||||
|
commands:
|
||||||
|
- "eco give %player% 100"
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ dependencies:
|
|||||||
required: true
|
required: true
|
||||||
bootstrap: false
|
bootstrap: false
|
||||||
|
|
||||||
|
- name: libreforge
|
||||||
|
required: false
|
||||||
|
bootstrap: false
|
||||||
|
|
||||||
load-after:
|
load-after:
|
||||||
- name: eco
|
- name: eco
|
||||||
bootstrap: false
|
bootstrap: false
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ website: willfp.com
|
|||||||
load: STARTUP
|
load: STARTUP
|
||||||
depend:
|
depend:
|
||||||
- eco
|
- eco
|
||||||
|
softdepend:
|
||||||
|
- libreforge
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
ecomenus:
|
ecomenus:
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
|
#libreforge-updater
|
||||||
|
#Sat Jun 03 15:45:10 BST 2023
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
version=1.0.0
|
libreforge-version=4.17.2
|
||||||
|
version=1.0.0
|
||||||
Reference in New Issue
Block a user