package main import ( "crypto/hmac" "crypto/sha256" "database/sql" "encoding/binary" "encoding/hex" "fmt" "log" "time" _ "github.com/go-sql-driver/mysql" ) func main() { dsn := "root:bindbox2025kdy@tcp(150.158.78.154:3306)/dev_game?parseTime=true" db, err := sql.Open("mysql", dsn) if err != nil { log.Fatal("Connection failed:", err) } defer db.Close() orderNo := "O20260125201015731" fmt.Printf("Querying Order: %s\n", orderNo) var id, userID int64 var status, sourceType int32 var total, discount, actual int64 var remark, createdAt string // Check Order err = db.QueryRow("SELECT id, user_id, status, source_type, total_amount, discount_amount, actual_amount, remark, created_at FROM orders WHERE order_no = ?", orderNo). Scan(&id, &userID, &status, &sourceType, &total, &discount, &actual, &remark, &createdAt) if err != nil { log.Fatalf("Order not found: %v", err) } fmt.Printf("ID: %d\nUser: %d\nStatus: %d (1=Pending, 2=Paid)\nSourceType: %d\nTotal: %d\nDiscount: %d\nActual: %d\nRemark: %s\nCreated: %s\n", id, userID, status, sourceType, total, discount, actual, remark, createdAt) // Check Draw Logs rows, err := db.Query("SELECT id, reward_id, is_winner, draw_index, created_at FROM activity_draw_logs WHERE order_id = ?", id) if err != nil { log.Fatal("Query logs failed:", err) } defer rows.Close() fmt.Println("\n--- Draw Logs ---") count := 0 for rows.Next() { var logID, rID, dIdx int64 var isWinner int32 var ca time.Time rows.Scan(&logID, &rID, &isWinner, &dIdx, &ca) fmt.Printf("LogID: %d, RewardID: %d, IsWinner: %d, DrawIndex: %d, Time: %s\n", logID, rID, isWinner, dIdx, ca) count++ } if count == 0 { fmt.Println("No draw logs found.") } // Check Inventory (Grants) rowsInv, err := db.Query("SELECT id, reward_id, product_id, status FROM user_inventory WHERE order_id = ?", id) if err != nil { log.Fatal("Query inventory failed:", err) } defer rowsInv.Close() fmt.Println("\n--- Inventory (Grants) ---") invCount := 0 for rowsInv.Next() { var invID, rID, pID int64 var s int rowsInv.Scan(&invID, &rID, &pID, &s) fmt.Printf("InvID: %d, RewardID: %d, ProductID: %d, Status: %d\n", invID, rID, pID, s) invCount++ } if invCount == 0 { fmt.Println("No inventory grants found.") } // Check Issue 104 fmt.Println("\n--- Issue 104 ---") var actID int64 var issueNumber string err = db.QueryRow("SELECT activity_id, issue_number FROM activity_issues WHERE id = 104").Scan(&actID, &issueNumber) if err != nil { fmt.Printf("Issue query failed: %v\n", err) } else { fmt.Printf("Issue Number: %s, ActivityID: %d\n", issueNumber, actID) // Query Activity by ID var actName, playType string err = db.QueryRow("SELECT name, play_type FROM activities WHERE id = ?", actID).Scan(&actName, &playType) if err != nil { fmt.Printf("Activity query failed: %v\n", err) } else { fmt.Printf("Activity: %s, PlayType: %s\n", actName, playType) // Reconstruct Game fmt.Println("\n--- Reconstructing Game ---") // Fetch Draw Log var drawLogID, issueID int64 err = db.QueryRow("SELECT id, issue_id FROM activity_draw_logs WHERE order_id = ?", id).Scan(&drawLogID, &issueID) if err != nil { log.Fatal("Draw log not found:", err) } // Fetch Receipt var subSeedHex, position string err = db.QueryRow("SELECT server_sub_seed, client_seed FROM activity_draw_receipts WHERE draw_log_id = ?", drawLogID).Scan(&subSeedHex, &position) if err != nil { log.Printf("Receipt not found: %v", err) return } fmt.Printf("Receipt Found. SubSeed: %s, Position (ClientSeed): %s\n", subSeedHex, position) serverSeed, err := hex.DecodeString(subSeedHex) if err != nil { log.Fatal("Invalid seed hex:", err) } // Fetch Card Configs rowsCards, err := db.Query("SELECT code, name, quantity FROM matching_card_types WHERE status=1 ORDER BY sort ASC") if err != nil { log.Fatal("Card types query failed:", err) } defer rowsCards.Close() type CardTypeConfig struct { Code string Name string Quantity int32 } var configs []CardTypeConfig for rowsCards.Next() { var c CardTypeConfig rowsCards.Scan(&c.Code, &c.Name, &c.Quantity) configs = append(configs, c) } // Create Game Logic fmt.Println("Simulating Game Logic...") cardIDCounter := int64(0) type MatchingCard struct { ID string Type string } var deck []*MatchingCard for _, cfg := range configs { for i := int32(0); i < cfg.Quantity; i++ { cardIDCounter++ deck = append(deck, &MatchingCard{ ID: fmt.Sprintf("c%d", cardIDCounter), Type: cfg.Code, }) } } // SecureShuffle secureRandInt := func(max int, context string, nonce *int64) int { *nonce++ message := fmt.Sprintf("%s|nonce:%d", context, *nonce) mac := hmac.New(sha256.New, serverSeed) mac.Write([]byte(message)) sum := mac.Sum(nil) val := binary.BigEndian.Uint64(sum[:8]) return int(val % uint64(max)) } nonce := int64(0) n := len(deck) for i := n - 1; i > 0; i-- { j := secureRandInt(i+1, fmt.Sprintf("shuffle:%d", i), &nonce) deck[i], deck[j] = deck[j], deck[i] } // Distribute to Board (first 9) board := make([]*MatchingCard, 9) for i := 0; i < 9; i++ { if len(deck) > 0 { board[i] = deck[0] deck = deck[1:] } } fmt.Printf("Board Types: ") for _, c := range board { if c != nil { fmt.Printf("%s ", c.Type) } } fmt.Println() // SimulateMaxPairs // Reconstruct allCards (Board + Deck) allCards := make([]*MatchingCard, 0, len(board)+len(deck)) for _, c := range board { if c != nil { allCards = append(allCards, c) } } allCards = append(allCards, deck...) selectedType := position hand := make([]*MatchingCard, 9) copy(hand, allCards[:9]) deckIndex := 9 chance := int64(0) for _, c := range hand { if c != nil && c.Type == selectedType { chance++ } } fmt.Printf("Selected Type: %s, Initial Chance: %d\n", selectedType, chance) totalPairs := int64(0) guard := 0 for guard < 1000 { guard++ // canEliminate counts := make(map[string]int) pairType := "" for _, c := range hand { if c == nil { continue } counts[c.Type]++ if counts[c.Type] >= 2 { pairType = c.Type break } } if pairType != "" { // Eliminate first, second := -1, -1 for i, c := range hand { if c == nil || c.Type != pairType { continue } if first < 0 { first = i } else { second = i break } } if first >= 0 && second >= 0 { newHand := make([]*MatchingCard, 0, len(hand)-2) for i, c := range hand { if i != first && i != second { newHand = append(newHand, c) } } hand = newHand totalPairs++ chance++ continue } } // Draw if chance > 0 && deckIndex < len(allCards) { newCard := allCards[deckIndex] hand = append(hand, newCard) deckIndex++ chance-- continue } break } fmt.Printf("Simulation Finished. Total Pairs: %d\n", totalPairs) // Check Rewards rowsRewards, err := db.Query("SELECT id, min_score, product_id, quantity, level FROM activity_reward_settings WHERE issue_id = ?", issueID) if err != nil { log.Printf("Query rewards failed: %v", err) } else { defer rowsRewards.Close() fmt.Println("\n--- Matching Rewards ---") found := false for rowsRewards.Next() { var rwID, minScore, pID int64 var qty, level int32 rowsRewards.Scan(&rwID, &minScore, &pID, &qty, &level) if int64(minScore) == totalPairs { var pName string _ = db.QueryRow("SELECT name FROM products WHERE id=?", pID).Scan(&pName) fmt.Printf("MATCH! RewardID: %d, ProductID: %d (%s), Qty: %d, Level: %d\n", rwID, pID, pName, qty, level) found = true } } if !found { fmt.Println("No matching reward found for this score.") } } } } }