diff --git a/build.gradle b/build.gradle index 89892e777..870e775ac 100644 --- a/build.gradle +++ b/build.gradle @@ -822,6 +822,42 @@ project(":bukkit:rpk-skill-lib-bukkit") { } +project(":bukkit:rpk-class-lib-bukkit") { + + dependencies { + compile project(":bukkit:rpk-core-bukkit") + compile project(":bukkit:rpk-character-lib-bukkit") + compile project(":bukkit:rpk-stat-lib-bukkit") + compile project(":bukkit:rpk-skill-lib-bukkit") + compile project(":bukkit:rpk-experience-lib-bukkit") + } + + processResources { + filter ReplaceTokens, tokens: [ + "version": version + ] + } + + artifacts { + archives jar + } + + uploadArchives { + repositories.mavenDeployer { + + repository(url: "https://repo.seventh-root.com/artifactory/libs-release-local/") { + authentication(userName: repoUserName, password: repoPassword) + } + + pom.version = project(":bukkit:rpk-class-lib-bukkit").version + pom.artifactId = project(":bukkit:rpk-class-lib-bukkit").name + pom.groupId = project(":bukkit:rpk-class-lib-bukkit").group + + } + } + +} + // Bukkit implementations project(":bukkit:rpk-players-bukkit") { @@ -1466,9 +1502,52 @@ project(":bukkit:rpk-skills-bukkit") { uploadArchives { repositories.mavenDeployer { + repository(url: "https://repo.seventh-root.com/artifactory/libs-release-local/") { authentication(userName: repoUserName, password: repoPassword) } + + pom.version = project(":bukkit:rpk-skills-bukkit").version + pom.artifactId = project(":bukkit:rpk-skills-bukkit").name + pom.groupId = project(":bukkit:rpk-skills-bukkit").group + } + + } + +} + +project(":bukkit:rpk-classes-bukkit") { + + dependencies { + compile project(":bukkit:rpk-core-bukkit") + compile project(":bukkit:rpk-character-lib-bukkit") + compile project(":bukkit:rpk-stat-lib-bukkit") + compile project(":bukkit:rpk-skill-lib-bukkit") + compile project(":bukkit:rpk-experience-lib-bukkit") + compile project(":bukkit:rpk-class-lib-bukkit") + } + + processResources { + filter ReplaceTokens, tokens: [ + "version": version + ] + } + + artifacts { + archives jar + } + + uploadArchives { + repositories.mavenDeployer { + + repository(url: "https://repo.seventh-root.com/artifactory/libs-release-local/") { + authentication(userName: repoUserName, password: repoPassword) + } + + pom.version = project(":bukkit:rpk-classes-bukkit").version + pom.artifactId = project(":bukkit:rpk-classes-bukkit").name + pom.groupId = project(":bukkit:rpk-classes-bukkit").group + } } diff --git a/bukkit/rpk-class-lib-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/RPKClassLibBukkit.kt b/bukkit/rpk-class-lib-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/RPKClassLibBukkit.kt new file mode 100644 index 000000000..69ffd7f51 --- /dev/null +++ b/bukkit/rpk-class-lib-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/RPKClassLibBukkit.kt @@ -0,0 +1,10 @@ +package com.rpkit.classes.bukkit + +import com.rpkit.core.bukkit.plugin.RPKBukkitPlugin + + +class RPKClassLibBukkit: RPKBukkitPlugin() { + + + +} \ No newline at end of file diff --git a/bukkit/rpk-class-lib-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/classes/RPKClass.kt b/bukkit/rpk-class-lib-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/classes/RPKClass.kt new file mode 100644 index 000000000..1bb3e1c71 --- /dev/null +++ b/bukkit/rpk-class-lib-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/classes/RPKClass.kt @@ -0,0 +1,14 @@ +package com.rpkit.classes.bukkit.classes + +import com.rpkit.characters.bukkit.character.RPKCharacter +import com.rpkit.skills.bukkit.skills.RPKSkillType + + +interface RPKClass { + + val name: String + val maxLevel: Int + fun hasPrerequisites(character: RPKCharacter): Boolean + fun getSkillPoints(skillType: RPKSkillType, level: Int): Int + +} \ No newline at end of file diff --git a/bukkit/rpk-class-lib-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/classes/RPKClassProvider.kt b/bukkit/rpk-class-lib-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/classes/RPKClassProvider.kt new file mode 100644 index 000000000..e33b51fb7 --- /dev/null +++ b/bukkit/rpk-class-lib-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/classes/RPKClassProvider.kt @@ -0,0 +1,18 @@ +package com.rpkit.classes.bukkit.classes + +import com.rpkit.characters.bukkit.character.RPKCharacter +import com.rpkit.core.service.ServiceProvider + + +interface RPKClassProvider: ServiceProvider { + + val classes: List + fun getClass(name: String): RPKClass? + fun getClass(character: RPKCharacter): RPKClass? + fun setClass(character: RPKCharacter, clazz: RPKClass) + fun getLevel(character: RPKCharacter, clazz: RPKClass): Int + fun setLevel(character: RPKCharacter, clazz: RPKClass, level: Int) + fun getExperience(character: RPKCharacter, clazz: RPKClass): Int + fun setExperience(character: RPKCharacter, clazz: RPKClass, experience: Int) + +} \ No newline at end of file diff --git a/bukkit/rpk-class-lib-bukkit/src/main/resources/plugin.yml b/bukkit/rpk-class-lib-bukkit/src/main/resources/plugin.yml new file mode 100644 index 000000000..3c2cc7604 --- /dev/null +++ b/bukkit/rpk-class-lib-bukkit/src/main/resources/plugin.yml @@ -0,0 +1,10 @@ +name: rpk-class-lib-bukkit +version: @version@ +author: alyphen +main: com.rpkit.classes.bukkit.RPKClassLibBukkit +depend: +- rpk-core-bukkit +- rpk-character-lib-bukkit +- rpk-stat-lib-bukkit +- rpk-skill-lib-bukkit +- rpk-experience-lib-bukkit \ No newline at end of file diff --git a/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/RPKClassesBukkit.kt b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/RPKClassesBukkit.kt new file mode 100644 index 000000000..7a99a63b7 --- /dev/null +++ b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/RPKClassesBukkit.kt @@ -0,0 +1,106 @@ +package com.rpkit.classes.bukkit + +import com.rpkit.characters.bukkit.character.RPKCharacter +import com.rpkit.characters.bukkit.character.field.RPKCharacterCardFieldProvider +import com.rpkit.classes.bukkit.character.ClassField +import com.rpkit.classes.bukkit.classes.RPKClass +import com.rpkit.classes.bukkit.classes.RPKClassProvider +import com.rpkit.classes.bukkit.classes.RPKClassProviderImpl +import com.rpkit.classes.bukkit.command.`class`.ClassCommand +import com.rpkit.classes.bukkit.database.table.RPKCharacterClassTable +import com.rpkit.classes.bukkit.database.table.RPKClassExperienceTable +import com.rpkit.classes.bukkit.listener.PluginEnableListener +import com.rpkit.core.bukkit.plugin.RPKBukkitPlugin +import com.rpkit.core.database.Database +import com.rpkit.core.exception.UnregisteredServiceException +import com.rpkit.stats.bukkit.stat.RPKStatVariable +import com.rpkit.stats.bukkit.stat.RPKStatVariableProvider + + +class RPKClassesBukkit: RPKBukkitPlugin() { + + private var statsInitialized = false + private var characterCardFieldsInitialized = false + + override fun onEnable() { + saveDefaultConfig() + serviceProviders = arrayOf( + RPKClassProviderImpl(this) + ) + } + + override fun onPostEnable() { + attemptStatRegistration() + attemptCharacterCardFieldRegistration() + } + + override fun registerCommands() { + getCommand("class").executor = ClassCommand(this) + } + + override fun registerListeners() { + registerListeners( + PluginEnableListener(this) + ) + } + + override fun createTables(database: Database) { + database.addTable(RPKCharacterClassTable(database, this)) + database.addTable(RPKClassExperienceTable(database, this)) + } + + override fun setDefaultMessages() { + messages.setDefault("class-usage", "&cUsage: /class [set|list]") + messages.setDefault("no-permission-class-set", "&cYou do not have permission to set your class.") + messages.setDefault("class-set-usage", "&cUsage: /class set [class]") + messages.setDefault("not-from-console", "&cYou must be a player to perform this command.") + messages.setDefault("no-character", "&cYou require a character to perform that command.") + messages.setDefault("class-set-invalid-class", "&cThat class is invalid.") + messages.setDefault("class-set-invalid-prerequisites", "&cYou do not have the prerequisites for that class.") + messages.setDefault("class-set-valid", "&aClass set to \$class.") + messages.setDefault("no-permission-class-list", "&cYou do not have permission to list classes.") + messages.setDefault("class-list-title", "&fClasses:") + messages.setDefault("class-list-item", "&f- &7\$class") + } + + fun attemptStatRegistration() { + if (statsInitialized) return + try { + val statVariableProvider = core.serviceManager.getServiceProvider(RPKStatVariableProvider::class) + val classProvider = core.serviceManager.getServiceProvider(RPKClassProvider::class) + statVariableProvider.addStatVariable(object: RPKStatVariable { + + override val name = "classLevels" + + override fun get(character: RPKCharacter): Map? { + return classProvider.classes + .map { clazz -> + Pair(clazz, classProvider.getLevel(character, clazz)) + } + .toMap() + } + + }) + statVariableProvider.addStatVariable(object: RPKStatVariable { + + override val name = "clazz" + + override fun get(character: RPKCharacter): Any? { + return classProvider.getClass(character) + } + + }) + statsInitialized = true + } catch (ignore: UnregisteredServiceException) {} + } + + fun attemptCharacterCardFieldRegistration() { + if (characterCardFieldsInitialized) return + try { + val characterCardFieldProvider = core.serviceManager.getServiceProvider(RPKCharacterCardFieldProvider::class) + characterCardFieldProvider.characterCardFields.add(ClassField(this)) + characterCardFieldsInitialized = true + } catch (ignore: UnregisteredServiceException) {} + } + +} \ No newline at end of file diff --git a/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/character/ClassField.kt b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/character/ClassField.kt new file mode 100644 index 000000000..356cf9d6e --- /dev/null +++ b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/character/ClassField.kt @@ -0,0 +1,17 @@ +package com.rpkit.classes.bukkit.character + +import com.rpkit.characters.bukkit.character.RPKCharacter +import com.rpkit.characters.bukkit.character.field.CharacterCardField +import com.rpkit.classes.bukkit.RPKClassesBukkit +import com.rpkit.classes.bukkit.classes.RPKClassProvider + + +class ClassField(private val plugin: RPKClassesBukkit): CharacterCardField { + + override val name = "class" + + override fun get(character: RPKCharacter): String { + return plugin.core.serviceManager.getServiceProvider(RPKClassProvider::class).getClass(character)?.name?:"unset" + } + +} \ No newline at end of file diff --git a/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/classes/RPKCharacterClass.kt b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/classes/RPKCharacterClass.kt new file mode 100644 index 000000000..3420939bd --- /dev/null +++ b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/classes/RPKCharacterClass.kt @@ -0,0 +1,11 @@ +package com.rpkit.classes.bukkit.classes + +import com.rpkit.characters.bukkit.character.RPKCharacter +import com.rpkit.core.database.Entity + + +class RPKCharacterClass( + override var id: Int = 0, + val character: RPKCharacter, + var clazz: RPKClass +) : Entity \ No newline at end of file diff --git a/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/classes/RPKClassExperience.kt b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/classes/RPKClassExperience.kt new file mode 100644 index 000000000..b95705ce8 --- /dev/null +++ b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/classes/RPKClassExperience.kt @@ -0,0 +1,12 @@ +package com.rpkit.classes.bukkit.classes + +import com.rpkit.characters.bukkit.character.RPKCharacter +import com.rpkit.core.database.Entity + + +class RPKClassExperience( + override var id: Int = 0, + val character: RPKCharacter, + val clazz: RPKClass, + var experience: Int +) : Entity \ No newline at end of file diff --git a/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/classes/RPKClassImpl.kt b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/classes/RPKClassImpl.kt new file mode 100644 index 000000000..08d426280 --- /dev/null +++ b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/classes/RPKClassImpl.kt @@ -0,0 +1,62 @@ +package com.rpkit.classes.bukkit.classes + +import com.rpkit.characters.bukkit.character.RPKCharacter +import com.rpkit.classes.bukkit.RPKClassesBukkit +import com.rpkit.skills.bukkit.skills.RPKSkillType +import com.rpkit.skills.bukkit.skills.RPKSkillTypeProvider + + +class RPKClassImpl( + private val plugin: RPKClassesBukkit, + override val name: String, + override val maxLevel: Int, + private val prerequisitesByName: Map, + private val baseSkillPointsByName: Map, + private val levelSkillPointsByName: Map +) : RPKClass { + + val prerequisites: Map + get() = prerequisitesByName + .map { entry -> + Pair( + plugin.core.serviceManager.getServiceProvider(RPKClassProvider::class).getClass(entry.key)!!, + entry.value + ) + } + .toMap() + + val baseSkillPoints: Map + get() = baseSkillPointsByName + .map { entry -> + Pair( + plugin.core.serviceManager.getServiceProvider(RPKSkillTypeProvider::class).getSkillType(entry.key)!!, + entry.value + ) + } + .toMap() + + val levelSkillPoints: Map + get() = levelSkillPointsByName + .map { entry -> + Pair( + plugin.core.serviceManager.getServiceProvider(RPKSkillTypeProvider::class).getSkillType(entry.key)!!, + entry.value + ) + } + .toMap() + + override fun hasPrerequisites(character: RPKCharacter): Boolean { + val classProvider = plugin.core.serviceManager.getServiceProvider(RPKClassProvider::class) + for ((clazz, level) in prerequisites) { + if (classProvider.getLevel(character, clazz) < level) { + return false + } + } + return true + } + + override fun getSkillPoints(skillType: RPKSkillType, level: Int): Int { + return baseSkillPoints[skillType]?:0 + (levelSkillPoints[skillType]?:0 * level) + } + +} \ No newline at end of file diff --git a/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/classes/RPKClassProviderImpl.kt b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/classes/RPKClassProviderImpl.kt new file mode 100644 index 000000000..da133c14f --- /dev/null +++ b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/classes/RPKClassProviderImpl.kt @@ -0,0 +1,150 @@ +package com.rpkit.classes.bukkit.classes + +import com.rpkit.characters.bukkit.character.RPKCharacter +import com.rpkit.classes.bukkit.RPKClassesBukkit +import com.rpkit.classes.bukkit.database.table.RPKCharacterClassTable +import com.rpkit.classes.bukkit.database.table.RPKClassExperienceTable +import com.rpkit.experience.bukkit.experience.RPKExperienceProvider + + +class RPKClassProviderImpl(private val plugin: RPKClassesBukkit): RPKClassProvider { + + override val classes: List = plugin.config.getConfigurationSection("classes").getKeys(false) + .map { className -> + RPKClassImpl( + plugin, + className, + plugin.config.getInt("classes.$className.max-level"), + plugin.config.getConfigurationSection("classes.$className.prerequisites") + ?.getKeys(false) + ?.map { prerequisiteClassName -> + Pair( + prerequisiteClassName, + plugin.config.getInt("classes.$className.prerequisites.$prerequisiteClassName") + ) + } + ?.toMap() + ?:mapOf(), + plugin.config.getConfigurationSection("classes.$className.skill-points.base") + .getKeys(false) + .map { skillTypeName -> + Pair( + skillTypeName, + plugin.config.getInt("classes.$className.skill-points.base.$skillTypeName") + ) + } + .toMap(), + plugin.config.getConfigurationSection("classes.$className.skill-points.level") + .getKeys(false) + .map { skillTypeName -> + Pair( + skillTypeName, + plugin.config.getInt("classes.$className.skill-points.level.$skillTypeName") + ) + } + .toMap() + ) + } + + override fun getClass(name: String): RPKClass? { + return classes.filter { it.name.equals(name, ignoreCase = true) }.firstOrNull() + } + + override fun getClass(character: RPKCharacter): RPKClass? { + return plugin.core.database.getTable(RPKCharacterClassTable::class).get(character)?.clazz + } + + override fun setClass(character: RPKCharacter, clazz: RPKClass) { + // Update experience in the class the character is being switched from + val experienceProvider = plugin.core.serviceManager.getServiceProvider(RPKExperienceProvider::class) + val oldClass = getClass(character) + if (oldClass != null) { + val experience = experienceProvider.getExperience(character) + val classExperienceTable = plugin.core.database.getTable(RPKClassExperienceTable::class) + var classExperience = classExperienceTable.get(character, oldClass) + if (classExperience == null) { + classExperience = RPKClassExperience( + character = character, + clazz = oldClass, + experience = experience + ) + classExperienceTable.insert(classExperience) + } else { + classExperience.experience = experience + classExperienceTable.update(classExperience) + } + } + + // Update experience in the experience provider to that of the new class + experienceProvider.setExperience(character, getExperience(character, clazz)) + + // Update database with new class + val characterClassTable = plugin.core.database.getTable(RPKCharacterClassTable::class) + var characterClass = characterClassTable.get(character) + if (characterClass == null) { + characterClass = RPKCharacterClass( + character = character, + clazz = clazz + ) + characterClassTable.insert(characterClass) + } else { + characterClass.clazz = clazz + characterClassTable.update(characterClass) + } + } + + override fun getLevel(character: RPKCharacter, clazz: RPKClass): Int { + val experienceProvider = plugin.core.serviceManager.getServiceProvider(RPKExperienceProvider::class) + if (clazz == getClass(character)) { + return experienceProvider.getLevel(character) + } else { + val experience = getExperience(character, clazz) + var level = 1 + while (level + 1 <= clazz.maxLevel && experienceProvider.getExperienceNeededForLevel(level + 1) <= experience) { + level++ + } + return level + } + } + + override fun setLevel(character: RPKCharacter, clazz: RPKClass, level: Int) { + val experienceProvider = plugin.core.serviceManager.getServiceProvider(RPKExperienceProvider::class) + if (clazz == getClass(character)) { + experienceProvider.setLevel(character, level) + } else { + setExperience(character, clazz, experienceProvider.getExperienceNeededForLevel(level)) + } + } + + override fun getExperience(character: RPKCharacter, clazz: RPKClass): Int { + val experienceProvider = plugin.core.serviceManager.getServiceProvider(RPKExperienceProvider::class) + if (clazz == getClass(character)) { + return experienceProvider.getExperience(character) + } else { + val classExperienceTable = plugin.core.database.getTable(RPKClassExperienceTable::class) + val classExperience = classExperienceTable.get(character, clazz) + return classExperience?.experience?:0 + } + } + + override fun setExperience(character: RPKCharacter, clazz: RPKClass, experience: Int) { + val experienceProvider = plugin.core.serviceManager.getServiceProvider(RPKExperienceProvider::class) + if (clazz == getClass(character)) { + experienceProvider.setExperience(character, experience) + } else { + val classExperienceTable = plugin.core.database.getTable(RPKClassExperienceTable::class) + var classExperience = classExperienceTable.get(character, clazz) + if (classExperience == null) { + classExperience = RPKClassExperience( + character = character, + clazz = clazz, + experience = experience + ) + classExperienceTable.insert(classExperience) + } else { + classExperience.experience = experience + classExperienceTable.update(classExperience) + } + } + } +} \ No newline at end of file diff --git a/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/command/class/ClassCommand.kt b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/command/class/ClassCommand.kt new file mode 100644 index 000000000..8c61f9462 --- /dev/null +++ b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/command/class/ClassCommand.kt @@ -0,0 +1,30 @@ +package com.rpkit.classes.bukkit.command.`class` + +import com.rpkit.classes.bukkit.RPKClassesBukkit +import org.bukkit.command.Command +import org.bukkit.command.CommandExecutor +import org.bukkit.command.CommandSender + + +class ClassCommand(private val plugin: RPKClassesBukkit): CommandExecutor { + + private val classSetCommand = ClassSetCommand(plugin) + private val classListCommand = ClassListCommand(plugin) + + override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array): Boolean { + if (args.isNotEmpty()) { + val newArgs = args.drop(1).toTypedArray() + if (args[0].equals("set", ignoreCase = true)) { + return classSetCommand.onCommand(sender, command, label, newArgs) + } else if (args[0].equals("list", ignoreCase = true)) { + return classListCommand.onCommand(sender, command, label, newArgs) + } else { + sender.sendMessage(plugin.messages["class-usage"]) + } + } else { + sender.sendMessage(plugin.messages["class-usage"]) + } + return true + } + +} \ No newline at end of file diff --git a/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/command/class/ClassListCommand.kt b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/command/class/ClassListCommand.kt new file mode 100644 index 000000000..a20c3f13a --- /dev/null +++ b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/command/class/ClassListCommand.kt @@ -0,0 +1,25 @@ +package com.rpkit.classes.bukkit.command.`class` + +import com.rpkit.classes.bukkit.RPKClassesBukkit +import com.rpkit.classes.bukkit.classes.RPKClassProvider +import org.bukkit.command.Command +import org.bukkit.command.CommandExecutor +import org.bukkit.command.CommandSender + + +class ClassListCommand(private val plugin: RPKClassesBukkit): CommandExecutor { + + override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array): Boolean { + if (!sender.hasPermission("rpkit.classes.command.class.list")) { + sender.sendMessage(plugin.messages["no-permission-class-list"]) + return true + } + val classProvider = plugin.core.serviceManager.getServiceProvider(RPKClassProvider::class) + sender.sendMessage(plugin.messages["class-list-title"]) + for (clazz in classProvider.classes) { + sender.sendMessage(plugin.messages["class-list-item", mapOf(Pair("class", clazz.name))]) + } + return true + } + +} \ No newline at end of file diff --git a/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/command/class/ClassSetCommand.kt b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/command/class/ClassSetCommand.kt new file mode 100644 index 000000000..90dba78ca --- /dev/null +++ b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/command/class/ClassSetCommand.kt @@ -0,0 +1,52 @@ +package com.rpkit.classes.bukkit.command.`class` + +import com.rpkit.characters.bukkit.character.RPKCharacterProvider +import com.rpkit.classes.bukkit.RPKClassesBukkit +import com.rpkit.classes.bukkit.classes.RPKClassProvider +import com.rpkit.players.bukkit.player.RPKPlayerProvider +import org.bukkit.command.Command +import org.bukkit.command.CommandExecutor +import org.bukkit.command.CommandSender +import org.bukkit.entity.Player + + +class ClassSetCommand(private val plugin: RPKClassesBukkit): CommandExecutor { + override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array): Boolean { + if (!sender.hasPermission("rpkit.classes.command.class.set")) { + sender.sendMessage(plugin.messages["no-permission-class-set"]) + return true + } + if (args.isEmpty()) { + sender.sendMessage(plugin.messages["class-set-usage"]) + return true + } + if (sender !is Player) { + sender.sendMessage(plugin.messages["not-from-console"]) + return true + } + val playerProvider = plugin.core.serviceManager.getServiceProvider(RPKPlayerProvider::class) + val characterProvider = plugin.core.serviceManager.getServiceProvider(RPKCharacterProvider::class) + val classProvider = plugin.core.serviceManager.getServiceProvider(RPKClassProvider::class) + val player = playerProvider.getPlayer(sender) + val character = characterProvider.getActiveCharacter(player) + if (character == null) { + sender.sendMessage(plugin.messages["no-character"]) + return true + } + val className = args[0] + val clazz = classProvider.getClass(className) + if (clazz == null) { + sender.sendMessage(plugin.messages["class-set-invalid-class"]) + return true + } + if (!clazz.hasPrerequisites(character)) { + sender.sendMessage(plugin.messages["class-set-invalid-prerequisites"]) + return true + } + classProvider.setClass(character, clazz) + sender.sendMessage(plugin.messages["class-set-valid", mapOf( + Pair("class", clazz.name) + )]) + return true + } +} \ No newline at end of file diff --git a/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/database/table/RPKCharacterClassTable.kt b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/database/table/RPKCharacterClassTable.kt new file mode 100644 index 000000000..c2a7d7b7f --- /dev/null +++ b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/database/table/RPKCharacterClassTable.kt @@ -0,0 +1,143 @@ +package com.rpkit.classes.bukkit.database.table + +import com.rpkit.characters.bukkit.character.RPKCharacter +import com.rpkit.characters.bukkit.character.RPKCharacterProvider +import com.rpkit.classes.bukkit.RPKClassesBukkit +import com.rpkit.classes.bukkit.classes.RPKCharacterClass +import com.rpkit.classes.bukkit.classes.RPKClassProvider +import com.rpkit.core.database.Database +import com.rpkit.core.database.Table +import com.rpkit.core.database.use +import org.ehcache.config.builders.CacheConfigurationBuilder +import org.ehcache.config.builders.CacheManagerBuilder +import org.ehcache.config.builders.ResourcePoolsBuilder +import java.sql.PreparedStatement +import java.sql.Statement.RETURN_GENERATED_KEYS + + +class RPKCharacterClassTable(database: Database, private val plugin: RPKClassesBukkit): Table(database, RPKCharacterClass::class) { + + private val cacheManager = CacheManagerBuilder.newCacheManagerBuilder().build(true) + private val cache = cacheManager.createCache("cache", + CacheConfigurationBuilder.newCacheConfigurationBuilder(Int::class.javaObjectType, RPKCharacterClass::class.java, + ResourcePoolsBuilder.heap(plugin.server.maxPlayers.toLong()))) + + override fun create() { + database.createConnection().use { connection -> + connection.prepareStatement( + "CREATE TABLE IF NOT EXISTS rpkit_character_class(" + + "id INTEGER PRIMARY KEY AUTO_INCREMENT," + + "character_id INTEGER," + + "class_name VARCHAR(256)" + + ")" + ).use(PreparedStatement::executeUpdate) + } + } + + override fun applyMigrations() { + if (database.getTableVersion(this) == null) { + database.setTableVersion(this, "1.2.0") + } + } + + override fun insert(entity: RPKCharacterClass): Int { + var id = 0 + database.createConnection().use { connection -> + connection.prepareStatement( + "INSERT INTO rpkit_character_class(character_id, class_name) VALUES(?, ?)", + RETURN_GENERATED_KEYS + ).use { statement -> + statement.setInt(1, entity.character.id) + statement.setString(2, entity.clazz.name) + statement.executeUpdate() + val generatedKeys = statement.generatedKeys + if (generatedKeys.next()) { + id = generatedKeys.getInt(1) + entity.id = id + cache.put(id, entity) + } + } + } + return id + } + + override fun update(entity: RPKCharacterClass) { + database.createConnection().use { connection -> + connection.prepareStatement( + "UPDATE rpkit_character_class SET character_id = ?, class_name = ? WHERE id = ?" + ).use { statement -> + statement.setInt(1, entity.character.id) + statement.setString(2, entity.clazz.name) + statement.setInt(3, entity.id) + statement.executeUpdate() + cache.put(entity.id, entity) + } + } + } + + override fun get(id: Int): RPKCharacterClass? { + if (cache.containsKey(id)) { + return cache.get(id) + } else { + var characterClass: RPKCharacterClass? = null + database.createConnection().use { connection -> + connection.prepareStatement( + "SELECT id, character_id, class_name FROM rpkit_character_class WHERE id = ?" + ).use { statement -> + statement.setInt(1, id) + val resultSet = statement.executeQuery() + if (resultSet.next()) { + val character = plugin.core.serviceManager.getServiceProvider(RPKCharacterProvider::class).getCharacter(resultSet.getInt("character_id")) + val clazz = plugin.core.serviceManager.getServiceProvider(RPKClassProvider::class).getClass(resultSet.getString("class_name")) + if (character != null && clazz != null) { + val finalCharacterClass = RPKCharacterClass( + resultSet.getInt("id"), + character, + clazz + ) + cache.put(finalCharacterClass.id, finalCharacterClass) + characterClass = finalCharacterClass + } else { + connection.prepareStatement( + "DELETE FROM rpkit_character_class WHERE id = ?" + ).use { statement -> + statement.setInt(1, resultSet.getInt("id")) + statement.executeUpdate() + cache.remove(resultSet.getInt("id")) + } + } + } + } + } + return characterClass + } + } + + fun get(character: RPKCharacter): RPKCharacterClass? { + var characterClass: RPKCharacterClass? = null + database.createConnection().use { connection -> + connection.prepareStatement( + "SELECT id FROM rpkit_character_class WHERE character_id = ?" + ).use { statement -> + statement.setInt(1, character.id) + val resultSet = statement.executeQuery() + if (resultSet.next()) { + characterClass = get(resultSet.getInt("id")) + } + } + } + return characterClass + } + + override fun delete(entity: RPKCharacterClass) { + database.createConnection().use { connection -> + connection.prepareStatement( + "DELETE FROM rpkit_character_class WHERE id = ?" + ).use { statement -> + statement.setInt(1, entity.id) + statement.executeUpdate() + cache.remove(entity.id) + } + } + } +} \ No newline at end of file diff --git a/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/database/table/RPKClassExperienceTable.kt b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/database/table/RPKClassExperienceTable.kt new file mode 100644 index 000000000..57e9c9419 --- /dev/null +++ b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/database/table/RPKClassExperienceTable.kt @@ -0,0 +1,150 @@ +package com.rpkit.classes.bukkit.database.table + +import com.rpkit.characters.bukkit.character.RPKCharacter +import com.rpkit.characters.bukkit.character.RPKCharacterProvider +import com.rpkit.classes.bukkit.RPKClassesBukkit +import com.rpkit.classes.bukkit.classes.RPKClass +import com.rpkit.classes.bukkit.classes.RPKClassExperience +import com.rpkit.classes.bukkit.classes.RPKClassProvider +import com.rpkit.core.database.Database +import com.rpkit.core.database.Table +import com.rpkit.core.database.use +import org.ehcache.config.builders.CacheConfigurationBuilder +import org.ehcache.config.builders.CacheManagerBuilder +import org.ehcache.config.builders.ResourcePoolsBuilder +import java.sql.PreparedStatement +import java.sql.Statement.RETURN_GENERATED_KEYS + + +class RPKClassExperienceTable(database: Database, private val plugin: RPKClassesBukkit): Table(database, RPKClassExperience::class) { + + private val cacheManager = CacheManagerBuilder.newCacheManagerBuilder().build(true) + private val cache = cacheManager.createCache("cache", + CacheConfigurationBuilder.newCacheConfigurationBuilder(Int::class.javaObjectType, RPKClassExperience::class.java, + ResourcePoolsBuilder.heap(plugin.server.maxPlayers.toLong()))) + + override fun create() { + database.createConnection().use { connection -> + connection.prepareStatement( + "CREATE TABLE IF NOT EXISTS rpkit_class_experience(" + + "id INTEGER PRIMARY KEY AUTO_INCREMENT," + + "character_id INTEGER," + + "class_name VARCHAR(256)," + + "experience INTEGER" + + ")" + ).use(PreparedStatement::executeUpdate) + } + } + + override fun applyMigrations() { + if (database.getTableVersion(this) == null) { + database.setTableVersion(this, "1.2.0") + } + } + + override fun insert(entity: RPKClassExperience): Int { + var id = 0 + database.createConnection().use { connection -> + connection.prepareStatement( + "INSERT INTO rpkit_class_experience(character_id, class_name, experience) VALUES(?, ?, ?)", + RETURN_GENERATED_KEYS + ).use { statement -> + statement.setInt(1, entity.character.id) + statement.setString(2, entity.clazz.name) + statement.setInt(3, entity.experience) + statement.executeUpdate() + val generatedKeys = statement.generatedKeys + if (generatedKeys.next()) { + id = generatedKeys.getInt(1) + entity.id = id + cache.put(id, entity) + } + } + } + return id + } + + override fun update(entity: RPKClassExperience) { + database.createConnection().use { connection -> + connection.prepareStatement( + "UPDATE rpkit_class_experience SET character_id = ?, class_name = ?, experience = ? WHERE id = ?" + ).use { statement -> + statement.setInt(1, entity.character.id) + statement.setString(2, entity.clazz.name) + statement.setInt(3, entity.experience) + statement.setInt(4, entity.id) + statement.executeUpdate() + cache.put(entity.id, entity) + } + } + } + + override fun get(id: Int): RPKClassExperience? { + if (cache.containsKey(id)) { + return cache.get(id) + } else { + var classExperience: RPKClassExperience? = null + database.createConnection().use { connection -> + connection.prepareStatement( + "SELECT id, character_id, class_name, experience FROM rpkit_class_experience WHERE id = ?" + ).use { statement -> + statement.setInt(1, id) + val resultSet = statement.executeQuery() + if (resultSet.next()) { + val character = plugin.core.serviceManager.getServiceProvider(RPKCharacterProvider::class).getCharacter(resultSet.getInt("character_id")) + val clazz = plugin.core.serviceManager.getServiceProvider(RPKClassProvider::class).getClass(resultSet.getString("class_name")) + if (character != null && clazz != null) { + val finalClassExperience = RPKClassExperience( + id, + character, + clazz, + resultSet.getInt("experience") + ) + cache.put(id, finalClassExperience) + classExperience = finalClassExperience + } else { + connection.prepareStatement( + "DELETE FROM rpkit_class_experience WHERE id = ?" + ).use { statement -> + statement.setInt(1, id) + statement.executeUpdate() + cache.remove(id) + } + } + } + } + } + return classExperience + } + } + + fun get(character: RPKCharacter, clazz: RPKClass): RPKClassExperience? { + var classExperience: RPKClassExperience? = null + database.createConnection().use { connection -> + connection.prepareStatement( + "SELECT id FROM rpkit_class_experience WHERE character_id = ? AND class_name = ?" + ).use { statement -> + statement.setInt(1, character.id) + statement.setString(2, clazz.name) + val resultSet = statement.executeQuery() + if (resultSet.next()) { + classExperience = get(resultSet.getInt("id")) + } + } + } + return classExperience + } + + override fun delete(entity: RPKClassExperience) { + database.createConnection().use { connection -> + connection.prepareStatement( + "DELETE FROM rpkit_class_experience WHERE id = ?" + ).use { statement -> + statement.setInt(1, entity.id) + statement.executeUpdate() + cache.remove(entity.id) + } + } + } + +} \ No newline at end of file diff --git a/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/listener/PluginEnableListener.kt b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/listener/PluginEnableListener.kt new file mode 100644 index 000000000..da6c1ed3f --- /dev/null +++ b/bukkit/rpk-classes-bukkit/src/main/kotlin/com/rpkit/classes/bukkit/listener/PluginEnableListener.kt @@ -0,0 +1,20 @@ +package com.rpkit.classes.bukkit.listener + +import com.rpkit.classes.bukkit.RPKClassesBukkit +import com.rpkit.core.bukkit.plugin.RPKBukkitPlugin +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener +import org.bukkit.event.server.PluginEnableEvent + + +class PluginEnableListener(private val plugin: RPKClassesBukkit): Listener { + + @EventHandler + fun onPluginEnable(event: PluginEnableEvent) { + if (plugin is RPKBukkitPlugin) { + plugin.attemptStatRegistration() + plugin.attemptCharacterCardFieldRegistration() + } + } + +} \ No newline at end of file diff --git a/bukkit/rpk-classes-bukkit/src/main/resources/config.yml b/bukkit/rpk-classes-bukkit/src/main/resources/config.yml new file mode 100644 index 000000000..4f697ab38 --- /dev/null +++ b/bukkit/rpk-classes-bukkit/src/main/resources/config.yml @@ -0,0 +1,129 @@ +classes: + swordsman: + max-level: 20 + skill-points: + base: + melee_offence: 10 + melee_defence: 10 + ranged_offence: 2 + ranged_defence: 2 + magic_offence: 0 + magic_defence: 0 + magic_healing: 0 + magic_nature: 0 + magic_illusion: 0 + magic_summoning: 0 + magic_sword: 1 + speed_nimble: 3 + support_perform: 3 + level: + melee_offence: 5 + melee_defence: 5 + ranged_offence: 2 + ranged_defence: 2 + magic_offence: 0 + magic_defence: 0 + magic_healing: 0 + magic_nature: 0 + magic_illusion: 0 + magic_summoning: 0 + magic_sword: 1 + speed_nimble: 3 + support_perform: 3 + bowman: + max-level: 20 + skill-points: + base: + melee_offence: 2 + melee_defence: 2 + ranged_offence: 10 + ranged_defence: 10 + magic_offence: 0 + magic_defence: 0 + magic_healing: 0 + magic_nature: 0 + magic_illusion: 0 + magic_summoning: 0 + magic_sword: 0 + speed_nimble: 5 + support_perform: 5 + level: + melee_offence: 2 + melee_defence: 2 + ranged_offence: 5 + ranged_defence: 5 + magic_offence: 0 + magic_defence: 0 + magic_healing: 0 + magic_nature: 0 + magic_illusion: 0 + magic_summoning: 0 + magic_sword: 0 + speed_nimble: 10 + support_perform: 5 + wizard: + max-level: 20 + skill-points: + base: + melee_offence: 1 + melee_defence: 1 + ranged_offence: 1 + ranged_defence: 1 + magic_offence: 5 + magic_defence: 5 + magic_healing: 5 + magic_nature: 5 + magic_illusion: 5 + magic_summoning: 5 + magic_sword: 1 + speed_nimble: 3 + support_perform: 3 + level: + melee_offence: 1 + melee_defence: 1 + ranged_offence: 1 + ranged_defence: 1 + magic_offence: 5 + magic_defence: 5 + magic_healing: 5 + magic_nature: 5 + magic_illusion: 5 + magic_summoning: 5 + magic_sword: 5 + speed_nimble: 1 + support_perform: 5 + freelancer: + max-level: 50 + prerequisites: + swordsman: 20 + bowman: 20 + wizard: 20 + skill-points: + base: + melee_offence: 5 + melee_defence: 5 + ranged_offence: 5 + ranged_defence: 5 + magic_offence: 5 + magic_defence: 5 + magic_healing: 5 + magic_nature: 5 + magic_illusion: 5 + magic_summoning: 5 + magic_sword: 5 + speed_nimble: 5 + support_perform: 5 + level: + melee_offence: 5 + melee_defence: 5 + ranged_offence: 5 + ranged_defence: 5 + magic_offence: 5 + magic_defence: 5 + magic_healing: 5 + magic_nature: 5 + magic_illusion: 5 + magic_summoning: 5 + magic_sword: 5 + speed_nimble: 5 + support_perform: 5 diff --git a/bukkit/rpk-classes-bukkit/src/main/resources/plugin.yml b/bukkit/rpk-classes-bukkit/src/main/resources/plugin.yml new file mode 100644 index 000000000..8ae4bf0cd --- /dev/null +++ b/bukkit/rpk-classes-bukkit/src/main/resources/plugin.yml @@ -0,0 +1,22 @@ +name: rpk-classes-bukkit +version: @version@ +author: alyphen +main: com.rpkit.classes.bukkit.RPKClassesBukkit +depend: +- rpk-core-bukkit +- rpk-character-lib-bukkit +- rpk-stat-lib-bukkit +- rpk-skill-lib-bukkit +- rpk-experience-lib-bukkit +- rpk-class-lib-bukkit +commands: + class: + description: Class management command + usage: / [set|list] +permissions: + rpkit.classes.command.class.set: + description: Allows setting your class + default: true + rpkit.classes.command.class.list: + description: Allows listing classes + default: true \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 460b726cf..dc7289d06 100644 --- a/settings.gradle +++ b/settings.gradle @@ -38,4 +38,6 @@ include "bukkit:rpk-rolling-bukkit" include "bukkit:rpk-experience-lib-bukkit" include "bukkit:rpk-experience-bukkit" include "bukkit:rpk-skill-lib-bukkit" -include "bukkit:rpk-skills-bukkit" \ No newline at end of file +include "bukkit:rpk-skills-bukkit" +include "bukkit:rpk-class-lib-bukkit" +include "bukkit:rpk-classes-bukkit"