Seregon/ShadPKG

A tool for deriving PKG packet encryption keys for ps4 written in c++

C++/47.3 KB/No license
core/file_format/playgo_chunk.h
ShadPKG / core / file_format / playgo_chunk.h
1// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3 
4#pragma once
5#include <filesystem>
6#include <mutex>
7#include <vector>
8#include "common/io_file.h"
9#include "core/libraries/playgo/playgo_types.h"
10 
11constexpr u32 PLAYGO_MAGIC = 0x6F676C70;
12 
13struct chunk_t {
14 u32 offset;
15 u32 length;
16} __attribute__((packed));
17 
18struct PlaygoHeader {
19 u32 magic;
20 
21 u16 version_major;
22 u16 version_minor;
23 u16 image_count; // [0;1]
24 u16 chunk_count; // [0;1000]
25 u16 mchunk_count; // [0;8000]
26 u16 scenario_count; // [0;32]
27 
28 u32 file_size;
29 u16 default_scenario_id;
30 u16 attrib;
31 u32 sdk_version;
32 u16 disc_count; // [0;2] (if equals to 0 then disc count = 1)
33 u16 layer_bmp;
34 
35 u8 reserved[32];
36 char content_id[128];
37 
38 chunk_t chunk_attrs; // [0;32000]
39 chunk_t chunk_mchunks;
40 chunk_t chunk_labels; // [0;16000]
41 chunk_t mchunk_attrs; // [0;12800]
42 chunk_t scenario_attrs; // [0;1024]
43 chunk_t scenario_chunks;
44 chunk_t scenario_labels;
45 chunk_t inner_mchunk_attrs; // [0;12800]
46} __attribute__((packed));
47 
48struct playgo_scenario_attr_entry_t {
49 u8 _type;
50 u8 _unk[19];
51 u16 initial_chunk_count;
52 u16 chunk_count;
53 u32 chunks_offset; //<-scenario_chunks
54 u32 label_offset; //<-scenario_labels
55} __attribute__((packed));
56 
57struct image_disc_layer_no_t {
58 u8 layer_no : 2;
59 u8 disc_no : 2;
60 u8 image_no : 4;
61} __attribute__((packed));
62 
63struct playgo_chunk_attr_entry_t {
64 u8 flag;
65 image_disc_layer_no_t image_disc_layer_no;
66 u8 req_locus;
67 u8 unk[11];
68 u16 mchunk_count;
69 u64 language_mask;
70 u32 mchunks_offset; //<-chunk_mchunks
71 u32 label_offset; //<-chunk_labels
72} __attribute__((packed));
73 
74struct playgo_chunk_loc_t {
75 u64 offset : 48;
76 u64 _align1 : 8;
77 u64 image_no : 4;
78 u64 _align2 : 4;
79} __attribute__((packed));
80 
81struct playgo_chunk_size_t {
82 u64 size : 48;
83 u64 _align : 16;
84} __attribute__((packed));
85 
86struct playgo_mchunk_attr_entry_t {
87 playgo_chunk_loc_t loc;
88 playgo_chunk_size_t size;
89} __attribute__((packed));
90 
91struct PlaygoChunk {
92 u64 req_locus;
93 u64 language_mask;
94 u64 total_size;
95 std::string label_name;
96};
97 
98class PlaygoFile {
99public:
100 OrbisPlayGoHandle handle = 0;
101 OrbisPlayGoChunkId id = 0;
102 OrbisPlayGoLocus locus = OrbisPlayGoLocus::NotDownloaded;
103 OrbisPlayGoInstallSpeed speed = OrbisPlayGoInstallSpeed::Trickle;
104 s64 speed_tick = 0;
105 OrbisPlayGoEta eta = 0;
106 OrbisPlayGoLanguageMask langMask = 0;
107 std::vector<PlaygoChunk> chunks;
108 
109public:
110 explicit PlaygoFile() = default;
111 ~PlaygoFile() = default;
112 
113 bool Open(const std::filesystem::path& filepath);
114 bool LoadChunks(const Common::FS::IOFile& file);
115 
116 PlaygoHeader& GetPlaygoHeader() {
117 return playgoHeader;
118 }
119 std::mutex& GetSpeedMutex() {
120 return speed_mutex;
121 }
122 
123private:
124 bool load_chunk_data(const Common::FS::IOFile& file, const chunk_t chunk, std::string& data);
125 
126private:
127 PlaygoHeader playgoHeader;
128 std::mutex speed_mutex;
129};
130