123 lines
4.0 KiB
Go
123 lines
4.0 KiB
Go
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 {
|
|
augCatalog, augErr := common.LoadCurrencyWarsAugments(catalog)
|
|
if augErr == nil {
|
|
if aug, ok := augCatalog.Augment(id); ok {
|
|
info = &pb.PPGEBEBPMJC{AugmentId: id}
|
|
for _, g := range aug.Grants {
|
|
if g.Kind == "gold" {
|
|
delta += int64(g.Count)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
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
|
|
}
|