Item is no longer JsonSerializable

before anyone starts screaming:

1) it's easy to create your own wrapper that converts items to arrays
2) there is no longer a single standard way to encode items.
3) the way that item serialization now works requires an ItemSerializer, which, barring singleton use, must be dependency-injected. Since there's no way to inject dependencies into jsonSerialize(), this means that its behaviour cannot be customized.
This commit is contained in:
Dylan K. Taylor 2022-06-30 19:16:20 +01:00
parent 4bd087fc83
commit db2b523762
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
3 changed files with 26 additions and 33 deletions

View File

@ -57,7 +57,7 @@ final class CraftingManagerFromDataHelper{
//TODO: we need to stop using jsonDeserialize for this
try{
$item = Item::jsonDeserialize($data);
$item = Item::legacyJsonDeserialize($data);
}catch(SavedDataLoadingException){
//unknown item
return null;
@ -74,7 +74,7 @@ final class CraftingManagerFromDataHelper{
$result = new CraftingManager();
$ingredientDeserializerFunc = \Closure::fromCallable([self::class, "deserializeIngredient"]);
$itemDeserializerFunc = \Closure::fromCallable([Item::class, 'jsonDeserialize']);
$itemDeserializerFunc = \Closure::fromCallable([Item::class, 'legacyJsonDeserialize']);
foreach($recipes["shapeless"] as $recipe){
$recipeType = match($recipe["block"]){
@ -142,7 +142,7 @@ final class CraftingManagerFromDataHelper{
continue;
}
try{
$output = Item::jsonDeserialize($recipe["output"]);
$output = Item::legacyJsonDeserialize($recipe["output"]);
}catch(SavedDataLoadingException){
continue;
}
@ -157,9 +157,9 @@ final class CraftingManagerFromDataHelper{
}
foreach($recipes["potion_type"] as $recipe){
try{
$input = Item::jsonDeserialize($recipe["input"]);
$ingredient = Item::jsonDeserialize($recipe["ingredient"]);
$output = Item::jsonDeserialize($recipe["output"]);
$input = Item::legacyJsonDeserialize($recipe["input"]);
$ingredient = Item::legacyJsonDeserialize($recipe["ingredient"]);
$output = Item::legacyJsonDeserialize($recipe["output"]);
}catch(SavedDataLoadingException){
//unknown item
continue;
@ -172,7 +172,7 @@ final class CraftingManagerFromDataHelper{
}
foreach($recipes["potion_container_change"] as $recipe){
try{
$ingredient = Item::jsonDeserialize($recipe["ingredient"]);
$ingredient = Item::legacyJsonDeserialize($recipe["ingredient"]);
}catch(SavedDataLoadingException){
//unknown item
continue;

View File

@ -41,7 +41,7 @@ final class CreativeInventory{
foreach($creativeItems as $data){
try{
$item = Item::jsonDeserialize($data);
$item = Item::legacyJsonDeserialize($data);
}catch(SavedDataLoadingException){
//unknown item
continue;

View File

@ -575,38 +575,21 @@ class Item implements \JsonSerializable{
}
/**
* Returns an array of item stack properties that can be serialized to json.
*
* @return mixed[]
* @phpstan-return array{id: int, damage?: int, count?: int, nbt_b64?: string}
* @phpstan-return never
*/
final public function jsonSerialize() : array{
$data = [
"id" => $this->getId()
];
if($this->getMeta() !== 0){
$data["damage"] = $this->getMeta();
}
if($this->getCount() !== 1){
$data["count"] = $this->getCount();
}
if($this->hasNamedTag()){
$data["nbt_b64"] = base64_encode((new LittleEndianNbtSerializer())->write(new TreeRoot($this->getNamedTag())));
}
return $data;
public function jsonSerialize() : array{
throw new \LogicException("json_encode()ing Item instances is no longer supported. Make your own method to convert the item to an array or stdClass.");
}
/**
* @deprecated This is intended for deserializing legacy data from the old crafting JSON and creative JSON data.
*
* Returns an Item from properties created in an array by {@link Item#jsonSerialize}
* @param mixed[] $data
*
* @throws SavedDataLoadingException
*/
final public static function jsonDeserialize(array $data) : Item{
final public static function legacyJsonDeserialize(array $data) : Item{
$nbt = "";
//Backwards compatibility
@ -617,9 +600,19 @@ class Item implements \JsonSerializable{
}elseif(isset($data["nbt_b64"])){
$nbt = base64_decode($data["nbt_b64"], true);
}
return ItemFactory::getInstance()->get(
(int) $data["id"], (int) ($data["damage"] ?? 0), (int) ($data["count"] ?? 1), $nbt !== "" ? (new LittleEndianNbtSerializer())->read($nbt)->mustGetCompoundTag() : null
$itemStackData = GlobalItemDataHandlers::getUpgrader()->upgradeItemTypeDataInt(
(int) $data["id"],
(int) ($data["damage"] ?? 0),
(int) ($data["count"] ?? 1),
$nbt !== "" ? (new LittleEndianNbtSerializer())->read($nbt)->mustGetCompoundTag() : null
);
try{
return GlobalItemDataHandlers::getDeserializer()->deserializeStack($itemStackData);
}catch(ItemTypeDeserializeException $e){
throw new SavedDataLoadingException($e->getMessage(), 0, $e);
}
}
/**