mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-20 07:54:19 +00:00
Merge branch 'stable' into master
This commit is contained in:
commit
e1d80f05b1
@ -1 +1 @@
|
||||
Subproject commit 43edcfde6b9611b7c7d643be52332707cc10cd1b
|
||||
Subproject commit 767676e2b97843072220bad719c076b169c28fd3
|
@ -24,52 +24,52 @@ declare(strict_types=1);
|
||||
namespace pocketmine\crafting;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use function array_map;
|
||||
use function file_get_contents;
|
||||
use function is_array;
|
||||
use function json_decode;
|
||||
|
||||
final class CraftingManagerFromDataHelper{
|
||||
|
||||
public static function make(string $filePath) : CraftingManager{
|
||||
$recipes = json_decode(file_get_contents($filePath), true);
|
||||
if(!is_array($recipes)){
|
||||
throw new AssumptionFailedError("recipes.json root should contain a map of recipe types");
|
||||
}
|
||||
$result = new CraftingManager();
|
||||
|
||||
$itemDeserializerFunc = \Closure::fromCallable([Item::class, 'jsonDeserialize']);
|
||||
foreach($recipes as $recipe){
|
||||
switch($recipe["type"]){
|
||||
case "shapeless":
|
||||
if($recipe["block"] !== "crafting_table"){ //TODO: filter others out for now to avoid breaking economics
|
||||
break;
|
||||
}
|
||||
$result->registerShapelessRecipe(new ShapelessRecipe(
|
||||
array_map($itemDeserializerFunc, $recipe["input"]),
|
||||
array_map($itemDeserializerFunc, $recipe["output"])
|
||||
));
|
||||
break;
|
||||
case "shaped":
|
||||
if($recipe["block"] !== "crafting_table"){ //TODO: filter others out for now to avoid breaking economics
|
||||
break;
|
||||
}
|
||||
$result->registerShapedRecipe(new ShapedRecipe(
|
||||
$recipe["shape"],
|
||||
array_map($itemDeserializerFunc, $recipe["input"]),
|
||||
array_map($itemDeserializerFunc, $recipe["output"])
|
||||
));
|
||||
break;
|
||||
case "smelting":
|
||||
if($recipe["block"] !== "furnace"){ //TODO: filter others out for now to avoid breaking economics
|
||||
break;
|
||||
}
|
||||
$result->getFurnaceRecipeManager()->register(new FurnaceRecipe(
|
||||
Item::jsonDeserialize($recipe["output"]),
|
||||
Item::jsonDeserialize($recipe["input"]))
|
||||
);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
foreach($recipes["shapeless"] as $recipe){
|
||||
if($recipe["block"] !== "crafting_table"){ //TODO: filter others out for now to avoid breaking economics
|
||||
continue;
|
||||
}
|
||||
$result->registerShapelessRecipe(new ShapelessRecipe(
|
||||
array_map($itemDeserializerFunc, $recipe["input"]),
|
||||
array_map($itemDeserializerFunc, $recipe["output"])
|
||||
));
|
||||
}
|
||||
foreach($recipes["shaped"] as $recipe){
|
||||
if($recipe["block"] !== "crafting_table"){ //TODO: filter others out for now to avoid breaking economics
|
||||
continue;
|
||||
}
|
||||
$result->registerShapedRecipe(new ShapedRecipe(
|
||||
$recipe["shape"],
|
||||
array_map($itemDeserializerFunc, $recipe["input"]),
|
||||
array_map($itemDeserializerFunc, $recipe["output"])
|
||||
));
|
||||
}
|
||||
foreach($recipes["smelting"] as $recipe){
|
||||
if($recipe["block"] !== "furnace"){ //TODO: filter others out for now to avoid breaking economics
|
||||
continue;
|
||||
}
|
||||
$result->getFurnaceRecipeManager()->register(new FurnaceRecipe(
|
||||
Item::jsonDeserialize($recipe["output"]),
|
||||
Item::jsonDeserialize($recipe["input"]))
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -137,6 +137,8 @@ class InventoryTransaction{
|
||||
* @throws TransactionValidationException
|
||||
*/
|
||||
protected function matchItems(array &$needItems, array &$haveItems) : void{
|
||||
$needItems = [];
|
||||
$haveItems = [];
|
||||
foreach($this->actions as $key => $action){
|
||||
if(!$action->getTargetItem()->isNull()){
|
||||
$needItems[] = $action->getTargetItem();
|
||||
|
@ -34,6 +34,7 @@ use pocketmine\inventory\transaction\action\InventoryAction;
|
||||
use pocketmine\inventory\transaction\CraftingTransaction;
|
||||
use pocketmine\inventory\transaction\InventoryTransaction;
|
||||
use pocketmine\inventory\transaction\TransactionException;
|
||||
use pocketmine\inventory\transaction\TransactionValidationException;
|
||||
use pocketmine\item\VanillaItems;
|
||||
use pocketmine\item\WritableBook;
|
||||
use pocketmine\item\WrittenBook;
|
||||
@ -82,10 +83,12 @@ use pocketmine\network\mcpe\protocol\ShowCreditsPacket;
|
||||
use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket;
|
||||
use pocketmine\network\mcpe\protocol\SubClientLoginPacket;
|
||||
use pocketmine\network\mcpe\protocol\TextPacket;
|
||||
use pocketmine\network\mcpe\protocol\types\inventory\ContainerIds;
|
||||
use pocketmine\network\mcpe\protocol\types\inventory\MismatchTransactionData;
|
||||
use pocketmine\network\mcpe\protocol\types\inventory\NetworkInventoryAction;
|
||||
use pocketmine\network\mcpe\protocol\types\inventory\NormalTransactionData;
|
||||
use pocketmine\network\mcpe\protocol\types\inventory\ReleaseItemTransactionData;
|
||||
use pocketmine\network\mcpe\protocol\types\inventory\UIInventorySlotOffset;
|
||||
use pocketmine\network\mcpe\protocol\types\inventory\UseItemOnEntityTransactionData;
|
||||
use pocketmine\network\mcpe\protocol\types\inventory\UseItemTransactionData;
|
||||
use pocketmine\network\mcpe\protocol\types\inventory\WindowTypes;
|
||||
@ -215,19 +218,23 @@ class InGamePacketHandler extends PacketHandler{
|
||||
$actions = [];
|
||||
|
||||
$isCraftingPart = false;
|
||||
$isFinalCraftingPart = false;
|
||||
$converter = TypeConverter::getInstance();
|
||||
foreach($data->getActions() as $networkInventoryAction){
|
||||
if(
|
||||
$networkInventoryAction->sourceType === NetworkInventoryAction::SOURCE_TODO and (
|
||||
$networkInventoryAction->windowId === NetworkInventoryAction::SOURCE_TYPE_CRAFTING_RESULT or
|
||||
$networkInventoryAction->windowId === NetworkInventoryAction::SOURCE_TYPE_CRAFTING_USE_INGREDIENT
|
||||
(
|
||||
$networkInventoryAction->sourceType === NetworkInventoryAction::SOURCE_TODO and (
|
||||
$networkInventoryAction->windowId === NetworkInventoryAction::SOURCE_TYPE_CRAFTING_RESULT or
|
||||
$networkInventoryAction->windowId === NetworkInventoryAction::SOURCE_TYPE_CRAFTING_USE_INGREDIENT
|
||||
)
|
||||
) or (
|
||||
$this->craftingTransaction !== null &&
|
||||
!$networkInventoryAction->oldItem->equals($networkInventoryAction->newItem) &&
|
||||
$networkInventoryAction->sourceType === NetworkInventoryAction::SOURCE_CONTAINER &&
|
||||
$networkInventoryAction->windowId === ContainerIds::UI &&
|
||||
$networkInventoryAction->inventorySlot === UIInventorySlotOffset::CREATED_ITEM_OUTPUT
|
||||
)
|
||||
){
|
||||
$isCraftingPart = true;
|
||||
if($networkInventoryAction->windowId === NetworkInventoryAction::SOURCE_TYPE_CRAFTING_RESULT){
|
||||
$isFinalCraftingPart = true;
|
||||
}
|
||||
}
|
||||
|
||||
try{
|
||||
@ -242,9 +249,6 @@ class InGamePacketHandler extends PacketHandler{
|
||||
}
|
||||
|
||||
if($isCraftingPart){
|
||||
//we get the actions for this in several packets, so we need to wait until we have all the pieces before
|
||||
//trying to execute it
|
||||
|
||||
if($this->craftingTransaction === null){
|
||||
$this->craftingTransaction = new CraftingTransaction($this->player, $this->player->getServer()->getCraftingManager(), $actions);
|
||||
}else{
|
||||
@ -253,29 +257,34 @@ class InGamePacketHandler extends PacketHandler{
|
||||
}
|
||||
}
|
||||
|
||||
if($isFinalCraftingPart){
|
||||
try{
|
||||
$this->session->getInvManager()->onTransactionStart($this->craftingTransaction);
|
||||
$this->craftingTransaction->execute();
|
||||
}catch(TransactionException $e){
|
||||
$this->session->getLogger()->debug("Failed to execute crafting transaction: " . $e->getMessage());
|
||||
try{
|
||||
$this->craftingTransaction->validate();
|
||||
}catch(TransactionValidationException $e){
|
||||
//transaction is incomplete - crafting transaction comes in lots of little bits, so we have to collect
|
||||
//all of the parts before we can execute it
|
||||
return true;
|
||||
}
|
||||
try{
|
||||
$this->session->getInvManager()->onTransactionStart($this->craftingTransaction);
|
||||
$this->craftingTransaction->execute();
|
||||
}catch(TransactionException $e){
|
||||
$this->session->getLogger()->debug("Failed to execute crafting transaction: " . $e->getMessage());
|
||||
|
||||
//TODO: only sync slots that the client tried to change
|
||||
foreach($this->craftingTransaction->getInventories() as $inventory){
|
||||
$this->session->getInvManager()->syncContents($inventory);
|
||||
}
|
||||
/*
|
||||
* TODO: HACK!
|
||||
* we can't resend the contents of the crafting window, so we force the client to close it instead.
|
||||
* So people don't whine about messy desync issues when someone cancels CraftItemEvent, or when a crafting
|
||||
* transaction goes wrong.
|
||||
*/
|
||||
$this->session->sendDataPacket(ContainerClosePacket::create(InventoryManager::HARDCODED_CRAFTING_GRID_WINDOW_ID));
|
||||
|
||||
return false;
|
||||
}finally{
|
||||
$this->craftingTransaction = null;
|
||||
//TODO: only sync slots that the client tried to change
|
||||
foreach($this->craftingTransaction->getInventories() as $inventory){
|
||||
$this->session->getInvManager()->syncContents($inventory);
|
||||
}
|
||||
/*
|
||||
* TODO: HACK!
|
||||
* we can't resend the contents of the crafting window, so we force the client to close it instead.
|
||||
* So people don't whine about messy desync issues when someone cancels CraftItemEvent, or when a crafting
|
||||
* transaction goes wrong.
|
||||
*/
|
||||
$this->session->sendDataPacket(ContainerClosePacket::create(InventoryManager::HARDCODED_CRAFTING_GRID_WINDOW_ID));
|
||||
|
||||
return false;
|
||||
}finally{
|
||||
$this->craftingTransaction = null;
|
||||
}
|
||||
}else{
|
||||
//normal transaction fallthru
|
||||
|
@ -52,7 +52,7 @@ class VersionString{
|
||||
$this->development = $isDevBuild;
|
||||
$this->build = $buildNumber;
|
||||
|
||||
preg_match('/(\d+)\.(\d+)\.(\d+)(?:-(.*))?$/', $this->baseVersion, $matches);
|
||||
preg_match('/^(\d+)\.(\d+)\.(\d+)(?:-(.*))?$/', $this->baseVersion, $matches);
|
||||
if(count($matches) < 4){
|
||||
throw new \InvalidArgumentException("Invalid base version \"$baseVersion\", should contain at least 3 version digits");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user