实现首个版本

This commit is contained in:
筱傑 2022-01-10 22:32:58 +08:00
parent f0eccaedaf
commit 327d9a7137
4 changed files with 267 additions and 31 deletions

View File

@ -1,5 +1,29 @@
# mirai-console-plugin-template
# J Horse Racing
## 一个简单的赛马插件
[Mirai Console](https://github.com/mamoe/mirai-console) 插件模板, 使用 Kotlin + Gradle.
### 赛马指令
- `#开启赛马` - 在本群中启用赛马功能(需管理身份)
- `#关闭赛马` - 在本群中禁用赛马功能(需管理身份)
- `#签到` - 获得签到奖励(可配置)
- `#赛马` - 比赛开盘
- `押马[1-5]#\d+` - 押n号马m币 例押马5#1000
- `#开始赛马` - 开始进行比赛
- `我有多少钱` - 查询余额(指令可配置)
[如何使用](https://github.com/project-mirai/how-to-use-plugin-template)
### 插件指令
- `/jhr enable <group>` - 启用指定群赛马
- `/jhr disable <group>` - 禁用指定群赛马
### 配置
- `goodEvents` 好消息
- `badEvents` 坏消息
### 游戏流程
通过签到得到初始资金进行赛马游戏
需要管理员或通过命令在群内启用赛马,然后发送`#赛马`开盘,下注完成后,通过`#开始赛马`来进行比赛。
等待比赛结束,结算奖励。
发送`我有多少钱`或者其它查询余额命令来查询当前余额。(可私聊查询)

View File

@ -7,8 +7,37 @@ import net.mamoe.mirai.console.data.value
object JHRPluginConfig : AutoSavePluginConfig("HorseRacingPluginConfig") {
@ValueDescription("签到奖励")
val signInReward by value(5000)
val signReward by value(5000)
@ValueDescription("启用赛马的群")
var enabledGroups: MutableList<Long> by value()
@ValueDescription("查询余额命令")
val queryScoreCommand: List<String> by value(listOf(
"我有多少钱鸭老婆",
"老婆我有多少钱",
"我有多少钱",
"我有多少钱老婆",
"老子还有多少钱",
))
@ValueDescription("好事件 ?为占位符")
val goodEvents: List<String> by value(listOf(
"?号马发现了前方的母马,加速加速!",
"?号马使用了私藏的超级棒棒糖,加速加速!",
"?号马已经没什么所谓了!",
"?号马发现,赛道岂是如此不便之物!",
))
@ValueDescription("坏事件 ?为占位符")
val badEvents: List<String> by value(listOf(
"?号马滑倒了!",
"?号马自由了!",
"?号马踩到了sf",
"?号马突然想上天摘星星!",
"?号马掉入了时辰的陷阱!",
))
// @ValueDescription("赛马数量")
// val horseCount by value(5)
}

View File

@ -7,6 +7,6 @@ import net.mamoe.mirai.console.data.value
object JHRPluginData : AutoSavePluginData("HorseRacingPluginData") {
@ValueDescription("用户存款")
val Scores: HashMap<Long, Int> by value()
val Scores: MutableMap<Long, Int> by value()
}

View File

@ -1,23 +1,20 @@
package top.jie65535.jhr
import net.mamoe.mirai.Bot
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.register
import net.mamoe.mirai.console.command.CommandManager.INSTANCE.unregister
import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription
import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin
import net.mamoe.mirai.event.EventChannel
import net.mamoe.mirai.contact.isOperator
import net.mamoe.mirai.event.GlobalEventChannel
import net.mamoe.mirai.event.events.BotInvitedJoinGroupRequestEvent
import net.mamoe.mirai.event.events.FriendMessageEvent
import net.mamoe.mirai.event.events.GroupMessageEvent
import net.mamoe.mirai.event.events.NewFriendRequestEvent
import net.mamoe.mirai.event.globalEventChannel
import net.mamoe.mirai.message.data.At
import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.message.data.Image.Key.queryUrl
import net.mamoe.mirai.message.data.PlainText
import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.message.data.MessageSource.Key.quote
import net.mamoe.mirai.utils.info
import java.util.*
import java.util.regex.Pattern
import kotlin.random.Random
object JHorseRacing : KotlinPlugin(
@ -27,10 +24,80 @@ object JHorseRacing : KotlinPlugin(
version = "0.1.0"
) {
author("jie65535")
info("赛马")
info("赛马")
}
) {
var date: Date = Calendar.getInstance().time
// region 签到
private var date = Calendar.getInstance().get(Calendar.DATE)
private val mSignUpSheet = mutableListOf<Long>()
private val signUpSheet: MutableList<Long>
get() {
val now = Calendar.getInstance().get(Calendar.DATE)
if (date != now) {
date = now
mSignUpSheet.clear()
}
return mSignUpSheet
}
private fun checkSign(id: Long): Boolean {
return signUpSheet.indexOf(id) != -1
}
// endregion
// region 赛马
private data class Bet(val id: Long, val number: Int, val score: Int)
private data class Horse(val type: Int, var position: Int = 0)
private val pools = mutableMapOf<Long, MutableList<Bet>>()
private const val horseCount = 5
private const val lapLength = 10
private val horseTypes = listOf(
"\uD83E\uDD84",
"\uD83D\uDC34",
"\uD83D\uDC3A",
"\uD83D\uDC02",
"\uD83D\uDC04",
"\uD83D\uDC0E",
"\uD83D\uDC07",
"\uD83D\uDC13",
"\uD83E\uDD8F",
"\uD83D\uDC29",
"\uD83D\uDC2E",
"\uD83D\uDC35",
"\uD83D\uDC19",
"\uD83D\uDC80",
"\uD83D\uDC24",
"\uD83D\uDC28",
"\uD83D\uDC2E",
"\uD83D\uDC14",
"\uD83D\uDC38",
"\uD83D\uDC7B",
"\uD83D\uDC1B",
"\uD83D\uDC20",
"\uD83D\uDC36",
"\uD83D\uDC2F",
" ",
"\uD83D\uDEBD"
)
private val ranks = mutableMapOf<Long, List<Horse>>()
private fun newRank() = List(horseCount) { Horse(Random.nextInt(horseTypes.size)) }
private fun drawHorse(horses: List<Horse>): String {
val sb = StringBuilder()
for ((i, horse) in horses.withIndex()) {
sb.append(i + 1)
for (j in horse.position until lapLength)
sb.append("Ξ")
sb.append(horseTypes[horse.type])
for (j in 1 until horse.position)
sb.append("Ξ")
sb.appendLine()
}
return sb.toString()
}
// endregion
override fun onEnable() {
logger.info { "Plugin loaded" }
@ -40,24 +107,142 @@ object JHorseRacing : KotlinPlugin(
val eventChannel = GlobalEventChannel.parentScope(this)
eventChannel.subscribeAlways<GroupMessageEvent> {
val msg = message.contentToString()
// 确认该群是否启用赛马
if (JHRPluginConfig.enabledGroups.indexOf(group.id) == -1) {
if (msg == "#开启赛马" && sender.permission.isOperator()) {
JHRPluginConfig.enabledGroups.add(group.id)
subject.sendMessage("已开启赛马")
}
return@subscribeAlways
}
val msg = message.contentToString()
// at机器人
if (message.any { it is At && it.target == bot.id }) {
when {
msg.startsWith("#赛马") -> TODO()
msg.startsWith("#开始赛马") -> TODO()
when {
msg.startsWith("#赛马") -> {
if (pools[subject.id] != null) {
subject.sendMessage("已经有比赛在进行了")
} else {
pools[subject.id] = mutableListOf()
subject.sendMessage("赛马比赛开盘,有钱交钱妹钱交人")
}
}
} else {
when {
msg.startsWith("#签到") -> TODO()
msg.startsWith("#押马") -> TODO()
msg.startsWith("#余额") -> TODO()
msg.startsWith("#开始赛马") -> {
subject.sendMessage("赛马开始辣,走过路过不要错过")
val rank = newRank()
ranks[subject.id] = rank
subject.sendMessage(drawHorse(rank))
launch {
var winner = -1
while (winner == -1) {
delay(Random.nextLong(1000) + 2000)
// 比赛事件触发
val eventHorseIndex = Random.nextInt(rank.size)
val eventHorse = rank[eventHorseIndex]
val eventMsg = if (Random.nextInt(77) > 32) {
eventHorse.position += 1
JHRPluginConfig.goodEvents[Random.nextInt(JHRPluginConfig.goodEvents.size)]
} else {
eventHorse.position -= 1
JHRPluginConfig.badEvents[Random.nextInt(JHRPluginConfig.badEvents.size)]
}
subject.sendMessage(eventMsg.replace("?", (eventHorseIndex + 1).toString()))
// 所有马前进
for ((i, horse) in rank.withIndex()) {
if (++horse.position >= lapLength) {
winner = i + 1
}
}
subject.sendMessage(drawHorse(rank))
delay(Random.nextLong(1000) + 3000)
}
val pool = pools.remove(subject.id)
for (bet in pool!!) {
val score = JHRPluginData.Scores[bet.id]!!
JHRPluginData.Scores[bet.id] = score + if (bet.number == winner) {
(bet.score * 1.5).toInt()
} else {
-bet.score
}
}
subject.sendMessage("${winner}最终赢得了胜利,让我们为它鼓掌")
}
}
msg == "#关闭赛马" -> {
if (sender.permission.isOperator()) {
JHRPluginConfig.enabledGroups.remove(subject.id)
subject.sendMessage("已关闭赛马")
}
}
msg == "#签到" -> {
if (checkSign(sender.id)) {
subject.sendMessage("一天只能签到一次噢")
} else {
signUpSheet.add(sender.id)
val score = JHRPluginData.Scores[sender.id]
val reward = JHRPluginConfig.signReward
if (score != null) {
JHRPluginData.Scores[sender.id] = score + reward
subject.sendMessage("马币+${reward},现在马币:${score + reward}")
} else {
JHRPluginData.Scores[sender.id] = reward
subject.sendMessage("马币+${reward}")
}
}
}
msg.startsWith("押马") -> {
val pool = pools[subject.id] ?: return@subscribeAlways
if (pool.any { it.id == sender.id }) {
subject.sendMessage("你已经下过注辣")
return@subscribeAlways
}
val m = msg.removePrefix("押马")
val p = m.split('#')
if (p.size != 2) {
return@subscribeAlways
}
val no = p[0].toIntOrNull()
val coin = p[1].toIntOrNull()
if (no == null || no < 1 || no > horseCount) {
subject.sendMessage("没有这个编号的选手")
return@subscribeAlways
}
if (coin == null || coin < 0) {
subject.sendMessage("胡乱下注不可取")
return@subscribeAlways
}
val score = JHRPluginData.Scores[sender.id]
if (score == null || score - coin < 0) {
subject.sendMessage("没那么多可以下注的币惹")
return@subscribeAlways
}
pool.add(Bet(sender.id, no, coin))
subject.sendMessage("下注完成 加油啊${no}号马")
}
}
}
eventChannel.subscribeAlways<MessageEvent> {
val msg = message.contentToString().trim()
if (JHRPluginConfig.queryScoreCommand.indexOf(msg) != -1) {
// 查询余额
val score = JHRPluginData.Scores[it.sender.id]
val ret = MessageChainBuilder()
ret.add(message.quote())
if (score != null) {
ret.add("${score}块钱")
if (!checkSign(sender.id)) {
ret.add(",还没有签到哦")
}
} else {
ret.add("锅里没有一滴油")
}
subject.sendMessage(ret.asMessageChain())
}
}
}
@ -65,6 +250,4 @@ object JHorseRacing : KotlinPlugin(
override fun onDisable() {
JHRCommand.unregister()
}
}