🎨原神抽卡 (#156)

* Add files via upload

* 原神抽卡

* 🎨原神抽卡
This commit is contained in:
Coloured-glaze 2022-03-20 10:59:11 +08:00 committed by GitHub
parent 70cc28c191
commit cdf844be52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

453
plugin/genshin/ys.go Normal file
View File

@ -0,0 +1,453 @@
package genshin
import (
"archive/zip"
"fmt"
"image"
"image/color"
"image/draw"
"image/jpeg"
"image/png"
"io"
"math/rand"
"os"
"path/filepath"
"regexp"
"runtime"
"strconv"
"strings"
"time"
control "github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/control/order"
"github.com/FloatTech/zbputils/file"
"github.com/golang/freetype"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
var (
//genzip = "https://gitcode.net/qq_33747476/Images/-/raw/master/zero/Genshin.zip"
genzip = "https://raw.githubusercontent.com/FloatTech/zbpdata/main/Genshin/Genshin.zip" //素材包
Three, four, four2, five, five2 = []string{}, []string{}, []string{}, []string{}, []string{} //三 , 四, 五星的名字
DP, gen, ZipN, Spath = "./data/Genshin/", "_genshin.jpg", DP + "Genshin.zip", DP + "gacha/" //路径
five_bg, four_bg, three_bg = DP + "five_bg.jpg", DP + "four_bg.jpg", DP + "three_bg.jpg" //背景图片名
StarN3, StarN4, StarN5 = Spath + "ThreeStar.png", Spath + "FourStar.png", Spath + "FiveStar.png" //星级图标
Toatl, IMGN, isPath, Lock = 0, 0, false, false //累计抽奖次数, 卡池总数, 是否遍历过路径, 锁
DefaultMode, FiveMode, iPrefix = true, false, 0 //抽卡模式,文件前缀
engine = control.Register("genshin", order.AcquirePrio(), &control.Options{
DisableOnDefault: false,
Help: "genshin\n@bot\n- 十连\n- 十连抽\n- 切换卡池\n- 刷新卡池",
})
)
func init() {
engine.OnFullMatchGroup([]string{"刷新卡池"}, zero.OnlyToMe).SetBlock(false).
Handle(func(ctx *zero.Ctx) {
if IsExists(DP) {
IMGN = 0
LoadFolder()
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("刷新完成!\n数量:", IMGN))
IMGN = 0
} else {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("没有素材哦~\n请发送 十连 \n下载素材.."))
}
})
engine.OnFullMatchGroup([]string{"切换卡池"}, zero.OnlyToMe).SetBlock(false).
Handle(func(ctx *zero.Ctx) {
if !DefaultMode {
DefaultMode, FiveMode = true, false
ctx.SendChain(message.Text("切换到普通卡池~"))
} else {
DefaultMode, FiveMode = false, true
ctx.SendChain(message.Text("切换到五星卡池~"))
}
})
//@bot
engine.OnFullMatchGroup([]string{"十连", "十连抽", "来发十连", "来次十连", "来份十连"}, zero.OnlyToMe).SetBlock(false).
Handle(func(ctx *zero.Ctx) {
times := time.Now().Unix()
iPrefix++
if !isPath {
if Lock {
return
}
if !IsExists(DP) && !Lock {
Lock = true
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("素材未下载...\n是否需要下载素材\n下载素材|取消下载"))
ch := make(chan int, 1)
defer close(ch)
rule := func(ctx *zero.Ctx) bool {
for _, v := range ctx.Event.Message {
if v.Type == "text" {
text := strings.ReplaceAll(v.Data["text"], " ", "")
if text == "下载素材" {
return true
}
if text == "取消下载" {
ch <- 1
return false
}
}
}
return false
}
next := zero.NewFutureEvent("message", 999, false, zero.CheckUser(ctx.Event.UserID), rule)
recv, cancel := next.Repeat()
select {
case <-time.After(time.Second * 60):
Lock = false
cancel()
return
case <-recv:
cancel()
ctx.SendChain(message.Text("正在下载中~"))
os.Mkdir(DP, 0755)
err := file.DownloadTo(genzip, ZipN, true)
Lock = false
if err != nil {
ctx.SendChain(message.Text("下载出错了~", err))
return
}
case <-ch:
cancel()
ctx.SendChain(message.Text("取消了呢~"))
Lock = false
close(ch)
return
}
err := unzip(ZipN, "./data/")
if err != nil {
ctx.SendChain(message.Text("解压出错了~", err))
}
ctx.SendChain(message.Text("下载完成~"))
os.Remove(ZipN)
os.Chmod(DP, 0755)
return
} else {
LoadFolder()
}
}
Str := strconv.Itoa(iPrefix)
defer os.Remove(DP + Str + gen) //删除图片
Add(Str)
ctx.SendChain(message.At(ctx.Event.UserID), message.Text("十连成功~"),
message.Image("file:///"+file.Pwd()+"/data/Genshin/"+Str+gen))
fmt.Printf("OK %v 秒\n", time.Now().Unix()-times)
})
}
func Add(sf string) {
var (
fourName, fiveName = []string{}, []string{} //抽到 四, 五星角色的名字
ThreeArms, fourArms, fiveArms = []string{}, []string{}, []string{} //抽到 三 , 四, 五星武器的名字
fourN, fiveN, Nums, bgs = 0, 0, 10, []string{} //抽到 四, 五星角色的数量, 连抽次数, 背景图片名
ThreeN2, fourN2, fiveN2 = 0, 0, 0 //抽到 三 , 四, 五星武器的数量
Hero, StarName = []string{}, []string{} //角色武器名, 储存星级图标
Cicon, He_N = []string{}, []string{} //元素图标
)
rand.Seed(time.Now().UnixNano())
if Toatl == 9 { //累计9次十连加入一个五星
switch a := rand.Intn(2); a {
case 0:
fiveN++
f := rand.Intn(len(five))
fiveName = append(fiveName, five[f])
case 1:
fiveN2++
f := rand.Intn(len(five2))
fiveArms = append(fiveArms, five2[f])
}
Toatl, Nums = 0, 9
}
if DefaultMode { //默认模式
for i := 0; i < Nums; i++ {
a := rand.Intn(1000)
if a >= 0 && a <= 750 { //抽卡几率 三星75% 四星18% 五星7%
ThreeN2++
ta := rand.Intn(len(Three)) //名字总个数
ThreeArms = append(ThreeArms, Three[ta])
} else if a > 750 && a <= 840 {
fourN++
tb := rand.Intn(len(four))
fourName = append(fourName, four[tb]) //随机角色
} else if a > 840 && a <= 930 {
fourN2++
tb := rand.Intn(len(four2))
fourArms = append(fourArms, four2[tb]) //随机武器
} else if a > 930 && a <= 965 {
fiveN++
tc := rand.Intn(len(five))
fiveName = append(fiveName, five[tc])
} else if a > 965 {
fiveN2++
tc := rand.Intn(len(five2))
fiveArms = append(fiveArms, five2[tc])
}
}
if fourN+fourN2 == 0 && ThreeN2 > 0 { //没有四星时自动加入
ThreeN2--
ThreeArms = ThreeArms[:len(ThreeArms)-1]
switch a := rand.Intn(2); a {
case 0:
fourN++
f := rand.Intn(len(four))
fourName = append(fourName, four[f]) //随机角色
case 1:
fourN2++
f := rand.Intn(len(four2))
fourArms = append(fourArms, four2[f]) //随机武器
}
}
Toatl++ //次数+1
}
if FiveMode { //5星模式
for i := 0; i < Nums; i++ {
a := rand.Intn(100)
if a >= 0 && a <= 50 {
fiveN++
tc := rand.Intn(len(five))
fiveName = append(fiveName, five[tc]) //随机角色
} else if a > 50 {
fiveN2++
tc := rand.Intn(len(five2))
fiveArms = append(fiveArms, five2[tc]) //随机武器
}
}
}
//正则取出图标名
Addicon := func(Prefix string) string {
regC, _ := regexp.Compile(`\/[a-z]+_`)
regC2, _ := regexp.Compile(`\/`)
if runtime.GOOS == "windows" {
regC, _ = regexp.Compile(`\\[a-z]+_`)
regC2, _ = regexp.Compile(`\\`)
}
Pr := regC.FindAllString(Prefix, 1) //取出字符
str := strings.Join(Pr, "") //连接字符
Sp := strings.Split(str, "_")
Str2 := strings.Join(Sp, "")
Str3 := regC2.ReplaceAllString(Str2, "")
switch Str3 {
case "anemo":
return DP + "anemo.png"
case "cryo":
return DP + "cryo.png"
case "dendro":
return DP + "dendro.png"
case "electro":
return DP + "electro.png"
case "geo":
return DP + "geo.png"
case "hydro":
return DP + "hydro.png"
case "pyro":
return DP + "pyro.png"
case "bow":
return DP + "bow.png"
case "catalyst":
return DP + "catalyst.png"
case "claymore":
return DP + "claymore.png"
case "polearm":
return DP + "polearm.png"
default:
return DP + "sword.png"
}
}
He := func(StarNum int, id int, Star string, bg string) {
for i := 0; i < StarNum; i++ {
switch id {
case 1:
He_N = ThreeArms
case 2:
He_N = fourArms
case 3:
He_N = fourName
case 4:
He_N = fiveArms
case 5:
He_N = fiveName
}
bgs = append(bgs, bg) //加入颜色背景
Hero = append(Hero, He_N[i])
StarName = append(StarName, Star) //加入星级图标
Cicon = append(Cicon, Addicon(He_N[i])) //加入元素图标
}
}
if fiveN > 0 { //按顺序加入
He(fiveN, 5, StarN5, five_bg) //五星角色
}
if fourN > 0 {
He(fourN, 3, StarN4, four_bg) //四星角色
}
if fiveN2 > 0 {
He(fiveN2, 4, StarN5, five_bg) //五星武器
}
if fourN2 > 0 {
He(fourN2, 2, StarN4, four_bg) //四星武器
}
if ThreeN2 > 0 {
He(ThreeN2, 1, StarN3, three_bg) //三星武器
}
// fmt.Printf("三星数量 = %v 四星数量 = %v 五星数量 = %v\n", ThreeN2, fourN+fourN2, fiveN+fiveN2)
// fmt.Printf("三星 = %v \n四星 = %v%v \n五星 = %v%v\n", ThreeArms, fourName, fourArms, fiveName, fiveArms)
var (
inp = DP + "bg0.jpg" //背景导入图片路径
c1, c2, c3 uint8 = 50, 50, 50 //背景颜色
opt jpeg.Options
//字体rgb 205, 205, 205
)
rectangle := image.Rect(0, 0, 1920, 1080) // 图片宽度, 图片高度
rgba := image.NewRGBA(rectangle)
draw.Draw(rgba, rgba.Bounds(), image.NewUniform(color.RGBA{c1, c2, c3, 255}), image.Point{}, draw.Over)
context := freetype.NewContext() // 创建一个新的上下文
context.SetDPI(72) //每英寸 dpi
context.SetClip(rgba.Bounds())
context.SetDst(rgba)
img00, _ := os.Open(inp) // 打开背景图片
defer img00.Close()
img0, _ := jpeg.Decode(img00) //读取一个本地图像
offset := image.Pt(0, 0) //图片在背景上的位置
draw.Draw(rgba, img0.Bounds().Add(offset), img0, image.Point{}, draw.Over)
OpenW1, OpenH1 := 230, 0
for i := 0; i < len(Hero); i++ {
if i > 0 {
OpenW1 += 146 //图片宽度
}
imgs, _ := os.Open(bgs[i]) //取出背景图片
defer imgs.Close()
img, _ := jpeg.Decode(imgs)
offset := image.Pt(OpenW1, OpenH1)
draw.Draw(rgba, img.Bounds().Add(offset), img, image.Point{}, draw.Over)
imgs1, _ := os.Open(Hero[i]) //取出图片名
defer imgs1.Close()
img1, _ := png.Decode(imgs1)
offset1 := image.Pt(OpenW1, OpenH1)
draw.Draw(rgba, img1.Bounds().Add(offset1), img1, image.Point{}, draw.Over)
imgs2, _ := os.Open(StarName[i]) //取出星级图标
defer imgs2.Close()
img2, _ := png.Decode(imgs2)
offset2 := image.Pt(OpenW1, OpenH1)
draw.Draw(rgba, img2.Bounds().Add(offset2), img2, image.Point{}, draw.Over)
imgs3, _ := os.Open(Cicon[i]) //取出类型图标
defer imgs3.Close()
img3, _ := png.Decode(imgs3)
offset3 := image.Pt(OpenW1, OpenH1)
draw.Draw(rgba, img3.Bounds().Add(offset3), img3, image.Point{}, draw.Over)
}
imgs4, _ := os.Open(DP + "Reply.png") //"分享" 图标
defer imgs4.Close()
img4, _ := png.Decode(imgs4)
offset4 := image.Pt(1270, 945) //宽, 高
draw.Draw(rgba, img4.Bounds().Add(offset4), img4, image.Point{}, draw.Over)
file, err := os.Create(DP + sf + gen) //输出图片
if err != nil {
fmt.Printf("输出图片错误: %v\n", err)
return
}
defer file.Close()
//png.Encode(file, rgba) //输出png
opt.Quality = 100
jpeg.Encode(file, rgba, &opt) //输出jpg
}
//遍历文件夹
func LoadFolder() {
isPath = true
Three, four = []string{}, []string{} //重置变量
four2, five, five2 = []string{}, []string{}, []string{}
ReadPath(DP+"Three", "Three")
ReadPath(DP+"four", "four")
ReadPath(DP+"four2", "four2")
ReadPath(DP+"five", "five")
ReadPath(DP+"five2", "five2")
}
func ReadPath(lpath string, star string) {
err := filepath.Walk(lpath, func(filename string, fi os.FileInfo, err error) error {
if fi.IsDir() { // 忽略目录
return nil
}
f := filename
if star == "five" {
five = append(five, "./"+f)
} else if star == "five2" {
five2 = append(five2, "./"+f)
} else if star == "four" {
four = append(four, "./"+f)
} else if star == "four2" {
four2 = append(four2, "./"+f)
} else {
Three = append(Three, "./"+f)
}
IMGN++
return nil
})
if err != nil {
fmt.Printf("读取文件错误%v\n", err)
}
}
func IsExists(path string) bool { //判断文件是否存在
_, err := os.Stat(path)
if err != nil && !os.IsExist(err) {
return false
}
return true
}
//解压缩
func unzip(zipFile string, destDir string) error {
zipReader, err := zip.OpenReader(zipFile)
if err != nil {
return err
}
defer zipReader.Close()
for _, f := range zipReader.File {
fpath := filepath.Join(destDir, f.Name)
if f.FileInfo().IsDir() {
os.MkdirAll(fpath, os.ModePerm)
} else {
if err = os.MkdirAll(filepath.Dir(fpath), os.ModePerm); err != nil {
return err
}
inFile, err := f.Open() //读取压缩文件
if err != nil {
return err
}
defer inFile.Close()
outFile, err := os.OpenFile(fpath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, f.Mode()) //创建的新文件
if err != nil {
return err
}
defer outFile.Close()
_, _ = io.Copy(outFile, inFile)
}
}
return err
}