22declare(strict_types=1);
24namespace pocketmine\resourcepacks;
28use Symfony\Component\Filesystem\Path;
29use
function array_keys;
32use
function file_exists;
38use
function is_string;
42use
function strtolower;
43use
const DIRECTORY_SEPARATOR;
47 private bool $serverForceResources =
false;
50 private array $resourcePacks = [];
53 private array $uuidList = [];
59 private array $encryptionKeys = [];
67 if(!file_exists($this->path)){
68 $logger->
debug(
"Resource packs path $path does not exist, creating directory");
70 }elseif(!is_dir($this->path)){
71 throw new \InvalidArgumentException(
"Resource packs path $path exists and is not a directory");
74 $resourcePacksYml = Path::join($this->path,
"resource_packs.yml");
75 if(!file_exists($resourcePacksYml)){
76 copy(Path::join(\
pocketmine\RESOURCE_PATH,
"resource_packs.yml"), $resourcePacksYml);
79 $resourcePacksConfig =
new Config($resourcePacksYml, Config::YAML, []);
81 $this->serverForceResources = (bool) $resourcePacksConfig->get(
"force_resources",
false);
83 $logger->
info(
"Loading resource packs...");
85 $resourceStack = $resourcePacksConfig->get(
"resource_stack", []);
86 if(!is_array($resourceStack)){
87 throw new \InvalidArgumentException(
"\"resource_stack\" key should contain a list of pack names");
90 foreach($resourceStack as $pos => $pack){
91 if(!is_string($pack) && !is_int($pack) && !is_float($pack)){
92 $logger->
critical(
"Found invalid entry in resource pack list at offset $pos of type " . gettype($pack));
95 $pack = (string) $pack;
97 $newPack = $this->loadPackFromPath(Path::join($this->path, $pack));
99 $this->resourcePacks[] = $newPack;
100 $index = strtolower($newPack->getPackId());
101 $this->uuidList[$index] = $newPack;
103 $keyPath = Path::join($this->path, $pack .
".key");
104 if(file_exists($keyPath)){
107 }
catch(\RuntimeException $e){
110 $key = rtrim($key,
"\r\n");
111 if(strlen($key) !== 32){
114 $this->encryptionKeys[$index] = $key;
117 $logger->
critical(
"Could not load resource pack \"$pack\": " . $e->getMessage());
121 $logger->
debug(
"Successfully loaded " . count($this->resourcePacks) .
" resource packs");
124 private function loadPackFromPath(
string $packPath) :
ResourcePack{
125 if(!file_exists($packPath)){
128 if(is_dir($packPath)){
129 throw new ResourcePackException(
"Directory resource packs are unsupported");
133 $info = new \SplFileInfo($packPath);
134 switch($info->getExtension()){
137 return new ZippedResourcePack($packPath);
140 throw new ResourcePackException(
"Format not recognized");
147 return $this->path . DIRECTORY_SEPARATOR;
154 return $this->serverForceResources;
161 $this->serverForceResources = $value;
169 return $this->resourcePacks;
183 foreach($resourceStack as $pack){
184 $uuid = strtolower($pack->getPackId());
185 if(isset($uuidList[$uuid])){
186 throw new \InvalidArgumentException(
"Cannot load two resource pack with the same UUID ($uuid)");
188 $uuidList[$uuid] = $pack;
189 $resourcePacks[] = $pack;
191 $this->resourcePacks = $resourcePacks;
192 $this->uuidList = $uuidList;
199 return $this->uuidList[strtolower($id)] ?? null;
207 return array_keys($this->uuidList);
214 return $this->encryptionKeys[strtolower($id)] ?? null;
222 $id = strtolower($id);
225 unset($this->encryptionKeys[$id]);
226 }elseif(isset($this->uuidList[$id])){
227 if(strlen($key) !== 32){
228 throw new \InvalidArgumentException(
"Encryption key must be exactly 32 bytes long");
230 $this->encryptionKeys[$id] = $key;
232 throw new \InvalidArgumentException(
"Unknown pack ID $id");
setPackEncryptionKey(string $id, ?string $key)
setResourcePacksRequired(bool $value)
__construct(string $path, \Logger $logger)
setResourceStack(array $resourceStack)
getPackEncryptionKey(string $id)
static fileGetContents(string $fileName, bool $useIncludePath=false, $context=null, int $offset=0, ?int $length=null)