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.cpp
ShadPKG / core / file_format / playgo_chunk.cpp
1// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3 
4#include "playgo_chunk.h"
5 
6bool PlaygoFile::Open(const std::filesystem::path& filepath) {
7 Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Read);
8 if (file.IsOpen()) {
9 file.Read(playgoHeader);
10 if (LoadChunks(file)) {
11 return true;
12 }
13 }
14 return false;
15}
16 
17bool PlaygoFile::LoadChunks(const Common::FS::IOFile& file) {
18 if (file.IsOpen()) {
19 if (playgoHeader.magic == PLAYGO_MAGIC) {
20 bool ret = true;
21 
22 std::string chunk_attrs_data, chunk_mchunks_data, chunk_labels_data, mchunk_attrs_data;
23 ret = ret && load_chunk_data(file, playgoHeader.chunk_attrs, chunk_attrs_data);
24 ret = ret && load_chunk_data(file, playgoHeader.chunk_mchunks, chunk_mchunks_data);
25 ret = ret && load_chunk_data(file, playgoHeader.chunk_labels, chunk_labels_data);
26 ret = ret && load_chunk_data(file, playgoHeader.mchunk_attrs, mchunk_attrs_data);
27 
28 if (ret) {
29 chunks.resize(playgoHeader.chunk_count);
30 
31 auto chunk_attrs =
32 reinterpret_cast<playgo_chunk_attr_entry_t*>(&chunk_attrs_data[0]);
33 auto chunk_mchunks = reinterpret_cast<u16*>(&chunk_mchunks_data[0]);
34 auto chunk_labels = reinterpret_cast<char*>(&chunk_labels_data[0]);
35 auto mchunk_attrs =
36 reinterpret_cast<playgo_mchunk_attr_entry_t*>(&mchunk_attrs_data[0]);
37 
38 for (u16 i = 0; i < playgoHeader.chunk_count; i++) {
39 chunks[i].req_locus = chunk_attrs[i].req_locus;
40 chunks[i].language_mask = chunk_attrs[i].language_mask;
41 chunks[i].label_name = std::string(chunk_labels + chunk_attrs[i].label_offset);
42 
43 u64 total_size = 0;
44 u16 mchunk_count = chunk_attrs[i].mchunk_count;
45 if (mchunk_count != 0) {
46 auto mchunks = reinterpret_cast<u16*>(
47 ((u8*)chunk_mchunks + chunk_attrs[i].mchunks_offset));
48 for (u16 j = 0; j < mchunk_count; j++) {
49 u16 mchunk_id = mchunks[j];
50 total_size += mchunk_attrs[mchunk_id].size.size;
51 }
52 }
53 chunks[i].total_size = total_size;
54 }
55 }
56 
57 return ret;
58 }
59 }
60 return false;
61}
62 
63bool PlaygoFile::load_chunk_data(const Common::FS::IOFile& file, const chunk_t chunk,
64 std::string& data) {
65 if (file.IsOpen()) {
66 if (file.Seek(chunk.offset)) {
67 data.resize(chunk.length);
68 if (data.size() == chunk.length) {
69 file.ReadRaw<char>(&data[0], chunk.length);
70 return true;
71 }
72 }
73 }
74 return false;
75}