Align SCUM operations with reference tools

This commit is contained in:
npc0-hue
2026-08-13 18:21:08 +08:00
parent 8b236d7c15
commit da01d39866
24 changed files with 375 additions and 105 deletions
+42 -10
View File
@@ -23,7 +23,7 @@ func (svc *CoreService) SaveGameGiftCatalogForSession(sessionID, serverID string
if err = svc.authorizeServerLifecycle(sessionID, serverID); err != nil {
return domain.GameGiftCatalog{}, err
}
if err = validateGiftItems(request.GameVersion, request.Items); err != nil {
if err = svc.validateGiftItems(serverID, request.GameVersion, request.Items); err != nil {
return domain.GameGiftCatalog{}, err
}
stamp := svc.now()
@@ -60,7 +60,7 @@ func (svc *CoreService) PublishGameGiftCatalogForSession(sessionID, catalogID st
if err = svc.authorizeServerLifecycle(sessionID, catalog.ServerInstanceID); err != nil {
return domain.GameGiftRevision{}, err
}
if err = validateGiftItems(catalog.GameVersion, catalog.DraftItems); err != nil {
if err = svc.validateGiftItems(catalog.ServerInstanceID, catalog.GameVersion, catalog.DraftItems); err != nil {
return domain.GameGiftRevision{}, err
}
revisions, err := svc.store.GameGiftRevisions().List(domain.GameGiftRevisionFilter{CatalogID: catalog.ID})
@@ -111,7 +111,7 @@ func (svc *CoreService) RequestGameGiftGrantForSession(sessionID, serverID strin
if err != nil || revision.ServerInstanceID != serverID {
return domain.GameGiftGrant{}, repo.ErrNotFound
}
if err = validateGiftItems(revision.GameVersion, revision.Items); err != nil {
if err = svc.validateGiftItems(serverID, revision.GameVersion, revision.Items); err != nil {
return domain.GameGiftGrant{}, err
}
player, err := svc.store.GamePlayers().Get(request.GamePlayerRecordID)
@@ -148,7 +148,7 @@ func (svc *CoreService) ApproveGameGiftGrantForSession(sessionID, grantID string
if grant.Status != domain.GameGiftGrantPendingApproval {
return domain.GameGiftGrant{}, validationError("gift grant is not awaiting approval")
}
if err = validateGiftItems(grant.GameVersion, grant.Items); err != nil {
if err = svc.validateGiftItems(grant.ServerInstanceID, grant.GameVersion, grant.Items); err != nil {
return domain.GameGiftGrant{}, err
}
sessions, err := svc.store.GamePlayerSessions().List(domain.GamePlayerSessionFilter{GamePlayerRecordID: grant.GamePlayerRecordID, OpenOnly: true})
@@ -198,23 +198,55 @@ func (svc *CoreService) ListGameGiftGrantsForSession(sessionID, serverID string)
sort.Slice(grants, func(i, j int) bool { return grants[i].CreatedAt.After(grants[j].CreatedAt) })
return grants, nil
}
func validateGiftItems(version string, items []domain.GameGiftItem) error {
if _, ok := domain.SCUMGiftCatalogForVersion(version); !ok {
return validationError("SCUM game version has no verified gift item catalog")
func (svc *CoreService) validateGiftItems(serverID, version string, items []domain.GameGiftItem) error {
instance, err := svc.store.ServerInstances().Get(serverID)
if err != nil {
return err
}
plugin, err := svc.store.GamePlugins().Get(instance.PluginID)
if err != nil {
return err
}
catalog, ok := scumGiftCatalogFromPlugin(plugin, version)
if !ok {
return validationError("installed SCUM plugin has no verified gift item catalog for this game version")
}
if len(items) == 0 || len(items) > 8 {
return validationError("gift requires 1 to 8 catalog items")
}
seen := map[string]bool{}
for _, item := range items {
def, ok := domain.SCUMGiftItemForVersion(version, item.CatalogItemKey)
if !ok || seen[item.CatalogItemKey] || item.Quantity < 1 || item.Quantity > def.MaximumQuantity || item.Label != def.Label {
for index, item := range items {
def, ok := scumGiftItem(catalog, item.CatalogItemKey)
if !ok || seen[item.CatalogItemKey] || item.Quantity < 1 || item.Quantity > def.MaximumQuantity {
return validationError("gift item is not valid for this SCUM version")
}
items[index].Label = def.Label
seen[item.CatalogItemKey] = true
}
return nil
}
func scumGiftCatalogFromPlugin(plugin domain.GamePlugin, version string) (domain.SCUMGiftItemCatalog, bool) {
for _, asset := range plugin.LifecycleAssets {
if !strings.HasPrefix(asset.Path, "data-packs/") || !strings.HasSuffix(asset.Path, "/gift-items.json") || strings.TrimSpace(asset.Content) == "" {
continue
}
catalog, ok := domain.ParseSCUMGiftItemCatalog(asset.Content)
if ok && catalog.GameVersion == version {
return catalog, true
}
}
return domain.SCUMGiftItemCatalog{}, false
}
func scumGiftItem(catalog domain.SCUMGiftItemCatalog, key string) (domain.SCUMGiftItemDefinition, bool) {
for _, item := range catalog.Items {
if item.Key == key {
return item, true
}
}
return domain.SCUMGiftItemDefinition{}, false
}
func giftDeliveryPayload(grant domain.GameGiftGrant) map[string]any {
items := make([]any, len(grant.Items))
for i, item := range grant.Items {