feat(all): add hunting and events, commerce and rewards, binary calendars, GameData caching and login diagnostics
Implement hunting AP and progress, event tasks, exchanges, games, stories and actions; connect battle and reward handling. Add CashShop plugin and installation, server purchases and entitlements, recharge rules and plugin version metadata. Distribute binary calendars independently; cache GameData in memory and fix single-connection query deadlocks. Improve automatic login and recovery diagnostics; document configuration and release flows.
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
package eventgames
|
||||
|
||||
import (
|
||||
"bd2server/internal/server/gamedata"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func validateSaved(key string, g GameState, d *gamedata.EventGame) error {
|
||||
if key != strconv.FormatUint(g.UID, 10) || g.ID != d.ID || g.Type != d.Type {
|
||||
return fmt.Errorf("eventgames: invalid saved identity")
|
||||
}
|
||||
if g.Type == 12 {
|
||||
if g.Position >= uint64(len(d.Cells)) {
|
||||
return fmt.Errorf("eventgames: invalid saved position")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if g.Type == 19 {
|
||||
if g.Free > d.Free || g.SinceSpecial > g.Tries {
|
||||
return fmt.Errorf("eventgames: invalid saved roulette counters")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
expected := 0
|
||||
for _, r := range d.Cells {
|
||||
if r.Count == rewardCount(d, g.Clear) {
|
||||
expected++
|
||||
}
|
||||
}
|
||||
if len(g.Board) != expected || expected == 0 {
|
||||
return fmt.Errorf("eventgames: saved board size differs from design")
|
||||
}
|
||||
if g.Type == 13 && (d.Columns == 0 || uint64(expected) != d.Columns*d.Columns) {
|
||||
return fmt.Errorf("eventgames: invalid bingo board dimensions")
|
||||
}
|
||||
seen := map[uint64]bool{}
|
||||
for _, id := range g.Board {
|
||||
if seen[id] {
|
||||
return fmt.Errorf("eventgames: duplicate saved board tile")
|
||||
}
|
||||
seen[id] = true
|
||||
found := false
|
||||
for _, r := range d.Cells {
|
||||
if r.ID == id && r.Count == rewardCount(d, g.Clear) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return fmt.Errorf("eventgames: saved tile outside design")
|
||||
}
|
||||
}
|
||||
seen = map[uint64]bool{}
|
||||
for _, id := range g.Opened {
|
||||
if seen[id] || g.Type == 13 && id >= uint64(len(g.Board)) || g.Type == 17 && !contains(g.Board, id) {
|
||||
return fmt.Errorf("eventgames: invalid saved open tile")
|
||||
}
|
||||
seen[id] = true
|
||||
}
|
||||
lineSeen := map[uint64]bool{}
|
||||
for _, key := range g.Lines {
|
||||
if lineSeen[key] {
|
||||
return fmt.Errorf("eventgames: duplicate saved line")
|
||||
}
|
||||
lineSeen[key] = true
|
||||
found := false
|
||||
for _, r := range d.Lines {
|
||||
if g.Type == 13 && r.Count == rewardCount(d, g.Clear) && key == r.LineType*1000+r.LineIndex && completeLine(&g, d.Columns, r.LineType, r.LineIndex) {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
for _, r := range d.Complete {
|
||||
if g.Type == 17 && r.Count == g.Clear && r.ID == key {
|
||||
all := true
|
||||
for _, id := range r.Members {
|
||||
all = all && contains(g.Opened, id)
|
||||
}
|
||||
found = all
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return fmt.Errorf("eventgames: saved completed line invalid")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user