mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-19 05:30:07 +08:00
840 lines
23 KiB
Go
840 lines
23 KiB
Go
// Package mcfish 钓鱼模拟器
|
||
package mcfish
|
||
|
||
import (
|
||
"encoding/json"
|
||
"math/rand"
|
||
"os"
|
||
"strconv"
|
||
"sync"
|
||
"time"
|
||
|
||
fcext "github.com/FloatTech/floatbox/ctxext"
|
||
"github.com/FloatTech/floatbox/math"
|
||
sql "github.com/FloatTech/sqlite"
|
||
ctrl "github.com/FloatTech/zbpctrl"
|
||
"github.com/FloatTech/zbputils/control"
|
||
"github.com/FloatTech/zbputils/ctxext"
|
||
zero "github.com/wdvxdr1123/ZeroBot"
|
||
"github.com/wdvxdr1123/ZeroBot/message"
|
||
)
|
||
|
||
type fishdb struct {
|
||
db *sql.Sqlite
|
||
sync.RWMutex
|
||
}
|
||
|
||
// FishLimit 钓鱼次数上限
|
||
const FishLimit = 50
|
||
|
||
// version 规则版本号
|
||
const version = "5.5.8"
|
||
|
||
// 各物品信息
|
||
type jsonInfo struct {
|
||
ZoneInfo []zoneInfo `json:"分类"` // 区域概率
|
||
ArticleInfo []articleInfo `json:"物品"` // 物品信息
|
||
}
|
||
type zoneInfo struct {
|
||
Name string `json:"类型"` // 类型
|
||
Probability int `json:"概率[0-100)"` // 概率
|
||
}
|
||
type articleInfo struct {
|
||
Name string `json:"名称"` // 名称
|
||
Type string `json:"类型"` // 类型
|
||
Probability int `json:"概率[0-100),omitempty"` // 概率
|
||
Durable int `json:"耐久上限,omitempty"` // 耐久
|
||
Price int `json:"价格"` // 价格
|
||
}
|
||
|
||
type probabilityLimit struct {
|
||
Min int
|
||
Max int
|
||
}
|
||
|
||
type equip struct {
|
||
ID int64 // 用户
|
||
Equip string // 装备名称
|
||
Durable int // 耐久
|
||
Maintenance int // 维修次数
|
||
Induce int // 诱钓等级
|
||
Favor int // 眷顾等级
|
||
}
|
||
|
||
type article struct {
|
||
Duration int64
|
||
Name string
|
||
Number int
|
||
Other string // 耐久/维修次数/诱钓/眷顾
|
||
Type string
|
||
}
|
||
|
||
type store struct {
|
||
Duration int64
|
||
Name string
|
||
Number int
|
||
Price int
|
||
Other string // 耐久/维修次数/诱钓/眷顾
|
||
Type string
|
||
}
|
||
|
||
type fishState struct {
|
||
ID int64
|
||
Duration int64
|
||
Fish int
|
||
Equip int
|
||
Curse int // 功德--(x)
|
||
Bless int // 功德++(x)
|
||
}
|
||
|
||
type storeDiscount struct {
|
||
Name string
|
||
Discount int
|
||
}
|
||
|
||
// buff状态记录
|
||
// buff0: 优惠卷
|
||
type buffInfo struct {
|
||
ID int64
|
||
Duration int64
|
||
BuyTimes int `db:"Buff0"` // 购买次数
|
||
Coupon int `db:"Buff1"` // 优惠卷
|
||
SalesPole int `db:"Buff2"` // 卖鱼竿上限
|
||
BuyTing int `db:"Buff3"` // 购买上限
|
||
SalesFish int `db:"Buff4"` // 卖鱼次数
|
||
Buff5 int `db:"Buff5"` // 暂定
|
||
Buff6 int `db:"Buff6"` // 暂定
|
||
Buff7 int `db:"Buff7"` // 暂定
|
||
Buff8 int `db:"Buff8"` // 暂定
|
||
Buff9 int `db:"Buff9"` // 暂定
|
||
}
|
||
|
||
var (
|
||
articlesInfo = jsonInfo{} // 物品信息
|
||
thingList = make([]string, 0, 100) // 竿列表
|
||
poleList = make([]string, 0, 10) // 竿列表
|
||
fishList = make([]string, 0, 10) // 鱼列表
|
||
treasureList = make([]string, 0, 10) // 鱼列表
|
||
wasteList = make([]string, 0, 10) // 垃圾列表
|
||
probabilities = make(map[string]probabilityLimit, 50) // 概率分布
|
||
priceList = make(map[string]int, 50) // 价格分布
|
||
durationList = make(map[string]int, 50) // 装备耐久分布
|
||
discountList = make(map[string]int, 50) // 价格波动信息
|
||
enchantLevel = []string{"0", "Ⅰ", "Ⅱ", "Ⅲ"}
|
||
dbdata = &fishdb{
|
||
db: &sql.Sqlite{},
|
||
}
|
||
)
|
||
|
||
var (
|
||
engine = control.AutoRegister(&ctrl.Options[*zero.Ctx]{
|
||
DisableOnDefault: false,
|
||
Brief: "钓鱼",
|
||
Help: "一款钓鱼模拟器\n----------指令----------\n" +
|
||
"- 钓鱼看板/钓鱼商店\n- 购买xxx\n- 购买xxx [数量]\n- 出售xxx\n- 出售xxx [数量]\n- 出售所有垃圾\n" +
|
||
"- 钓鱼背包\n- 装备[xx竿|三叉戟|美西螈]\n- 附魔[诱钓|海之眷顾]\n- 修复鱼竿\n- 合成[xx竿|三叉戟]\n- 消除[绑定|宝藏]诅咒\n- 消除[绑定|宝藏]诅咒 [数量]\n" +
|
||
"- 进行钓鱼\n- 进行n次钓鱼\n- 当前装备概率明细\n" +
|
||
"规则V" + version + ":\n" +
|
||
"1.每日的商店价格是波动的!!如何最大化收益自己考虑一下喔\n" +
|
||
"2.装备信息:\n-> 木竿 : 耐久上限:30 均价:100 上钩概率:0.7%\n-> 铁竿 : 耐久上限:50 均价:300 上钩概率:0.2%\n-> 金竿 : 耐久上限:70 均价700 上钩概率:0.06%\n" +
|
||
"-> 钻石竿 : 耐久上限:100 均价1500 上钩概率:0.03%\n-> 下界合金竿 : 耐久上限:150 均价3100 上钩概率:0.01%\n-> 三叉戟 : 可使1次钓鱼视为3次钓鱼. 耐久上限:300 均价4000 只能合成、修复和交易\n" +
|
||
"3.附魔书信息:\n-> 诱钓 : 减少上钩时间. 均价:1000, 上钩概率:0.25%\n-> 海之眷顾 : 增加宝藏上钩概率. 均价:2500, 上钩概率:0.10%\n" +
|
||
"4.稀有物品:\n-> 唱片 : 出售物品时使用该物品使价格翻倍. 均价:3000, 上钩概率:0.01%\n" +
|
||
"-> 美西螈 : 可装备,获得隐形[钓鱼佬]buff,并让钓到除鱼竿和美西螈外的物品数量变成3,无耐久上限.不可修复/附魔,每次钓鱼消耗两任意鱼类物品. 均价:3000, 上钩概率:0.01%\n" +
|
||
"-> 海豚 : 使空竿概率变成垃圾概率. 均价:1000, 上钩概率:0.19%\n" +
|
||
"-> 宝藏诅咒 : 无法交易,每一层就会增加购买时10%价格和减少出售时10%价格(超过10层会变为倒贴钱). 上钩概率:0.25%\n-> 净化书 : 用于消除宝藏诅咒. 均价:5000, 上钩概率:0.19%\n" +
|
||
"5.鱼类信息:\n-> 鳕鱼 : 均价:10 上钩概率:0.69%\n-> 鲑鱼 : 均价:50 上钩概率:0.2%\n-> 热带鱼 : 均价:100 上钩概率:0.06%\n-> 河豚 : 均价:300 上钩概率:0.03%\n-> 鹦鹉螺 : 均价:500 上钩概率:0.01%\n-> 墨鱼 : 均价:500 上钩概率:0.01%\n" +
|
||
"6.垃圾:\n-> 均价:10 上钩概率:30%\n" +
|
||
"7.物品BUFF:\n-> 钓鱼佬 : 当背包名字含有'鱼'的物品数量超过100时激活,钓到物品概率提高至90%\n-> 修复大师 : 当背包鱼竿数量超过10时激活,修复物品时耐久百分百继承\n" +
|
||
"8.合成:\n-> 铁竿 : 3x木竿\n-> 金竿 : 3x铁竿\n-> 钻石竿 : 3x金竿\n-> 下界合金竿 : 3x钻石竿\n-> 三叉戟 : 3x下界合金竿\n注:合成成功率90%(包括梭哈),合成鱼竿的附魔等级=(附魔等级合/合成鱼竿数量)\n" +
|
||
"9.杂项:\n-> 无装备的情况下,每人最多可以购买3次100块钱的鱼竿\n-> 默认状态钓鱼上钩概率为60%(理论值!!!)\n-> 附魔的鱼竿会因附魔变得昂贵,每个附魔最高3级\n-> 三叉戟不算鱼竿,修复时可直接满耐久\n" +
|
||
"-> 鱼竿数量大于50的不能买东西;\n 鱼竿数量大于30的不能钓鱼;\n 每购/售10次鱼竿获得1层宝藏诅咒;\n 每购买20次物品将获得3次价格减半福利;\n 每钓鱼75次获得1本净化书;\n" +
|
||
" 每天最多只可出售5个鱼竿和购买15次物品;鱼类交易每天最多100条.",
|
||
PublicDataFolder: "McFish",
|
||
}).ApplySingle(ctxext.DefaultSingle)
|
||
getdb = fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
|
||
dbdata.db.DBPath = engine.DataFolder() + "fishdata.db"
|
||
err := dbdata.db.Open(time.Hour * 24)
|
||
if err != nil {
|
||
ctx.SendChain(message.Text("[ERROR at main.go.1]:", err))
|
||
return false
|
||
}
|
||
return true
|
||
})
|
||
)
|
||
|
||
func init() {
|
||
// go func() {
|
||
_, err := engine.GetLazyData("articlesInfo.json", false)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
reader, err := os.Open(engine.DataFolder() + "articlesInfo.json")
|
||
if err == nil {
|
||
err = json.NewDecoder(reader).Decode(&articlesInfo)
|
||
}
|
||
if err == nil {
|
||
err = reader.Close()
|
||
}
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
probableList := make([]int, 4)
|
||
for _, info := range articlesInfo.ZoneInfo {
|
||
switch info.Name {
|
||
case "treasure":
|
||
probableList[0] = info.Probability
|
||
case "pole":
|
||
probableList[1] = info.Probability
|
||
case "fish":
|
||
probableList[2] = info.Probability
|
||
case "waste":
|
||
probableList[3] = info.Probability
|
||
}
|
||
}
|
||
probabilities["treasure"] = probabilityLimit{
|
||
Min: 0,
|
||
Max: probableList[0],
|
||
}
|
||
probabilities["pole"] = probabilityLimit{
|
||
Min: probableList[0],
|
||
Max: probableList[1],
|
||
}
|
||
probabilities["fish"] = probabilityLimit{
|
||
Min: probableList[1],
|
||
Max: probableList[2],
|
||
}
|
||
probabilities["waste"] = probabilityLimit{
|
||
Min: probableList[2],
|
||
Max: probableList[3],
|
||
}
|
||
minMap := make(map[string]int, 4)
|
||
for _, info := range articlesInfo.ArticleInfo {
|
||
switch {
|
||
case info.Type == "pole" || info.Name == "美西螈":
|
||
poleList = append(poleList, info.Name)
|
||
case info.Type == "fish" || info.Name == "海豚":
|
||
fishList = append(fishList, info.Name)
|
||
case info.Type == "waste":
|
||
wasteList = append(wasteList, info.Name)
|
||
case info.Type == "treasure":
|
||
treasureList = append(treasureList, info.Name)
|
||
}
|
||
if info.Name != "宝藏诅咒" {
|
||
thingList = append(thingList, info.Name)
|
||
priceList[info.Name] = info.Price
|
||
}
|
||
if info.Durable != 0 {
|
||
durationList[info.Name] = info.Durable
|
||
}
|
||
probabilities[info.Name] = probabilityLimit{
|
||
Min: minMap[info.Type],
|
||
Max: minMap[info.Type] + info.Probability,
|
||
}
|
||
minMap[info.Type] += info.Probability
|
||
}
|
||
// }()
|
||
}
|
||
|
||
// 更新上限信息
|
||
func (sql *fishdb) updateFishInfo(uid int64, number int) (residue int, err error) {
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
userInfo := fishState{ID: uid}
|
||
err = sql.db.Create("fishState", &userInfo)
|
||
if err != nil {
|
||
return 0, err
|
||
}
|
||
_ = sql.db.Find("fishState", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
|
||
if time.Unix(userInfo.Duration, 0).Day() != time.Now().Day() {
|
||
userInfo.Fish = 0
|
||
userInfo.Duration = time.Now().Unix()
|
||
}
|
||
if userInfo.Fish >= FishLimit {
|
||
return 0, nil
|
||
}
|
||
residue = number
|
||
if userInfo.Fish+number > FishLimit {
|
||
residue = FishLimit - userInfo.Fish
|
||
number = residue
|
||
}
|
||
userInfo.Fish += number
|
||
err = sql.db.Insert("fishState", &userInfo)
|
||
return
|
||
}
|
||
|
||
// 更新诅咒
|
||
func (sql *fishdb) updateCurseFor(uid int64, info string, number int) (err error) {
|
||
if number < 1 {
|
||
return
|
||
}
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
userInfo := fishState{ID: uid}
|
||
err = sql.db.Create("fishState", &userInfo)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
changeCheck := false
|
||
add := 0
|
||
buffName := "宝藏诅咒"
|
||
_ = sql.db.Find("fishState", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
|
||
if info == "fish" {
|
||
userInfo.Bless += number
|
||
for userInfo.Bless >= 75 {
|
||
add++
|
||
changeCheck = true
|
||
buffName = "净化书"
|
||
userInfo.Bless -= 75
|
||
}
|
||
} else {
|
||
userInfo.Curse += number
|
||
for userInfo.Curse >= 10 {
|
||
add++
|
||
changeCheck = true
|
||
userInfo.Curse -= 10
|
||
}
|
||
}
|
||
err = sql.db.Insert("fishState", &userInfo)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if changeCheck {
|
||
table := strconv.FormatInt(uid, 10) + "Pack"
|
||
thing := article{
|
||
Duration: time.Now().Unix(),
|
||
Name: buffName,
|
||
Type: "treasure",
|
||
}
|
||
_ = sql.db.Find(table, &thing, "where Name = '"+buffName+"'")
|
||
thing.Number += add
|
||
return sql.db.Insert(table, &thing)
|
||
}
|
||
return
|
||
}
|
||
|
||
/*********************************************************/
|
||
/************************装备相关函数***********************/
|
||
/*********************************************************/
|
||
|
||
func (sql *fishdb) checkEquipFor(uid int64) (ok bool, err error) {
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
userInfo := fishState{ID: uid}
|
||
err = sql.db.Create("fishState", &userInfo)
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
if !sql.db.CanFind("fishState", "where ID = "+strconv.FormatInt(uid, 10)) {
|
||
return true, nil
|
||
}
|
||
err = sql.db.Find("fishState", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
if userInfo.Equip > 3 {
|
||
return false, nil
|
||
}
|
||
return true, nil
|
||
}
|
||
|
||
func (sql *fishdb) setEquipFor(uid int64) (err error) {
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
userInfo := fishState{ID: uid}
|
||
err = sql.db.Create("fishState", &userInfo)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
_ = sql.db.Find("fishState", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
|
||
if err != nil {
|
||
return err
|
||
}
|
||
userInfo.Equip++
|
||
return sql.db.Insert("fishState", &userInfo)
|
||
}
|
||
|
||
// 获取装备信息
|
||
func (sql *fishdb) getUserEquip(uid int64) (userInfo equip, err error) {
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
err = sql.db.Create("equips", &userInfo)
|
||
if err != nil {
|
||
return
|
||
}
|
||
if !sql.db.CanFind("equips", "where ID = "+strconv.FormatInt(uid, 10)) {
|
||
return
|
||
}
|
||
err = sql.db.Find("equips", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
|
||
return
|
||
}
|
||
|
||
// 更新装备信息
|
||
func (sql *fishdb) updateUserEquip(userInfo equip) (err error) {
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
err = sql.db.Create("equips", &userInfo)
|
||
if err != nil {
|
||
return
|
||
}
|
||
if userInfo.Durable == 0 {
|
||
return sql.db.Del("equips", "where ID = "+strconv.FormatInt(userInfo.ID, 10))
|
||
}
|
||
return sql.db.Insert("equips", &userInfo)
|
||
}
|
||
|
||
func (sql *fishdb) pickFishFor(uid int64, number int) (fishNames map[string]int, err error) {
|
||
fishNames = make(map[string]int, 6)
|
||
name := strconv.FormatInt(uid, 10) + "Pack"
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
userInfo := article{}
|
||
err = sql.db.Create(name, &userInfo)
|
||
if err != nil {
|
||
return
|
||
}
|
||
count, err := sql.db.Count(name)
|
||
if err != nil {
|
||
return
|
||
}
|
||
if count == 0 {
|
||
return
|
||
}
|
||
if !sql.db.CanFind(name, "where Type is 'fish'") {
|
||
return
|
||
}
|
||
fishInfo := article{}
|
||
k := 0
|
||
for i := number * 2; i > 0 && k < len(fishList); {
|
||
_ = sql.db.Find(name, &fishInfo, "where Name is '"+fishList[k]+"'")
|
||
if fishInfo.Number <= 0 {
|
||
k++
|
||
continue
|
||
}
|
||
if fishInfo.Number < i {
|
||
k++
|
||
i -= fishInfo.Number
|
||
fishNames[fishInfo.Name] += fishInfo.Number
|
||
fishInfo.Number = 0
|
||
} else {
|
||
fishNames[fishInfo.Name] += i
|
||
fishInfo.Number -= i
|
||
i = 0
|
||
}
|
||
if fishInfo.Number <= 0 {
|
||
err = sql.db.Del(name, "where Duration = "+strconv.FormatInt(fishInfo.Duration, 10))
|
||
} else {
|
||
err = sql.db.Insert(name, &fishInfo)
|
||
}
|
||
if err != nil {
|
||
return
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
/*********************************************************/
|
||
/************************背包相关函数***********************/
|
||
/*********************************************************/
|
||
|
||
// 获取用户背包信息
|
||
func (sql *fishdb) getUserPack(uid int64) (thingInfos []article, err error) {
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
userInfo := article{}
|
||
err = sql.db.Create(strconv.FormatInt(uid, 10)+"Pack", &userInfo)
|
||
if err != nil {
|
||
return
|
||
}
|
||
count, err := sql.db.Count(strconv.FormatInt(uid, 10) + "Pack")
|
||
if err != nil {
|
||
return
|
||
}
|
||
if count == 0 {
|
||
return
|
||
}
|
||
err = sql.db.FindFor(strconv.FormatInt(uid, 10)+"Pack", &userInfo, "ORDER by Type, Name, Other ASC", func() error {
|
||
thingInfos = append(thingInfos, userInfo)
|
||
return nil
|
||
})
|
||
return
|
||
}
|
||
|
||
// 获取用户物品信息
|
||
func (sql *fishdb) getUserThingInfo(uid int64, thing string) (thingInfos []article, err error) {
|
||
name := strconv.FormatInt(uid, 10) + "Pack"
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
userInfo := article{}
|
||
err = sql.db.Create(name, &userInfo)
|
||
if err != nil {
|
||
return
|
||
}
|
||
count, err := sql.db.Count(name)
|
||
if err != nil {
|
||
return
|
||
}
|
||
if count == 0 {
|
||
return
|
||
}
|
||
if !sql.db.CanFind(name, "where Name = '"+thing+"'") {
|
||
return
|
||
}
|
||
err = sql.db.FindFor(name, &userInfo, "where Name = '"+thing+"'", func() error {
|
||
thingInfos = append(thingInfos, userInfo)
|
||
return nil
|
||
})
|
||
return
|
||
}
|
||
|
||
// 更新用户物品信息
|
||
func (sql *fishdb) updateUserThingInfo(uid int64, userInfo article) (err error) {
|
||
name := strconv.FormatInt(uid, 10) + "Pack"
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
err = sql.db.Create(name, &userInfo)
|
||
if err != nil {
|
||
return
|
||
}
|
||
if userInfo.Number == 0 {
|
||
return sql.db.Del(name, "where Duration = "+strconv.FormatInt(userInfo.Duration, 10))
|
||
}
|
||
return sql.db.Insert(name, &userInfo)
|
||
}
|
||
|
||
// 获取某关键字的数量
|
||
func (sql *fishdb) getNumberFor(uid int64, thing string) (number int, err error) {
|
||
name := strconv.FormatInt(uid, 10) + "Pack"
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
userInfo := article{}
|
||
err = sql.db.Create(name, &userInfo)
|
||
if err != nil {
|
||
return
|
||
}
|
||
count, err := sql.db.Count(name)
|
||
if err != nil {
|
||
return
|
||
}
|
||
if count == 0 {
|
||
return
|
||
}
|
||
if !sql.db.CanFind(name, "where Name glob '*"+thing+"*'") {
|
||
return
|
||
}
|
||
info := article{}
|
||
err = sql.db.FindFor(name, &info, "where Name glob '*"+thing+"*'", func() error {
|
||
number += info.Number
|
||
return nil
|
||
})
|
||
return
|
||
}
|
||
|
||
// 获取用户的某类物品信息
|
||
func (sql *fishdb) getUserTypeInfo(uid int64, thingType string) (thingInfos []article, err error) {
|
||
name := strconv.FormatInt(uid, 10) + "Pack"
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
userInfo := article{}
|
||
err = sql.db.Create(name, &userInfo)
|
||
if err != nil {
|
||
return
|
||
}
|
||
if !sql.db.CanFind(name, "where Type = '"+thingType+"'") {
|
||
return
|
||
}
|
||
err = sql.db.FindFor(name, &userInfo, "where Type = '"+thingType+"'", func() error {
|
||
thingInfos = append(thingInfos, userInfo)
|
||
return nil
|
||
})
|
||
return
|
||
}
|
||
|
||
/*********************************************************/
|
||
/************************商店相关函数***********************/
|
||
/*********************************************************/
|
||
|
||
// 刷新商店信息
|
||
func (sql *fishdb) refreshStroeInfo() (ok bool, err error) {
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
err = sql.db.Create("stroeDiscount", &storeDiscount{})
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
err = sql.db.Create("store", &store{})
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
lastTime := storeDiscount{}
|
||
_ = sql.db.Find("stroeDiscount", &lastTime, "where Name = 'lastTime'")
|
||
refresh := false
|
||
timeNow := time.Now().Day()
|
||
if timeNow != lastTime.Discount {
|
||
lastTime = storeDiscount{
|
||
Name: "lastTime",
|
||
Discount: timeNow,
|
||
}
|
||
err = sql.db.Insert("stroeDiscount", &lastTime)
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
refresh = true
|
||
}
|
||
for _, name := range thingList {
|
||
thing := storeDiscount{}
|
||
switch refresh {
|
||
case true:
|
||
thingDiscount := 50 + rand.Intn(150)
|
||
thing = storeDiscount{
|
||
Name: name,
|
||
Discount: thingDiscount,
|
||
}
|
||
thingInfo := store{}
|
||
_ = sql.db.Find("store", &thingInfo, "where Name = '"+name+"'")
|
||
if thingInfo.Number > 150 {
|
||
// 通货膨胀
|
||
thing.Discount = (1000 - 5*(thingInfo.Number-150)) / 10
|
||
}
|
||
err = sql.db.Insert("stroeDiscount", &thing)
|
||
if err != nil {
|
||
return
|
||
}
|
||
default:
|
||
_ = sql.db.Find("stroeDiscount", &thing, "where Name = '"+name+"'")
|
||
}
|
||
if thing.Discount != 0 {
|
||
discountList[name] = thing.Discount
|
||
} else {
|
||
discountList[name] = 100
|
||
}
|
||
}
|
||
thing := store{}
|
||
oldThing := []store{}
|
||
_ = sql.db.FindFor("stroeDiscount", &thing, "where type = 'pole'", func() error {
|
||
if time.Since(time.Unix(thing.Duration, 0)) > 24 {
|
||
oldThing = append(oldThing, thing)
|
||
}
|
||
return nil
|
||
})
|
||
for _, info := range oldThing {
|
||
_ = sql.db.Del("stroeDiscount", "where Duration = "+strconv.FormatInt(info.Duration, 10))
|
||
}
|
||
if refresh {
|
||
// 每天调控1种鱼
|
||
fish := fishList[rand.Intn(len(fishList))]
|
||
thingInfo := store{
|
||
Duration: time.Now().Unix(),
|
||
Name: fish,
|
||
Type: "fish",
|
||
Price: priceList[fish] * discountList[fish] / 100,
|
||
}
|
||
_ = sql.db.Find("store", &thingInfo, "where Name = '"+fish+"'")
|
||
thingInfo.Number += (100 - discountList[fish])
|
||
if thingInfo.Number < 1 {
|
||
thingInfo.Number = 100
|
||
}
|
||
_ = sql.db.Insert("store", &thingInfo)
|
||
// 每天上架20本净化书
|
||
thingInfo = store{
|
||
Duration: time.Now().Unix(),
|
||
Name: "净化书",
|
||
Type: "article",
|
||
Price: priceList["净化书"] * discountList["净化书"] / 100,
|
||
}
|
||
_ = sql.db.Find("store", &thingInfo, "where Name = '净化书'")
|
||
thingInfo.Number = 20
|
||
_ = sql.db.Insert("store", &thingInfo)
|
||
}
|
||
return true, nil
|
||
}
|
||
|
||
// 获取商店信息
|
||
func (sql *fishdb) getStoreInfo() (thingInfos []store, err error) {
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
thingInfo := store{}
|
||
err = sql.db.Create("store", &thingInfo)
|
||
if err != nil {
|
||
return
|
||
}
|
||
count, err := sql.db.Count("store")
|
||
if err != nil {
|
||
return
|
||
}
|
||
if count == 0 {
|
||
return
|
||
}
|
||
err = sql.db.FindFor("store", &thingInfo, "ORDER by Type, Name, Price ASC", func() error {
|
||
thingInfos = append(thingInfos, thingInfo)
|
||
return nil
|
||
})
|
||
return
|
||
}
|
||
|
||
// 获取商店物品信息
|
||
func (sql *fishdb) getStoreThingInfo(thing string) (thingInfos []store, err error) {
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
thingInfo := store{}
|
||
err = sql.db.Create("store", &thingInfo)
|
||
if err != nil {
|
||
return
|
||
}
|
||
count, err := sql.db.Count("store")
|
||
if err != nil {
|
||
return
|
||
}
|
||
if count == 0 {
|
||
return
|
||
}
|
||
if !sql.db.CanFind("store", "where Name = '"+thing+"'") {
|
||
return
|
||
}
|
||
err = sql.db.FindFor("store", &thingInfo, "where Name = '"+thing+"'", func() error {
|
||
thingInfos = append(thingInfos, thingInfo)
|
||
return nil
|
||
})
|
||
return
|
||
}
|
||
|
||
// 获取商店物品信息
|
||
func (sql *fishdb) checkStoreFor(thing store, number int) (ok bool, err error) {
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
err = sql.db.Create("store", &thing)
|
||
if err != nil {
|
||
return
|
||
}
|
||
count, err := sql.db.Count("store")
|
||
if err != nil {
|
||
return
|
||
}
|
||
if count == 0 {
|
||
return false, nil
|
||
}
|
||
if !sql.db.CanFind("store", "where Duration = "+strconv.FormatInt(thing.Duration, 10)) {
|
||
return false, nil
|
||
}
|
||
err = sql.db.Find("store", &thing, "where Duration = "+strconv.FormatInt(thing.Duration, 10))
|
||
if err != nil {
|
||
return
|
||
}
|
||
if thing.Number < number {
|
||
return false, nil
|
||
}
|
||
return true, nil
|
||
}
|
||
|
||
// 更新商店信息
|
||
func (sql *fishdb) updateStoreInfo(thingInfo store) (err error) {
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
err = sql.db.Create("store", &thingInfo)
|
||
if err != nil {
|
||
return
|
||
}
|
||
if thingInfo.Number == 0 {
|
||
return sql.db.Del("store", "where Duration = "+strconv.FormatInt(thingInfo.Duration, 10))
|
||
}
|
||
return sql.db.Insert("store", &thingInfo)
|
||
}
|
||
|
||
// 更新购买次数
|
||
func (sql *fishdb) updateBuyTimeFor(uid int64, add int) (err error) {
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
userInfo := buffInfo{ID: uid}
|
||
err = sql.db.Create("buff", &userInfo)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
_ = sql.db.Find("buff", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
|
||
userInfo.BuyTimes += add
|
||
if userInfo.BuyTimes > 20 {
|
||
userInfo.BuyTimes -= 20
|
||
userInfo.Coupon = 3
|
||
}
|
||
return sql.db.Insert("buff", &userInfo)
|
||
}
|
||
|
||
// 使用优惠卷
|
||
func (sql *fishdb) useCouponAt(uid int64, times int) (int, error) {
|
||
useTimes := -1
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
userInfo := buffInfo{ID: uid}
|
||
err := sql.db.Create("buff", &userInfo)
|
||
if err != nil {
|
||
return useTimes, err
|
||
}
|
||
_ = sql.db.Find("buff", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
|
||
if userInfo.Coupon > 0 {
|
||
useTimes = math.Min(userInfo.Coupon, times)
|
||
userInfo.Coupon -= useTimes
|
||
}
|
||
return useTimes, sql.db.Insert("buff", &userInfo)
|
||
}
|
||
|
||
// 检测卖鱼竿上限
|
||
func (sql *fishdb) checkCanSalesFor(uid int64, sales bool) (int, error) {
|
||
residue := 0
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
userInfo := buffInfo{ID: uid}
|
||
err := sql.db.Create("buff", &userInfo)
|
||
if err != nil {
|
||
return residue, err
|
||
}
|
||
_ = sql.db.Find("buff", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
|
||
if time.Now().Day() != time.Unix(userInfo.Duration, 0).Day() {
|
||
userInfo.Duration = time.Now().Unix()
|
||
userInfo.SalesPole = 0
|
||
userInfo.BuyTing = 0
|
||
}
|
||
if sales && userInfo.SalesPole < 5 {
|
||
residue = 5 - userInfo.SalesPole
|
||
userInfo.SalesPole++
|
||
} else if userInfo.BuyTing < 15 {
|
||
residue = 15 - userInfo.BuyTing
|
||
userInfo.BuyTing++
|
||
}
|
||
return residue, sql.db.Insert("buff", &userInfo)
|
||
}
|
||
|
||
// 检测物品是否是鱼
|
||
func checkIsFish(thing string) bool {
|
||
for _, v := range fishList {
|
||
if v == thing {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// 检测买卖鱼上限
|
||
func (sql *fishdb) checkCanSalesFishFor(uid int64, sales int) (int, error) {
|
||
residue := 0
|
||
sql.Lock()
|
||
defer sql.Unlock()
|
||
userInfo := buffInfo{ID: uid}
|
||
err := sql.db.Create("buff", &userInfo)
|
||
if err != nil {
|
||
return residue, err
|
||
}
|
||
_ = sql.db.Find("buff", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
|
||
if time.Now().Day() != time.Unix(userInfo.Duration, 0).Day() {
|
||
userInfo.Duration = time.Now().Unix()
|
||
userInfo.SalesFish = 0
|
||
}
|
||
maxSales := 100 - userInfo.SalesFish
|
||
if maxSales < 0 {
|
||
maxSales = 0
|
||
}
|
||
if sales > maxSales {
|
||
sales = maxSales
|
||
}
|
||
userInfo.SalesFish += sales
|
||
return sales, sql.db.Insert("buff", &userInfo)
|
||
}
|