mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-05 09:26:06 +00:00
Allow offering different resource packs to different players (#6249)
closes #6248
This commit is contained in:
@ -37,12 +37,13 @@ use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackInfoEntry;
|
||||
use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackStackEntry;
|
||||
use pocketmine\network\mcpe\protocol\types\resourcepacks\ResourcePackType;
|
||||
use pocketmine\resourcepacks\ResourcePack;
|
||||
use pocketmine\resourcepacks\ResourcePackManager;
|
||||
use function array_keys;
|
||||
use function array_map;
|
||||
use function ceil;
|
||||
use function count;
|
||||
use function implode;
|
||||
use function strpos;
|
||||
use function strtolower;
|
||||
use function substr;
|
||||
|
||||
/**
|
||||
@ -52,35 +53,55 @@ use function substr;
|
||||
class ResourcePacksPacketHandler extends PacketHandler{
|
||||
private const PACK_CHUNK_SIZE = 128 * 1024; //128KB
|
||||
|
||||
/**
|
||||
* @var ResourcePack[]
|
||||
* @phpstan-var array<string, ResourcePack>
|
||||
*/
|
||||
private array $resourcePacksById = [];
|
||||
|
||||
/** @var bool[][] uuid => [chunk index => hasSent] */
|
||||
private array $downloadedChunks = [];
|
||||
|
||||
/**
|
||||
* @phpstan-param \Closure() : void $completionCallback
|
||||
* @param ResourcePack[] $resourcePackStack
|
||||
* @param string[] $encryptionKeys pack UUID => key, leave unset for any packs that are not encrypted
|
||||
*
|
||||
* @phpstan-param list<ResourcePack> $resourcePackStack
|
||||
* @phpstan-param array<string, string> $encryptionKeys
|
||||
* @phpstan-param \Closure() : void $completionCallback
|
||||
*/
|
||||
public function __construct(
|
||||
private NetworkSession $session,
|
||||
private ResourcePackManager $resourcePackManager,
|
||||
private array $resourcePackStack,
|
||||
private array $encryptionKeys,
|
||||
private bool $mustAccept,
|
||||
private \Closure $completionCallback
|
||||
){}
|
||||
){
|
||||
foreach($resourcePackStack as $pack){
|
||||
$this->resourcePacksById[$pack->getPackId()] = $pack;
|
||||
}
|
||||
}
|
||||
|
||||
private function getPackById(string $id) : ?ResourcePack{
|
||||
return $this->resourcePacksById[strtolower($id)] ?? null;
|
||||
}
|
||||
|
||||
public function setUp() : void{
|
||||
$resourcePackEntries = array_map(function(ResourcePack $pack) : ResourcePackInfoEntry{
|
||||
//TODO: more stuff
|
||||
$encryptionKey = $this->resourcePackManager->getPackEncryptionKey($pack->getPackId());
|
||||
|
||||
return new ResourcePackInfoEntry(
|
||||
$pack->getPackId(),
|
||||
$pack->getPackVersion(),
|
||||
$pack->getPackSize(),
|
||||
$encryptionKey ?? "",
|
||||
$this->encryptionKeys[$pack->getPackId()] ?? "",
|
||||
"",
|
||||
$pack->getPackId(),
|
||||
false
|
||||
);
|
||||
}, $this->resourcePackManager->getResourceStack());
|
||||
//TODO: support forcing server packs
|
||||
$this->session->sendDataPacket(ResourcePacksInfoPacket::create($resourcePackEntries, [], $this->resourcePackManager->resourcePacksRequired(), false, false, []));
|
||||
}, $this->resourcePackStack);
|
||||
// TODO: support forcing server packs
|
||||
$this->session->sendDataPacket(ResourcePacksInfoPacket::create($resourcePackEntries, [], $this->mustAccept, false, false, []));
|
||||
$this->session->getLogger()->debug("Waiting for client to accept resource packs");
|
||||
}
|
||||
|
||||
@ -104,11 +125,11 @@ class ResourcePacksPacketHandler extends PacketHandler{
|
||||
if($splitPos !== false){
|
||||
$uuid = substr($uuid, 0, $splitPos);
|
||||
}
|
||||
$pack = $this->resourcePackManager->getPackById($uuid);
|
||||
$pack = $this->getPackById($uuid);
|
||||
|
||||
if(!($pack instanceof ResourcePack)){
|
||||
//Client requested a resource pack but we don't have it available on the server
|
||||
$this->disconnectWithError("Unknown pack $uuid requested, available packs: " . implode(", ", $this->resourcePackManager->getPackIdList()));
|
||||
$this->disconnectWithError("Unknown pack $uuid requested, available packs: " . implode(", ", array_keys($this->resourcePacksById)));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -128,7 +149,7 @@ class ResourcePacksPacketHandler extends PacketHandler{
|
||||
case ResourcePackClientResponsePacket::STATUS_HAVE_ALL_PACKS:
|
||||
$stack = array_map(static function(ResourcePack $pack) : ResourcePackStackEntry{
|
||||
return new ResourcePackStackEntry($pack->getPackId(), $pack->getPackVersion(), ""); //TODO: subpacks
|
||||
}, $this->resourcePackManager->getResourceStack());
|
||||
}, $this->resourcePackStack);
|
||||
|
||||
//we support chemistry blocks by default, the client should already have this installed
|
||||
$stack[] = new ResourcePackStackEntry("0fba4063-dba1-4281-9b89-ff9390653530", "1.0.0", "");
|
||||
@ -151,9 +172,9 @@ class ResourcePacksPacketHandler extends PacketHandler{
|
||||
}
|
||||
|
||||
public function handleResourcePackChunkRequest(ResourcePackChunkRequestPacket $packet) : bool{
|
||||
$pack = $this->resourcePackManager->getPackById($packet->packId);
|
||||
$pack = $this->getPackById($packet->packId);
|
||||
if(!($pack instanceof ResourcePack)){
|
||||
$this->disconnectWithError("Invalid request for chunk $packet->chunkIndex of unknown pack $packet->packId, available packs: " . implode(", ", $this->resourcePackManager->getPackIdList()));
|
||||
$this->disconnectWithError("Invalid request for chunk $packet->chunkIndex of unknown pack $packet->packId, available packs: " . implode(", ", array_keys($this->resourcePacksById)));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user