package gameserver import ( "gac-hkrpg-go/internal/common" goproto "gac-hkrpg-go/protocol/proto" ) // Keep resource defaults immutable: saved values belong to the player session. func (s *Session) sceneGroupProperties(floor, group uint32, rules map[string]common.GroupPropertyRule) map[string]int32 { values := make(map[string]int32, len(rules)) player := s.JSON() for name, rule := range rules { value := rule.DefaultValue if player != nil { if saved, ok := player.SceneGroupProperties[floor][group][name]; ok && saved >= rule.MinValue && saved <= rule.MaxValue { value = saved } } values[name] = value } return values } func init() { handle("UpdateGroupProperty", func(s *Session, req *goproto.UpdateGroupPropertyCsReq, rsp *goproto.UpdateGroupPropertyScRsp) error { // PearlSR 005d2c12 services/scene.zig acknowledges these named fields. // The sole int32 request field (15) is treated as the new value, constrained // by the Client GroupPropertyConfig. Obfuscated response values stay unset, // as in the reference; their old/new semantics have not been verified. rsp.FloorId = req.FloorId rsp.GroupId = req.GroupId rsp.DimensionId = req.DimensionId rsp.HMELFPDPCFC = req.HMELFPDPCFC p := s.JSON() if p == nil || req.FloorId != s.CurrentSceneFloor || s.ChallengeRun != nil { rsp.Retcode = uint32(goproto.Retcode_RET_FAIL) return nil } if _, active := CURRENT_BATTLE.Load(s.Token); active { rsp.Retcode = uint32(goproto.Retcode_RET_FAIL) return nil } res, err := common.GameRes() if err != nil { return err } entry := findEntryForFloor(res, req.FloorId) _, cfg, ok := firstSceneOfEntry(res, entry) if !ok || req.DimensionId != cfg.DimensionID { rsp.Retcode = uint32(goproto.Retcode_RET_NOT_CORRECT_GROUP_PROPERTY_NAME) return nil } rule, ok := cfg.GroupProperties[req.GroupId][req.HMELFPDPCFC] if !ok || req.OLBEPIBLDBD < rule.MinValue || req.OLBEPIBLDBD > rule.MaxValue { rsp.Retcode = uint32(goproto.Retcode_RET_NOT_CORRECT_GROUP_PROPERTY_NAME) return nil } if p.SceneGroupProperties == nil { p.SceneGroupProperties = map[uint32]map[uint32]map[string]int32{} } if p.SceneGroupProperties[req.FloorId] == nil { p.SceneGroupProperties[req.FloorId] = map[uint32]map[string]int32{} } if p.SceneGroupProperties[req.FloorId][req.GroupId] == nil { p.SceneGroupProperties[req.FloorId][req.GroupId] = map[string]int32{} } values := p.SceneGroupProperties[req.FloorId][req.GroupId] previous, existed := values[req.HMELFPDPCFC] values[req.HMELFPDPCFC] = req.OLBEPIBLDBD if err := p.SavePersistentChecked(); err != nil { if existed { values[req.HMELFPDPCFC] = previous } else { delete(values, req.HMELFPDPCFC) } return err } SceneDebugLog("GROUP_PROPERTY floor=%d group=%d property=%s value=%d", req.FloorId, req.GroupId, req.HMELFPDPCFC, req.OLBEPIBLDBD) return nil }) }