package models import ( "fmt" "strings" "time" "gorm.io/driver/mysql" "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" "gorm.io/gorm/logger" ) var db *gorm.DB var JD_COOKIE = "JD_COOKIE" var RECORD = "RECORD" var ENV = "env" var TASK = "TASK" var keys map[string]bool var pins map[string]bool func initDB() { var err error var c = &gorm.Config{ Logger: logger.Default.LogMode(logger.Info), } if strings.Contains(Config.Database, "@tcp(") { db, err = gorm.Open(mysql.Open(Config.Database), c) } else if strings.Contains(Config.Database, "dbname=") { db, err = gorm.Open(postgres.Open(Config.Database), c) } else { db, err = gorm.Open(sqlite.Open(Config.Database), c) } if err != nil { panic(err) } db.AutoMigrate( &JdCookie{}, &JdCookiePool{}, &User{}, ) keys = make(map[string]bool) pins = make(map[string]bool) jps := []JdCookiePool{} db.Find(&jps) for _, jp := range jps { keys[jp.PtKey] = true pins[jp.PtPin] = true } } func HasPin(pin string) bool { if _, ok := pins[pin]; ok { return ok } pins[pin] = true return false } func HasKey(key string) bool { if _, ok := keys[key]; ok { return ok } keys[key] = true return false } type JdCookie struct { ID int `gorm:"column:ID;primaryKey"` Priority int `gorm:"column:Priority;default:1"` CreateAt string `gorm:"column:CreateAt"` PtKey string `gorm:"column:PtKey"` PtPin string `gorm:"column:PtPin;unique"` Note string `gorm:"column:Note"` Available string `gorm:"column:Available;default:true" validate:"oneof=true false"` Nickname string `gorm:"column:Nickname"` BeanNum string `gorm:"column:BeanNum"` QQ int `gorm:"column:QQ"` PushPlus string `gorm:"column:PushPlus"` Telegram int `gorm:"column:Telegram"` Fruit string `gorm:"column:Fruit"` Pet string `gorm:"column:Pet"` Bean string `gorm:"column:Bean"` JdFactory string `gorm:"column:JdFactory"` DreamFactory string `gorm:"column:DreamFactory"` Jxnc string `gorm:"column:Jxnc"` Jdzz string `gorm:"column:Jdzz"` Joy string `gorm:"column:Joy"` Sgmh string `gorm:"column:Sgmh"` Cfd string `gorm:"column:Cfd"` Cash string `gorm:"column:Cash"` Help string `gorm:"column:Help;default:false" validate:"oneof=true false"` Pool string `gorm:"-"` Hack string `gorm:"column:Hack" validate:"oneof=true false"` } type JdCookiePool struct { ID int `gorm:"column:ID;primaryKey"` PtKey string `gorm:"column:PtKey;unique"` PtPin string `gorm:"column:PtPin"` LoseAt string `gorm:"column:LoseAt"` CreateAt string `gorm:"column:CreateAt"` } var ScanedAt = "ScanedAt" var LoseAt = "LoseAt" var CreateAt = "CreateAt" var Note = "Note" var Available = "Available" var UnAvailable = "UnAvailable" var PtKey = "PtKey" var PtPin = "PtPin" var Priority = "Priority" var Nickname = "Nickname" var BeanNum = "BeanNum" var Pool = "Pool" var True = "true" var False = "false" var QQ = "QQ" var PushPlus = "PushPlus" var Save chan *JdCookie var ExecPath string var Telegram = "Telegram" var Hack = "Hack" const ( Fruit = "Fruit" Pet = "Pet" Bean = "Bean" JdFactory = "JdFactory" DreamFactory = "DreamFactory" Jxnc = "Jxnc" Jdzz = "Jdzz" Joy = "Joy" Sgmh = "Sgmh" Cfd = "Cfd" Cash = "Cash" Help = "Help" ) func Date() string { return time.Now().Local().Format("2006-01-02") } func GetJdCookies() []JdCookie { cks := []JdCookie{} db.Order("priority desc").Find(&cks) return cks } func GetJdCookie(pin string) (*JdCookie, error) { ck := &JdCookie{} return ck, db.Where(PtPin+" = ?", pin).First(ck).Error } func (ck *JdCookie) Updates(values interface{}) { if ck.ID != 0 { db.Model(ck).Updates(values) } if ck.PtPin != "" { db.Model(ck).Where(PtPin+" = ?", ck.PtPin).Updates(values) } } func (ck *JdCookie) Update(column string, value interface{}) { if ck.ID != 0 { db.Model(ck).Update(column, value) } if ck.PtPin != "" { db.Model(JdCookie{}).Where(PtPin+" = ?", ck.PtPin).Update(column, value) } } func (ck *JdCookie) InPool(pt_key string) error { if ck.ID != 0 { date := Date() tx := db.Begin() jp := &JdCookiePool{} if tx.Where(fmt.Sprintf("%s = '%s' and %s = '%s'", PtPin, ck.PtPin, PtKey, pt_key)).First(jp).Error == nil { return tx.Rollback().Error } if err := tx.Create(&JdCookiePool{ PtPin: ck.PtPin, PtKey: pt_key, CreateAt: date, }).Error; err != nil { tx.Rollback() return err } tx.Model(ck).Updates(map[string]interface{}{ Available: True, PtKey: pt_key, }) return tx.Commit().Error } return nil } func (ck *JdCookie) OutPool() (string, error) { if ck.ID != 0 { date := Date() tx := db.Begin() jp := &JdCookiePool{} tx.Model(jp).Where(fmt.Sprintf("%s = '%s' and %s = '%s'", PtPin, ck.PtPin, PtKey, ck.PtKey)).Update(LoseAt, date) us := map[string]interface{}{} if tx.Where(fmt.Sprintf("%s = '%s' and %s = '%s'", PtPin, ck.PtPin, LoseAt, "")).First(jp).Error != nil { us[Available] = False us[PtKey] = "" } else { us[Available] = True us[PtKey] = jp.PtKey } e := tx.Model(ck).Updates(us).RowsAffected if e == 0 { tx.Rollback() return "", nil } ck.Available = us[Available].(string) ck.PtKey = jp.PtKey return jp.PtKey, tx.Commit().Error } return "", nil } func NewJdCookie(ck *JdCookie) error { if ck.Hack == "" { ck.Hack = False } ck.Priority = Config.DefaultPriority date := Date() ck.CreateAt = date tx := db.Begin() if err := tx.Create(ck).Error; err != nil { tx.Rollback() return err } if err := tx.Create(&JdCookiePool{ PtPin: ck.PtPin, PtKey: ck.PtKey, CreateAt: date, }).Error; err != nil { tx.Rollback() return err } return tx.Commit().Error } func CheckIn(pin, key string) int { if !HasPin(pin) { NewJdCookie(&JdCookie{ PtKey: key, PtPin: pin, Hack: False, }) return 0 } else if !HasKey(key) { ck, _ := GetJdCookie(pin) ck.InPool(key) return 1 } return 2 }