187 lines
5.5 KiB
Go
187 lines
5.5 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/golang-jwt/jwt/v4"
|
|
"gorm.io/driver/mysql"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// Configs from dev_configs.toml
|
|
const (
|
|
DbDSN = "root:bindbox2025kdy@tcp(150.158.78.154:3306)/dev_game?charset=utf8mb4&parseTime=True&loc=Local"
|
|
JwtSecret = "AppUserJwtSecret2025"
|
|
ApiURL = "http://127.0.0.1:9991/api/app/lottery/join"
|
|
)
|
|
|
|
type UserItemCards struct {
|
|
ID int64 `gorm:"column:id"`
|
|
Status int32 `gorm:"column:status"`
|
|
UsedAt time.Time `gorm:"column:used_at"`
|
|
UsedActivityID int64 `gorm:"column:used_activity_id"`
|
|
UsedIssueID int64 `gorm:"column:used_issue_id"`
|
|
UsedDrawLogID int64 `gorm:"column:used_draw_log_id"`
|
|
}
|
|
|
|
func (UserItemCards) TableName() string { return "user_item_cards" }
|
|
|
|
func main() {
|
|
// 1. Connect DB
|
|
db, err := gorm.Open(mysql.Open(DbDSN), &gorm.Config{})
|
|
if err != nil {
|
|
log.Fatalf("DB connection failed: %v", err)
|
|
}
|
|
|
|
// 2. Reset Item Card 836
|
|
cardID := int64(836)
|
|
fmt.Printf("Restoring UserItemCard %d...\n", cardID)
|
|
// We set status to 1 and clear used fields
|
|
res := db.Model(&UserItemCards{}).Where("id = ?", cardID).Updates(map[string]interface{}{
|
|
"status": 1,
|
|
"used_at": nil,
|
|
"used_activity_id": 0,
|
|
"used_issue_id": 0,
|
|
"used_draw_log_id": 0,
|
|
})
|
|
if res.Error != nil {
|
|
log.Fatalf("Failed to restore card: %v", res.Error)
|
|
}
|
|
fmt.Println("Card restored to Status 1.")
|
|
|
|
// 3. Generate JWT
|
|
tokenString, err := generateToken(9090, JwtSecret)
|
|
if err != nil {
|
|
log.Fatalf("Failed to generate token: %v", err)
|
|
}
|
|
fmt.Printf("Generated Token for User 9090.\n")
|
|
|
|
// 4. Send API Request
|
|
targetSlot := int64(1)
|
|
|
|
reqBody := map[string]interface{}{
|
|
"activity_id": 94,
|
|
"issue_id": 105,
|
|
"count": 1,
|
|
"slot_index": []int64{targetSlot},
|
|
"item_card_id": cardID,
|
|
"channel": "simulation",
|
|
}
|
|
jsonBody, _ := json.Marshal(reqBody)
|
|
|
|
req, _ := http.NewRequest("POST", ApiURL, bytes.NewBuffer(jsonBody))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
// Backend seems to expect raw token string without Bearer prefix
|
|
req.Header.Set("Authorization", tokenString)
|
|
|
|
client := &http.Client{}
|
|
fmt.Println("Sending JoinLottery request...")
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
log.Fatalf("Request failed: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
body, _ := io.ReadAll(resp.Body)
|
|
fmt.Printf("Response Status: %s\n", resp.Status)
|
|
fmt.Printf("Response Body: %s\n", string(body))
|
|
|
|
// If success (200 OK), parse order info, simulate payment, trigger draw
|
|
if resp.StatusCode == 200 {
|
|
var resMap map[string]interface{}
|
|
json.Unmarshal(body, &resMap)
|
|
// joinID := resMap["join_id"].(string) // Unused
|
|
orderNo := resMap["order_no"].(string)
|
|
|
|
fmt.Printf("Order Created: %s. Simulating Payment...\n", orderNo)
|
|
|
|
// Simulate Payment in DB
|
|
db.Table("orders").Where("order_no = ?", orderNo).Updates(map[string]interface{}{
|
|
"status": 2,
|
|
"paid_at": time.Now(),
|
|
})
|
|
fmt.Println("Order marked as PAID (Status 2).")
|
|
|
|
// Trigger Draw via GetLotteryResult with order_no
|
|
resultURL := fmt.Sprintf("http://127.0.0.1:9991/api/app/lottery/result?order_no=%s", orderNo)
|
|
reqResult, _ := http.NewRequest("GET", resultURL, nil)
|
|
reqResult.Header.Set("Authorization", tokenString)
|
|
|
|
fmt.Println("Triggering Draw (GetLotteryResult)...")
|
|
respResult, err := client.Do(reqResult)
|
|
if err != nil {
|
|
log.Fatalf("Result Request failed: %v", err)
|
|
}
|
|
defer respResult.Body.Close()
|
|
bodyResult, _ := io.ReadAll(respResult.Body)
|
|
fmt.Printf("Draw Response: %s\n", string(bodyResult))
|
|
|
|
time.Sleep(2 * time.Second)
|
|
checkLogs(db, cardID)
|
|
}
|
|
}
|
|
|
|
func generateToken(userID int64, secret string) (string, error) {
|
|
// Claims mimicking bindbox-game/internal/pkg/jwtoken/jwtoken.go structure
|
|
claims := jwt.MapClaims{
|
|
"id": int32(userID),
|
|
"username": "simulation",
|
|
"nickname": "simulation_user",
|
|
"is_super": 0,
|
|
"platform": "simulation",
|
|
// Standard claims
|
|
"exp": time.Now().Add(time.Hour).Unix(),
|
|
"iat": time.Now().Unix(),
|
|
"nbf": time.Now().Unix(),
|
|
}
|
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
|
return token.SignedString([]byte(secret))
|
|
}
|
|
|
|
func checkLogs(db *gorm.DB, cardID int64) {
|
|
fmt.Println("\n--- Verification Results ---")
|
|
// Check Card Status
|
|
var card UserItemCards
|
|
if err := db.First(&card, cardID).Error; err != nil {
|
|
fmt.Printf("Error fetching card: %v\n", err)
|
|
return
|
|
}
|
|
fmt.Printf("Card Status: %d (Expected 2 if success)\n", card.Status)
|
|
|
|
if card.Status == 2 {
|
|
fmt.Printf("Card Used At: %v\n", card.UsedAt)
|
|
fmt.Printf("Used Draw Log ID: %d\n", card.UsedDrawLogID)
|
|
|
|
if card.UsedDrawLogID > 0 {
|
|
// Check Draw Log
|
|
type ActivityDrawLogs struct {
|
|
ID int64 `gorm:"column:id"`
|
|
RewardID int64 `gorm:"column:reward_id"`
|
|
OrderID int64 `gorm:"column:order_id"`
|
|
}
|
|
var dl ActivityDrawLogs
|
|
db.Table("activity_draw_logs").First(&dl, card.UsedDrawLogID)
|
|
fmt.Printf("Original Draw Reward ID: %d, Order ID: %d\n", dl.RewardID, dl.OrderID)
|
|
|
|
// Check Inventory Count for this Order (Should be > 1 if doubled)
|
|
var inventoryCount int64
|
|
db.Table("user_inventory").Where("order_id = ?", dl.OrderID).Count(&inventoryCount)
|
|
fmt.Printf("Total Inventory Items for Order %d: %d\n", dl.OrderID, inventoryCount)
|
|
|
|
if inventoryCount > 1 {
|
|
fmt.Println("SUCCESS: Double reward applied (Inventory count > 1)")
|
|
} else {
|
|
fmt.Println("WARNING: Inventory count is 1. Double reward might NOT have been applied.")
|
|
}
|
|
}
|
|
} else {
|
|
fmt.Println("FAILURE: Card status is still 1 (Not Consumed).")
|
|
}
|
|
}
|