Generate equipment loot atomically, grant random boxes and prevent repeat claims. Read gacha pools, pity, products, tickets, missions, presets, chapter rewards and inventory costs from GameData; extend both collaboration UR ticket pools. Sync owned recipes, configure startup state and calendars in versioned seeds, and validate unlock tickets and revival talents.
54 lines
1.8 KiB
Go
54 lines
1.8 KiB
Go
package world
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"bd2server/internal/server/gamedata"
|
|
"bd2server/internal/server/wire"
|
|
)
|
|
|
|
func packJamIdentity(packID int) string { return fmt.Sprintf("pack-jam:%d", packID) }
|
|
|
|
func (s *Service) handlePackDocking(path string, request []byte) (int, []byte, bool, error) {
|
|
packID, err := requestPack(request)
|
|
if err != nil {
|
|
return 0, nil, true, err
|
|
}
|
|
if _, known := s.questsFor(packID); !known || !s.packUnlocked(packID) {
|
|
return 0, nil, true, fmt.Errorf("%w: unavailable docking pack %d", ErrInvalidRequest, packID)
|
|
}
|
|
if s.wallet == nil || s.packJamDesign == nil {
|
|
return 0, nil, true, fmt.Errorf("world: pack jam design or wallet unavailable")
|
|
}
|
|
identity := packJamIdentity(packID)
|
|
if path == "/PackPreviewInfo" {
|
|
var response []byte
|
|
if active := s.firstUnclearedQuestFor(packID); active != 0 {
|
|
quest := wire.AppendVarint(nil, 1, uint64(active))
|
|
quest = wire.AppendVarint(quest, 6, uint64(packID))
|
|
response = wire.AppendBytes(response, 1, quest)
|
|
}
|
|
if s.wallet.WasGranted(identity) {
|
|
response = wire.AppendVarint(response, 3, 1)
|
|
}
|
|
return 104, response, true, nil
|
|
}
|
|
// Serialize the claim check and grant so concurrent domain callers cannot
|
|
// return the animation reward twice. The wallet commits balance and ledger together.
|
|
s.packJamMu.Lock()
|
|
defer s.packJamMu.Unlock()
|
|
if s.wallet.WasGranted(identity) {
|
|
return 72, nil, true, nil
|
|
}
|
|
reward := s.packJamDesign.Reward
|
|
if s.packJamDesign.ValidateReward() != nil {
|
|
return 0, nil, true, fmt.Errorf("world: unsupported pack jam reward")
|
|
}
|
|
if _, err := s.wallet.GrantQuestOnce(identity, []gamedata.Reward{reward}); err != nil {
|
|
return 0, nil, true, fmt.Errorf("world: grant pack jam reward: %w", err)
|
|
}
|
|
item := wire.AppendVarint(nil, 3, reward.Type)
|
|
item = wire.AppendVarint(item, 4, reward.Count)
|
|
return 72, wire.AppendBytes(nil, 1, item), true, nil
|
|
}
|