package gameserver import ( "fmt" "gac-hkrpg-go/internal/common" pb "gac-hkrpg-go/protocol/proto" "google.golang.org/protobuf/proto" ) func stellaJumpData(id uint32) (*pb.JBOBHIPHGPB, error) { cases, err := common.LoadStellaJumpCases() if err != nil { return nil, err } row, ok := cases[id] if !ok { return nil, fmt.Errorf("unknown Stella Jump case %d", id) } record, err := common.ReadStellaJumpRecord(id) if err != nil { return nil, err } return &pb.JBOBHIPHGPB{IJCJBDDGGJF: row.ID, OOMILCOFGPN: true, HIEMHCBHKEO: record.CheatMode, HLNODEFLOCF: record.BestTime, CJKAGEDKAFL: append([]uint32(nil), row.Challenges...)}, nil } // The current Client's ChenLingGameBoyPuzzleData.Sync consumes JBOBHIPHGPB: // finished-challenge IDs unlock the challenge packs. This sandbox projection // exposes the captured packs without inventing scores in the persistent record. // Source: preview-gameboy-sync.asm and the named CaseRow capture. func init() { handle("GetChenLingGameBoyData", func(s *Session, req *pb.GetChenLingGameBoyDataCsReq, rsp *pb.GetChenLingGameBoyDataScRsp) error { rsp.Retcode = uint32(pb.Retcode_RET_FAIL) cases, err := common.LoadStellaJumpCases() if err != nil { return err } row, ok := cases[req.IJCJBDDGGJF] if !ok { return nil } record, err := common.ReadStellaJumpRecord(row.ID) if err != nil { return err } rsp.IAOBHCOOMJP = &pb.JBOBHIPHGPB{IJCJBDDGGJF: row.ID, OOMILCOFGPN: true, HIEMHCBHKEO: record.CheatMode, HLNODEFLOCF: record.BestTime, CJKAGEDKAFL: append([]uint32(nil), row.Challenges...)} rsp.Retcode = 0 PacketLog(fmt.Sprintf("STELLA_JUMP_DATA case=%d unlocked_packs=%d", row.ID, len(row.Challenges))) return nil }) handle("FinishChenLingGameBoy", func(s *Session, req *pb.FinishChenLingGameBoyCsReq, rsp *pb.FinishChenLingGameBoyScRsp) error { rsp.Retcode = uint32(pb.Retcode_RET_FAIL) record, err := common.SaveStellaJumpResult(req.IJCJBDDGGJF, req.BEJCJJCLJHL, req.CJKAGEDKAFL) if err != nil { PacketLog("STELLA_JUMP_FINISH rejected: " + err.Error()) return nil } rsp.IJCJBDDGGJF = req.IJCJBDDGGJF rsp.BEJCJJCLJHL = req.BEJCJJCLJHL rsp.HLNODEFLOCF = record.BestTime rsp.Reward = &pb.ItemList{} rsp.Retcode = 0 return nil }) handle("ChenLingGameBoyGetFriendRankingInfo", func(s *Session, req *pb.ChenLingGameBoyGetFriendRankingInfoCsReq, rsp *pb.ChenLingGameBoyGetFriendRankingInfoScRsp) error { rsp.Retcode = uint32(pb.Retcode_RET_FAIL) cases, err := common.LoadStellaJumpCases() if err != nil { return err } if _, ok := cases[req.IJCJBDDGGJF]; !ok { return nil } rsp.IJCJBDDGGJF = req.IJCJBDDGGJF rsp.Retcode = 0 // No fabricated friends or leaderboard times. return nil }) handle("ChenLingGameBoyChangeSettings", func(s *Session, req *pb.ChenLingGameBoyChangeSettingsCsReq, rsp *pb.ChenLingGameBoyChangeSettingsScRsp) error { rsp.EBAFPOLLJIA = req.EBAFPOLLJIA return nil }) // These two request names remain obfuscated in the revision-tagged table. // Shapes are one case ID, and case ID + bool respectively. They correspond // to FiveDimModule.SendChenLingCheatInputKeyReq / SendChenLingCheatModeReq. // The second response boolean's exact Client label remains unverified; // keep the source names and record it independently from completion/score. rawNamed("ANDPLLAKCLE", func(s *Session, body []byte) error { rsp := &pb.CDJKLJDMJHO{Retcode: uint32(pb.Retcode_RET_FAIL)} req := new(pb.ANDPLLAKCLE) if err := proto.Unmarshal(body, req); err == nil { if err = common.SaveStellaJumpCheatSetting(req.IJCJBDDGGJF, true, true); err == nil { rsp.IAOBHCOOMJP, err = stellaJumpData(req.IJCJBDDGGJF) if err == nil { rsp.Retcode = 0 } } } return s.Send(rsp) }) rawNamed("EMDKLICDPKK", func(s *Session, body []byte) error { rsp := &pb.JHEHACPKKBL{Retcode: uint32(pb.Retcode_RET_FAIL)} req := new(pb.EMDKLICDPKK) if err := proto.Unmarshal(body, req); err == nil { if err = common.SaveStellaJumpCheatSetting(req.IJCJBDDGGJF, false, req.HIEMHCBHKEO); err == nil { rsp.IAOBHCOOMJP, err = stellaJumpData(req.IJCJBDDGGJF) if err == nil { rsp.Retcode = 0 } } } return s.Send(rsp) }) }