|
@@ -9,19 +9,15 @@ import (
|
|
|
usercenter "server/datacenter"
|
|
|
maildb "server/datacenter/mail_db"
|
|
|
mysqlmgr "server/db/mysql"
|
|
|
+ "server/msg"
|
|
|
+ "strings"
|
|
|
|
|
|
_ "github.com/go-sql-driver/mysql"
|
|
|
)
|
|
|
|
|
|
-
|
|
|
-type Item struct {
|
|
|
- ID int `json:"item_id"`
|
|
|
- Quantity int `json:"quantity"`
|
|
|
-}
|
|
|
-
|
|
|
|
|
|
type InventoryData struct {
|
|
|
- Slots []Item `json:"slots"`
|
|
|
+ Slots []msg.ItemRequest `json:"slots"`
|
|
|
}
|
|
|
|
|
|
|
|
@@ -31,19 +27,13 @@ type ItemInfo struct {
|
|
|
MaxStack int `json:"max_stack"`
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-type ItemRequest struct {
|
|
|
- ItemID int `json:"item_id"`
|
|
|
- Quantity int `json:"quantity"`
|
|
|
-}
|
|
|
-
|
|
|
|
|
|
func GetUserInventory(userID string) (*InventoryData, error) {
|
|
|
var dataStr string
|
|
|
err := mysqlmgr.QueryRow("SELECT inventory_data FROM user_inventory WHERE user_id = ?", userID).Scan(&dataStr)
|
|
|
if err != nil {
|
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
|
- return &InventoryData{Slots: make([]Item, 0)}, nil
|
|
|
+ return &InventoryData{Slots: make([]msg.ItemRequest, 0)}, nil
|
|
|
}
|
|
|
return nil, fmt.Errorf("查询用户背包失败: %v", err)
|
|
|
}
|
|
@@ -78,7 +68,7 @@ func SaveUserInventory(userID string, data *InventoryData) error {
|
|
|
}
|
|
|
|
|
|
|
|
|
-func GetItemInfo(itemID int) (*ItemInfo, error) {
|
|
|
+func GetItemInfo(itemID int32) (*ItemInfo, error) {
|
|
|
var item ItemInfo
|
|
|
err := mysqlmgr.QueryRow(`
|
|
|
SELECT item_id, item_name, max_stack
|
|
@@ -92,7 +82,7 @@ func GetItemInfo(itemID int) (*ItemInfo, error) {
|
|
|
}
|
|
|
|
|
|
|
|
|
-func AddItemsToMail(userID string, items []ItemRequest) error {
|
|
|
+func AddItemsToMail(userID string, items []msg.ItemRequest) error {
|
|
|
|
|
|
tx, err := mysqlmgr.Begin()
|
|
|
if err != nil {
|
|
@@ -138,7 +128,7 @@ func AddItemsToMail(userID string, items []ItemRequest) error {
|
|
|
}
|
|
|
|
|
|
|
|
|
-func AcquireMultipleItems(userID string, itemRequests []ItemRequest) ([]ItemRequest, error) {
|
|
|
+func AcquireMultipleItems(userID string, itemRequests []msg.ItemRequest) ([]msg.ItemRequest, error) {
|
|
|
|
|
|
var maxSlots int
|
|
|
err := mysqlmgr.QueryRow("SELECT max_slots FROM users WHERE user_id = ?", userID).Scan(&maxSlots)
|
|
@@ -159,8 +149,8 @@ func AcquireMultipleItems(userID string, itemRequests []ItemRequest) ([]ItemRequ
|
|
|
}
|
|
|
|
|
|
|
|
|
- var mailItems []ItemRequest
|
|
|
- updatedInventory := &InventoryData{Slots: make([]Item, len(inventory.Slots))}
|
|
|
+ var mailItems []msg.ItemRequest
|
|
|
+ updatedInventory := &InventoryData{Slots: make([]msg.ItemRequest, len(inventory.Slots))}
|
|
|
copy(updatedInventory.Slots, inventory.Slots)
|
|
|
|
|
|
for _, req := range itemRequests {
|
|
@@ -175,10 +165,10 @@ func AcquireMultipleItems(userID string, itemRequests []ItemRequest) ([]ItemRequ
|
|
|
if itemInfo.MaxStack > 1 {
|
|
|
|
|
|
for i := range updatedInventory.Slots {
|
|
|
- if updatedInventory.Slots[i].ID == req.ItemID &&
|
|
|
- updatedInventory.Slots[i].Quantity < itemInfo.MaxStack {
|
|
|
- canAdd := itemInfo.MaxStack - updatedInventory.Slots[i].Quantity
|
|
|
- add := min(remainingQuantity, canAdd)
|
|
|
+ if updatedInventory.Slots[i].ItemID == req.ItemID &&
|
|
|
+ updatedInventory.Slots[i].Quantity < int32(itemInfo.MaxStack) {
|
|
|
+ canAdd := itemInfo.MaxStack - int(updatedInventory.Slots[i].Quantity)
|
|
|
+ add := min(remainingQuantity, int32(canAdd))
|
|
|
updatedInventory.Slots[i].Quantity += add
|
|
|
remainingQuantity -= add
|
|
|
if remainingQuantity == 0 {
|
|
@@ -192,7 +182,7 @@ func AcquireMultipleItems(userID string, itemRequests []ItemRequest) ([]ItemRequ
|
|
|
for remainingQuantity > 0 {
|
|
|
if remainingSlots <= 0 {
|
|
|
|
|
|
- mailItems = append(mailItems, ItemRequest{
|
|
|
+ mailItems = append(mailItems, msg.ItemRequest{
|
|
|
ItemID: req.ItemID,
|
|
|
Quantity: remainingQuantity,
|
|
|
})
|
|
@@ -203,17 +193,17 @@ func AcquireMultipleItems(userID string, itemRequests []ItemRequest) ([]ItemRequ
|
|
|
|
|
|
if itemInfo.MaxStack <= 1 {
|
|
|
|
|
|
- updatedInventory.Slots = append(updatedInventory.Slots, Item{
|
|
|
- ID: req.ItemID,
|
|
|
+ updatedInventory.Slots = append(updatedInventory.Slots, msg.ItemRequest{
|
|
|
+ ItemID: req.ItemID,
|
|
|
Quantity: 1,
|
|
|
})
|
|
|
remainingQuantity--
|
|
|
remainingSlots--
|
|
|
} else {
|
|
|
|
|
|
- add := min(remainingQuantity, itemInfo.MaxStack)
|
|
|
- updatedInventory.Slots = append(updatedInventory.Slots, Item{
|
|
|
- ID: req.ItemID,
|
|
|
+ add := min(remainingQuantity, int32(itemInfo.MaxStack))
|
|
|
+ updatedInventory.Slots = append(updatedInventory.Slots, msg.ItemRequest{
|
|
|
+ ItemID: req.ItemID,
|
|
|
Quantity: add,
|
|
|
})
|
|
|
remainingQuantity -= add
|
|
@@ -241,7 +231,7 @@ func AcquireMultipleItems(userID string, itemRequests []ItemRequest) ([]ItemRequ
|
|
|
}
|
|
|
|
|
|
|
|
|
-func ConsumeMultipleItems(userID string, itemRequests []ItemRequest) error {
|
|
|
+func ConsumeMultipleItems(userID string, itemRequests []msg.ItemRequest) error {
|
|
|
|
|
|
inventory, err := GetUserInventory(userID)
|
|
|
if err != nil {
|
|
@@ -249,15 +239,15 @@ func ConsumeMultipleItems(userID string, itemRequests []ItemRequest) error {
|
|
|
}
|
|
|
|
|
|
|
|
|
- itemCounts := make(map[int]int)
|
|
|
+ itemCounts := make(map[int32]int32)
|
|
|
for _, req := range itemRequests {
|
|
|
itemCounts[req.ItemID] += req.Quantity
|
|
|
}
|
|
|
|
|
|
|
|
|
- currentCounts := make(map[int]int)
|
|
|
+ currentCounts := make(map[int32]int32)
|
|
|
for _, slot := range inventory.Slots {
|
|
|
- currentCounts[slot.ID] += slot.Quantity
|
|
|
+ currentCounts[slot.ItemID] += slot.Quantity
|
|
|
}
|
|
|
|
|
|
|
|
@@ -270,24 +260,24 @@ func ConsumeMultipleItems(userID string, itemRequests []ItemRequest) error {
|
|
|
}
|
|
|
|
|
|
|
|
|
- newSlots := make([]Item, 0, len(inventory.Slots))
|
|
|
- remainingToConsume := make(map[int]int)
|
|
|
+ newSlots := make([]msg.ItemRequest, 0, len(inventory.Slots))
|
|
|
+ remainingToConsume := make(map[int32]int32)
|
|
|
for itemID, count := range itemCounts {
|
|
|
remainingToConsume[itemID] = count
|
|
|
}
|
|
|
|
|
|
for _, slot := range inventory.Slots {
|
|
|
- if consume, ok := remainingToConsume[slot.ID]; ok && consume > 0 {
|
|
|
+ if consume, ok := remainingToConsume[slot.ItemID]; ok && consume > 0 {
|
|
|
if slot.Quantity > consume {
|
|
|
|
|
|
- newSlots = append(newSlots, Item{
|
|
|
- ID: slot.ID,
|
|
|
+ newSlots = append(newSlots, msg.ItemRequest{
|
|
|
+ ItemID: slot.ItemID,
|
|
|
Quantity: slot.Quantity - consume,
|
|
|
})
|
|
|
- remainingToConsume[slot.ID] = 0
|
|
|
+ remainingToConsume[slot.ItemID] = 0
|
|
|
} else {
|
|
|
|
|
|
- remainingToConsume[slot.ID] -= slot.Quantity
|
|
|
+ remainingToConsume[slot.ItemID] -= slot.Quantity
|
|
|
}
|
|
|
} else {
|
|
|
|
|
@@ -300,18 +290,109 @@ func ConsumeMultipleItems(userID string, itemRequests []ItemRequest) error {
|
|
|
return SaveUserInventory(userID, updatedInventory)
|
|
|
}
|
|
|
|
|
|
-func min(a, b int) int {
|
|
|
+func min(a, b int32) int32 {
|
|
|
if a < b {
|
|
|
return a
|
|
|
}
|
|
|
return b
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+type InventoryItem struct {
|
|
|
+ ItemID int `json:"item_id"`
|
|
|
+ ItemName string `json:"item_name"`
|
|
|
+ ItemType int `json:"item_type"`
|
|
|
+ Quantity int `json:"quantity"`
|
|
|
+ MaxStack int `json:"max_stack"`
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func GetInventoryItemsByType(userID string, itemType int) ([]InventoryItem, error) {
|
|
|
+
|
|
|
+ inventory, err := GetUserInventory(userID)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if len(inventory.Slots) == 0 {
|
|
|
+ return []InventoryItem{}, nil
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ itemIDs := make([]int32, 0, len(inventory.Slots))
|
|
|
+ slotMap := make(map[int32][]msg.ItemRequest)
|
|
|
+ for _, slot := range inventory.Slots {
|
|
|
+ itemIDs = append(itemIDs, slot.ItemID)
|
|
|
+ slotMap[slot.ItemID] = append(slotMap[slot.ItemID], slot)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ query := `
|
|
|
+ SELECT item_id, item_name, item_type, max_stack
|
|
|
+ FROM items
|
|
|
+ WHERE item_id IN (` + placeholders(len(itemIDs)) + `)
|
|
|
+ AND item_type = ?
|
|
|
+ `
|
|
|
+
|
|
|
+
|
|
|
+ args := make([]interface{}, 0, len(itemIDs)+1)
|
|
|
+ for _, id := range itemIDs {
|
|
|
+ args = append(args, id)
|
|
|
+ }
|
|
|
+ args = append(args, itemType)
|
|
|
+
|
|
|
+ rows, err := mysqlmgr.Query(query, args...)
|
|
|
+ if err != nil {
|
|
|
+ return nil, fmt.Errorf("查询道具信息失败: %v", err)
|
|
|
+ }
|
|
|
+ defer rows.Close()
|
|
|
+
|
|
|
+
|
|
|
+ var result []InventoryItem
|
|
|
+ for rows.Next() {
|
|
|
+ var itemInfo struct {
|
|
|
+ ID int
|
|
|
+ Name string
|
|
|
+ Type int
|
|
|
+ MaxStack int
|
|
|
+ }
|
|
|
+ err := rows.Scan(&itemInfo.ID, &itemInfo.Name, &itemInfo.Type, &itemInfo.MaxStack)
|
|
|
+ if err != nil {
|
|
|
+ return nil, fmt.Errorf("解析道具信息失败: %v", err)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if slots, ok := slotMap[int32(itemInfo.ID)]; ok {
|
|
|
+ for _, slot := range slots {
|
|
|
+ result = append(result, InventoryItem{
|
|
|
+ ItemID: itemInfo.ID,
|
|
|
+ ItemName: itemInfo.Name,
|
|
|
+ ItemType: itemInfo.Type,
|
|
|
+ Quantity: int(slot.Quantity),
|
|
|
+ MaxStack: itemInfo.MaxStack,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return result, nil
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+func placeholders(n int) string {
|
|
|
+ phs := make([]string, n)
|
|
|
+ for i := range phs {
|
|
|
+ phs[i] = "?"
|
|
|
+ }
|
|
|
+ return strings.Join(phs, ",")
|
|
|
+}
|
|
|
+
|
|
|
func example() {
|
|
|
|
|
|
|
|
|
userID := "user123"
|
|
|
- itemsToAdd := []ItemRequest{
|
|
|
+ itemsToAdd := []msg.ItemRequest{
|
|
|
{ItemID: 101, Quantity: 15},
|
|
|
{ItemID: 201, Quantity: 3},
|
|
|
{ItemID: 301, Quantity: 5},
|
|
@@ -327,7 +408,7 @@ func example() {
|
|
|
}
|
|
|
|
|
|
|
|
|
- itemsToConsume := []ItemRequest{
|
|
|
+ itemsToConsume := []msg.ItemRequest{
|
|
|
{ItemID: 101, Quantity: 5},
|
|
|
{ItemID: 201, Quantity: 1},
|
|
|
}
|