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.
88 lines
2.3 KiB
Go
88 lines
2.3 KiB
Go
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
|
|
}
|