This repository has been archived on 2026-10-31. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Ananta-ps/internal/catalogs/economy_config_repository.go
T

255 lines
7.9 KiB
Go
Raw Normal View History

package catalogs
import (
"encoding/json"
"os"
"path/filepath"
"sync"
)
var _ = json.RawMessage{}
var _ = sync.Mutex{}
var _ = os.ReadFile
var _ = filepath.Join
//
// Client economy tables (mall commodities, drops, gacha pools/contents/tier rules) imported from the
// 4229938 config dump into paths.clientConfigs.
// Unlike ClientConfigRepository these tables are optional: a missing or malformed file only disables
// the matching feature (mall purchase / gacha draw) instead of refusing to start, because the rest of
// the server must keep working when a dump is incomplete.
//
var (
EconomyConfigRepository_cacheLock sync.RWMutex
EconomyConfigRepository_cached = false
EconomyConfigRepository_entries []any
)
// LoadEconomyConfigRepository loads catalog records from client config directory
func LoadEconomyConfigRepository(configDir string) ([]any, error) {
EconomyConfigRepository_cacheLock.RLock()
if EconomyConfigRepository_cached {
defer EconomyConfigRepository_cacheLock.RUnlock()
return EconomyConfigRepository_entries, nil
}
EconomyConfigRepository_cacheLock.RUnlock()
EconomyConfigRepository_cacheLock.Lock()
defer EconomyConfigRepository_cacheLock.Unlock()
if EconomyConfigRepository_cached { return EconomyConfigRepository_entries, nil }
filePath := filepath.Join(configDir, "EconomyConfigRepository.json")
data, err := os.ReadFile(filePath)
if err != nil {
return nil, err
}
var raw struct {
Records []json.RawMessage `json:"records"`
}
if err := json.Unmarshal(data, &raw); err != nil {
return nil, err
}
var result []any
for _, item := range raw.Records {
var m map[string]any
if err := json.Unmarshal(item, &m); err == nil {
result = append(result, m)
}
}
EconomyConfigRepository_entries = result
EconomyConfigRepository_cached = true
return result, nil
}
// Forces the (optional) tables to load so the startup log reports what was imported.
func EconomyConfigRepository_Warmup() {
// Catalog helper EconomyConfigRepository_Warmup
}
func EconomyConfigRepository_TryMallCommodity(id uint32, commodity MallCommodity) bool {
// Catalog helper EconomyConfigRepository_TryMallCommodity
return false
}
func EconomyConfigRepository_TryDrop(id uint32, drop DropRow) bool {
// Catalog helper EconomyConfigRepository_TryDrop
return false
}
func EconomyConfigRepository_TryPool(id uint32, pool GachaPool) bool {
// Catalog helper EconomyConfigRepository_TryPool
return false
}
func EconomyConfigRepository_TryTierRule(id uint32, rule GachaTierRule) bool {
// Catalog helper EconomyConfigRepository_TryTierRule
return false
}
func EconomyConfigRepository_TryTradeItem(id uint32, item TradeItem) bool {
// Catalog helper EconomyConfigRepository_TryTradeItem
return false
}
func EconomyConfigRepository_PoolContents(poolId uint32) []GachaContent {
// Catalog helper EconomyConfigRepository_PoolContents
return nil
}
func EconomyConfigRepository_ReadRecords(path string, warnings []string) []any {
// Catalog helper EconomyConfigRepository_ReadRecords
return nil
}
// Dump records may carry fully qualified keys ("LT.ConfigGen.IFoo.Id"), so match on the leaf name.
func EconomyConfigRepository_TryProperty(row any, name string, value any) bool {
// Catalog helper EconomyConfigRepository_TryProperty
return false
}
func EconomyConfigRepository_TryUInt32(row any, name string, result uint32) bool {
// Catalog helper EconomyConfigRepository_TryUInt32
return false
}
func EconomyConfigRepository_TryDouble(row any, name string, result float64) bool {
// Catalog helper EconomyConfigRepository_TryDouble
return false
}
func EconomyConfigRepository_ReadBool(row any, name string) bool {
// Catalog helper EconomyConfigRepository_ReadBool
return false
}
func EconomyConfigRepository_ReadUInt32Array(row any, name string) []uint32 {
// Catalog helper EconomyConfigRepository_ReadUInt32Array
return nil
}
// Item1: [{ "id1": 36211010, "count": 10 }, ...] - every entry is granted.
func EconomyConfigRepository_ReadItemList(row any, name string) []any {
// Catalog helper EconomyConfigRepository_ReadItemList
return nil
}
// Item2: [{ "id2": .., "min": .., "max": .. }] - one entry is chosen and rolled inside [min, max].
func EconomyConfigRepository_ReadItemRangeList(row any, name string) []any {
// Catalog helper EconomyConfigRepository_ReadItemRangeList
return nil
}
// Item3: [{ "id3": .., "count": 0.00075 }] - 'count' is a relative probability weight.
func EconomyConfigRepository_ReadItemWeightList(row any, name string) []any {
// Catalog helper EconomyConfigRepository_ReadItemWeightList
return nil
}
// CostCount: [{ "drawCount": 1, "cost": 100 }, ...]
func EconomyConfigRepository_ReadCostList(row any, name string) []any {
// Catalog helper EconomyConfigRepository_ReadCostList
return nil
}
// One mall shelf row. Price is the list price, DiscountPrice the current charge (0 = none).
type MallCommodity struct {
Id uint32 `json:"id"`
MallId uint32 `json:"mallId"`
Type uint32 `json:"type"`
BindId uint32 `json:"bindId"`
ConsumeItemId uint32 `json:"consumeItemId"`
Price float64 `json:"price"`
DiscountPrice float64 `json:"discountPrice"`
DropId uint32 `json:"dropId"`
LimitNum uint32 `json:"limitNum"`
CommodityBindIds []uint32 `json:"commodityBindIds"`
UnitPrice float64 `json:"unitPrice"`
}
//
// One drop row. items are always granted,
// picks one entry and a random count in [Min, Max], picks one entry by
// relative weight (Item3 carries fractional weights, so they are doubles).
//
type DropRow struct {
Id uint32 `json:"id"`
Money float64 `json:"money"`
BindingGold float64 `json:"bindingGold"`
Guaranteed []any `json:"guaranteed"`
Ranged []any `json:"ranged"`
Weighted []any `json:"weighted"`
IsEmpty bool `json:"isEmpty"`
}
type GachaPool struct {
Id uint32 `json:"id"`
IsDrop bool `json:"isDrop"`
MoneyId uint32 `json:"moneyId"`
CommodityId uint32 `json:"commodityId"`
GrandTierRuleId uint32 `json:"grandTierRuleId"`
Costs []any `json:"costs"`
}
type GachaContent struct {
Id uint32 `json:"id"`
PoolId uint32 `json:"poolId"`
TierRarity uint32 `json:"tierRarity"`
DropId uint32 `json:"dropId"`
Weight float64 `json:"weight"`
Quantity uint32 `json:"quantity"`
Quality uint32 `json:"quality"`
DuplicateReturnDropId uint32 `json:"duplicateReturnDropId"`
DuplicateReturnCount uint32 `json:"duplicateReturnCount"`
// SS-tier row: the UI plays the extra grand-prize video for these draws.
IsGrandPrize bool `json:"isGrandPrize"`
}
//
// Pity ramp for one tier rule. 1 pools ramp their grand-prize chance
// from by every draw
// once is reached and guarantee it at .
// 0 pools instead pick a tier from the cumulative
// table (scale 100000) with no pity at all.
//
type GachaTierRule struct {
Id uint32 `json:"id"`
RuleType uint32 `json:"ruleType"`
PityThreshold uint32 `json:"pityThreshold"`
RampStartDraw uint32 `json:"rampStartDraw"`
BaseProbability uint32 `json:"baseProbability"`
ProbabilityIncrement uint32 `json:"probabilityIncrement"`
GrandPrizeProbability []uint32 `json:"grandPrizeProbability"`
}
//
// One trading-post row. 0 hands out as an
// ordinary backpack item, 1 unlocks the wardrobe piece , 3 is a
// household collectible (also ) and 2 is a fashion suit that retail only
// trades through the order book.
//
type TradeItem struct {
Id uint32 `json:"id"`
ItemType uint32 `json:"itemType"`
ItemId uint32 `json:"itemId"`
Tab uint32 `json:"tab"`
FashionId uint32 `json:"fashionId"`
FashionSuitId uint32 `json:"fashionSuitId"`
MinPrice uint32 `json:"minPrice"`
MaxPrice uint32 `json:"maxPrice"`
BucketRanges []uint32 `json:"bucketRanges"`
// Cheapest price the row is offered at - the floor of its authored bucket ranges.
MarketPrice uint32 `json:"marketPrice"`
}
type EconomyConfigRepository_Data struct {
Mall map[uint32]MallCommodity `json:"mall"`
Drops map[uint32]DropRow `json:"drops"`
Pools map[uint32]GachaPool `json:"pools"`
TierRules map[uint32]GachaTierRule `json:"tierRules"`
ContentsByPool map[uint32][]GachaContent `json:"contentsByPool"`
TradeItems map[uint32]TradeItem `json:"tradeItems"`
}