diff --git a/api/club.go b/api/club.go index 99dc148..b77b9fe 100644 --- a/api/club.go +++ b/api/club.go @@ -24,7 +24,7 @@ func ApiClubList(c *gin.Context) { ret.List = make([]item, 0, Clubs.Len()) for cid, club := range Clubs.Items() { - ret.List = append(ret.List, item{CID: cid, Name: club.Name}) + ret.List = append(ret.List, item{CID: cid, Name: club.Name()}) } RetOk(c, ret) @@ -59,14 +59,14 @@ func ApiClubIs(c *gin.Context) { if ai.CID != 0 { var club *Club if club, ok = Clubs.Get(ai.CID); ok { - ri.CID = club.CID - ri.Name = club.Name + ri.CID = club.CID() + ri.Name = club.Name() } } else { for _, club := range Clubs.Items() { - if club.Name == ai.Name { - ri.CID = club.CID - ri.Name = club.Name + if name := club.Name(); name == ai.Name { + ri.CID = club.CID() + ri.Name = name break } } @@ -86,13 +86,8 @@ func ApiClubInfo(c *gin.Context) { CID uint64 `json:"cid" yaml:"cid" xml:"cid,attr" form:"cid" binding:"required"` } var ret struct { - XMLName xml.Name `json:"-" yaml:"-" xml:"ret"` - Name string `json:"name,omitempty" yaml:"name,omitempty" xml:"name,omitempty"` - Bank float64 `json:"bank" yaml:"bank" xml:"bank"` // users win/lost balance, in coins - Fund float64 `json:"fund" yaml:"fund" xml:"fund"` // jackpot fund, in coins - Lock float64 `json:"lock" yaml:"lock" xml:"lock"` // not changed deposit within games - Rate float64 `json:"rate" yaml:"rate" xml:"rate"` // jackpot rate for games with progressive jackpot - MRTP float64 `json:"mrtp" yaml:"mrtp" xml:"mrtp"` // master RTP + XMLName xml.Name `json:"-" yaml:"-" xml:"ret"` + ClubData `yaml:",inline"` } if err = c.ShouldBind(&arg); err != nil { @@ -112,14 +107,7 @@ func ApiClubInfo(c *gin.Context) { return } - club.mux.Lock() - ret.Name = club.Name - ret.Bank = club.Bank - ret.Fund = club.Fund - ret.Lock = club.Lock - ret.Rate = club.Rate - ret.MRTP = club.MRTP - club.mux.Unlock() + ret.ClubData = club.Get() RetOk(c, ret) } @@ -151,14 +139,12 @@ func ApiClubRename(c *gin.Context) { return } - if _, err = cfg.XormStorage.ID(club.CID).Cols("name").Update(&Club{Name: arg.Name}); err != nil { + if _, err = cfg.XormStorage.ID(club.CID()).Cols("name").Update(&ClubData{Name: arg.Name}); err != nil { Ret500(c, AEC_club_rename_update, err) return } - club.mux.Lock() - club.Name = arg.Name - club.mux.Unlock() + club.SetName(arg.Name) Ret204(c) } @@ -203,11 +189,10 @@ func ApiClubCashin(c *gin.Context) { return } - club.mux.Lock() - var bank = club.Bank + arg.BankSum - var fund = club.Fund + arg.FundSum - var lock = club.Lock + arg.LockSum - club.mux.Unlock() + var bank, fund, lock = club.GetCash() + bank += arg.BankSum + fund += arg.FundSum + lock += arg.LockSum if bank < 0 { Ret403(c, AEC_club_cashin_bankout, ErrBankOut) @@ -231,7 +216,7 @@ func ApiClubCashin(c *gin.Context) { LockSum: arg.LockSum, } if err = SafeTransaction(cfg.XormStorage, func(session *Session) (err error) { - if _, err = session.Exec(sqlclub, arg.BankSum, arg.FundSum, arg.LockSum, club.CID); err != nil { + if _, err = session.Exec(sqlclub, arg.BankSum, arg.FundSum, arg.LockSum, club.CID()); err != nil { Ret500(c, AEC_club_cashin_sqlbank, err) return } @@ -245,11 +230,7 @@ func ApiClubCashin(c *gin.Context) { } // make changes to memory data - club.mux.Lock() - club.Bank += arg.BankSum - club.Fund += arg.FundSum - club.Lock += arg.LockSum - club.mux.Unlock() + club.AddCash(arg.BankSum, arg.FundSum, arg.LockSum) ret.BID = rec.ID ret.Bank = bank diff --git a/api/keno.go b/api/keno.go index 941957d..9f8ed10 100644 --- a/api/keno.go +++ b/api/keno.go @@ -320,9 +320,7 @@ func ApiKenoSpin(c *gin.Context) { return } - club.mux.RLock() - var bank = club.Bank - club.mux.RUnlock() + var bank = club.Bank() var mrtp = GetRTP(user, club) // spin until gain less than bank value @@ -352,9 +350,7 @@ func ApiKenoSpin(c *gin.Context) { } // make changes to memory data - club.mux.Lock() - club.Bank += banksum - club.mux.Unlock() + club.AddBank(banksum) props.Wallet -= banksum // write spin result to log and get spin ID diff --git a/api/logic.go b/api/logic.go index 0c968bb..dde2e90 100644 --- a/api/logic.go +++ b/api/logic.go @@ -9,8 +9,7 @@ import ( "github.com/slotopol/server/util" ) -// Club means independent bank into which gambles some users. -type Club struct { +type ClubData struct { CID uint64 `xorm:"pk autoincr" json:"cid" yaml:"cid" xml:"cid,attr"` // club ID CTime time.Time `xorm:"created 'ctime' notnull default CURRENT_TIMESTAMP" json:"ctime" yaml:"ctime" xml:"ctime"` // creation time UTime time.Time `xorm:"updated 'utime' notnull default CURRENT_TIMESTAMP" json:"utime" yaml:"utime" xml:"utime"` // update time @@ -20,8 +19,16 @@ type Club struct { Lock float64 `xorm:"notnull default 0" json:"lock" yaml:"lock" xml:"lock"` // not changed deposit within games Rate float64 `xorm:"'rate' notnull default 2.5" json:"rate" yaml:"rate" xml:"rate"` // jackpot rate for games with progressive jackpot MRTP float64 `xorm:"'mrtp' notnull default 0" json:"mrtp" yaml:"mrtp" xml:"mrtp"` // master RTP +} - mux sync.RWMutex +func (ClubData) TableName() string { + return "club" +} + +// Club means independent bank into which gambles some users. +type Club struct { + data ClubData + mux sync.RWMutex } // User flag. @@ -154,6 +161,94 @@ var Users util.RWMap[uint64, *User] // All scenes, by GID. var Scenes util.RWMap[uint64, *Scene] +func MakeClub(cd ClubData) *Club { + return &Club{data: cd} +} + +func (club *Club) Get() ClubData { + club.mux.RLock() + defer club.mux.RUnlock() + return club.data +} + +func (club *Club) CID() uint64 { // read only + return club.data.CID +} + +func (club *Club) Name() string { + club.mux.RLock() + defer club.mux.RUnlock() + return club.data.Name +} + +func (club *Club) SetName(name string) { + club.mux.Lock() + defer club.mux.Unlock() + club.data.Name = name +} + +func (club *Club) Bank() float64 { + club.mux.RLock() + defer club.mux.RUnlock() + return club.data.Bank +} + +func (club *Club) Fund() float64 { + club.mux.RLock() + defer club.mux.RUnlock() + return club.data.Fund +} + +func (club *Club) Deposit() float64 { + club.mux.RLock() + defer club.mux.RUnlock() + return club.data.Lock +} + +func (club *Club) GetCash() (bank, fund, deposit float64) { + club.mux.RLock() + defer club.mux.RUnlock() + return club.data.Bank, club.data.Fund, club.data.Lock +} + +func (club *Club) AddCash(bank, fund, deposit float64) { + club.mux.Lock() + defer club.mux.Unlock() + club.data.Bank += bank + club.data.Fund += fund + club.data.Lock += deposit +} + +func (club *Club) AddBank(bank float64) { + club.mux.Lock() + defer club.mux.Unlock() + club.data.Bank += bank +} + +func (club *Club) AddFund(fund float64) { + club.mux.Lock() + defer club.mux.Unlock() + club.data.Fund += fund +} + +func (club *Club) AddDeposit(deposit float64) { + club.mux.Lock() + defer club.mux.Unlock() + club.data.Lock += deposit +} + +func (club *Club) Rate() float64 { + club.mux.RLock() + defer club.mux.RUnlock() + return club.data.Rate +} + +func (club *Club) MRTP() float64 { + club.mux.RLock() + defer club.mux.RUnlock() + return club.data.MRTP +} + func (user *User) Init() { user.games.Init(0) user.props.Init(0) @@ -205,14 +300,12 @@ func MustAdmin(c *gin.Context, cid uint64) (*User, AL) { func GetRTP(user *User, club *Club) float64 { if user != nil { - if props, ok := user.props.Get(club.CID); ok && props.MRTP != 0 { + if props, ok := user.props.Get(club.CID()); ok && props.MRTP != 0 { return props.MRTP } } - club.mux.RLock() - defer club.mux.RUnlock() - if club.MRTP != 0 { - return club.MRTP + if mrtp := club.MRTP(); mrtp != 0 { + return mrtp } return cfg.DefMRTP // default master RTP if no others found } diff --git a/api/slot.go b/api/slot.go index 0cc3dfc..621700a 100644 --- a/api/slot.go +++ b/api/slot.go @@ -284,9 +284,7 @@ func ApiSlotSpin(c *gin.Context) { return } - club.mux.RLock() - var bank = club.Bank - club.mux.RUnlock() + var bank = club.Bank() var mrtp = GetRTP(user, club) // spin until gain less than bank value @@ -321,9 +319,7 @@ func ApiSlotSpin(c *gin.Context) { } // make changes to memory data - club.mux.Lock() - club.Bank += banksum - club.mux.Unlock() + club.AddBank(banksum) props.Wallet -= banksum game.Apply(scrn, wins) @@ -434,9 +430,7 @@ func ApiSlotDoubleup(c *gin.Context) { return } - club.mux.RLock() - var bank = club.Bank - club.mux.RUnlock() + var bank = club.Bank() var mrtp = GetRTP(user, club) var multgain float64 // new multiplied gain @@ -458,10 +452,7 @@ func ApiSlotDoubleup(c *gin.Context) { } // make changes to memory data - club.mux.Lock() - club.Bank += banksum - club.mux.Unlock() - + club.AddBank(banksum) props.Wallet -= banksum game.SetGain(multgain) diff --git a/api/user.go b/api/user.go index df6c684..1a454b6 100644 --- a/api/user.go +++ b/api/user.go @@ -214,7 +214,7 @@ func ApiUserDelete(c *gin.Context) { for cid, props := range user.props.Items() { ret.Wallets[cid] = props.Wallet if club, ok := Clubs.Get(cid); ok && props.Wallet != 0 { - club.Lock += float64(props.Wallet) + club.AddDeposit(props.Wallet) ret.Wallets[cid] = props.Wallet } } diff --git a/cmd/startup.go b/cmd/startup.go index 00a890f..251f167 100644 --- a/cmd/startup.go +++ b/cmd/startup.go @@ -152,16 +152,16 @@ func InitStorage() (err error) { var offset = 0 for { - var chunk []*api.Club + var chunk []api.ClubData if err = session.Limit(limit, offset).Find(&chunk); err != nil { return } offset += limit - for _, club := range chunk { - api.Clubs.Set(club.CID, club) + for _, cd := range chunk { + api.Clubs.Set(cd.CID, api.MakeClub(cd)) var bat = &api.SqlBank{} - bat.Init(club.CID, Cfg.ClubUpdateBuffer, Cfg.ClubInsertBuffer) - api.BankBat[club.CID] = bat + bat.Init(cd.CID, Cfg.ClubUpdateBuffer, Cfg.ClubInsertBuffer) + api.BankBat[cd.CID] = bat } if limit > len(chunk) { break