package gameserver import ( "encoding/json" "fmt" "gac-hkrpg-go/internal/common" pb "gac-hkrpg-go/protocol/proto" "google.golang.org/protobuf/proto" "math" ) func cwSelectInvestment(catalog *common.CurrencyWarsCatalog, run *pb.MPIMAEMCEFH, id uint32) (*pb.GridFightSyncUpdateResultScNotify, error) { pending := run.FMIGOKIDKJL if pending == nil || pending.GetIBCHMBNIPLK() == nil { return nil, fmt.Errorf("CW investment not pending") } offered := false for _, v := range pending.GetIBCHMBNIPLK().CEBFFDFMKGK { offered = offered || v.AugmentId == id } if !offered || id == 0 { return nil, fmt.Errorf("CW investment not offered") } raw, err := common.ReadResourceFile("resources/CurrencyWarsInvestmentChoices.json") if err != nil { return nil, err } var resource struct { Format uint32 `json:"format_version"` Client string `json:"target_client_version"` Assembly string `json:"target_assembly_sha256"` Choices []struct { ID uint32 `json:"augment_id"` GoldDelta int64 `json:"gold_delta"` Info []byte `json:"augment_info_wire"` } `json:"choices"` } if err = json.Unmarshal(raw, &resource); err != nil { return nil, err } if resource.Format != 1 || resource.Client != catalog.ClientVersion || resource.Assembly != catalog.Provenance.GameAssemblySHA256 { return nil, fmt.Errorf("CW investment resource revision differs") } player, _, _ := cwComponents(run) if player == nil { return nil, fmt.Errorf("CW player missing") } var augments *pb.KGFNICBCMOA for _, c := range run.NAGDJGMMCBE { if v := c.GetLLDBOIANGDN(); v != nil { augments = v } } if augments == nil { return nil, fmt.Errorf("CW investment container missing") } for _, v := range augments.SyncAugmentInfo { if v.AugmentId == id { return nil, fmt.Errorf("CW investment already owned") } } var info *pb.PPGEBEBPMJC var delta int64 for _, choice := range resource.Choices { if choice.ID == id { if info != nil { return nil, fmt.Errorf("CW investment outcome duplicated") } info = new(pb.PPGEBEBPMJC) if err = proto.Unmarshal(choice.Info, info); err != nil { return nil, err } delta = choice.GoldDelta } } if info == nil || info.AugmentId != id { return nil, fmt.Errorf("CW investment effect not captured") } if delta < 0 { cost := uint64(-(delta + 1)) + 1 if cost > uint64(player.Gold) { return nil, fmt.Errorf("CW investment gold insufficient") } player.Gold -= uint32(cost) } else { total := uint64(player.Gold) + uint64(delta) if total > math.MaxUint32 { total = math.MaxUint32 } player.Gold = uint32(total) } if pending.QueuePosition == math.MaxUint32 { return nil, fmt.Errorf("CW pending queue exhausted") } next := &pb.CHCHAJIANIM{QueuePosition: pending.QueuePosition + 1, FGLIODAJFML: &pb.CHCHAJIANIM_LGNPHHBGKFH{LGNPHHBGKFH: &pb.HJPDALHDJHC{}}} augments.SyncAugmentInfo = append(augments.SyncAugmentInfo, info) run.FMIGOKIDKJL = next notify := cwNotify(&pb.KFNCAIHIHCM{MNLCHEJKDHO: &pb.KFNCAIHIHCM_EIKHFBCKIFA{EIKHFBCKIFA: &pb.OMINPDAIBLP{MCPIKEHDMND: info}}}) notify.GCPNIHHBGGD[0].GridUpdateSrc = pb.JJDFGMMMCMI_JJDFGMMMCMI_EJLJOJFECPM if delta != 0 { gold := cwNotify(cwGoldSync(player.Gold)).GCPNIHHBGGD[0] gold.OOEOCGLLHFO = []uint32{id} gold.GridUpdateSrc = pb.JJDFGMMMCMI_JJDFGMMMCMI_ANMFPKDFICD notify.GCPNIHHBGGD = append([]*pb.ABPLALCHNFA{gold}, notify.GCPNIHHBGGD...) } notify.GCPNIHHBGGD = append(notify.GCPNIHHBGGD, cwNotify(cwFinish(pending.QueuePosition), cwUnlock()).GCPNIHHBGGD...) notify.GCPNIHHBGGD = append(notify.GCPNIHHBGGD, cwNotify(&pb.KFNCAIHIHCM{MNLCHEJKDHO: &pb.KFNCAIHIHCM_JOMFJHOCHJP{JOMFJHOCHJP: player.GAJGBBFELEL}}, &pb.KFNCAIHIHCM{MNLCHEJKDHO: &pb.KFNCAIHIHCM_FMIGOKIDKJL{FMIGOKIDKJL: next}}).GCPNIHHBGGD...) return notify, nil }