@tendrock/database
Version:
A database lib under the Tendrock ecosystem for Minecraft Bedrock Edition Script API
122 lines (121 loc) • 5.18 kB
JavaScript
import { world } from "@minecraft/server";
import { Utils } from "./helper/Utils";
import { LocationUtils } from "@tendrock/location-id";
import { ConstructorRegistryImpl } from "./instance/ConstructorRegistry";
export class DynamicPropertySerializer {
constructor() {
}
serializeNonBlockDataIdToPropertyId(identifier) {
return `${DynamicPropertySerializer.TendrockPropertyIdPrefix}${identifier}`;
}
serializeBlockIdToPropertyId(locationOrLid, identifier) {
if (identifier.includes('-')) {
throw new Error(`Invalid identifier: "${identifier}"`);
}
return `${DynamicPropertySerializer.TendrockPropertyIdPrefix}${typeof locationOrLid === 'string' ? locationOrLid : LocationUtils.getLocationId(locationOrLid)}-${identifier}`;
}
validatePropertyId(propertyId) {
return propertyId.startsWith(`${DynamicPropertySerializer.TendrockPropertyIdPrefix}`);
}
validateBlockPropertyId(propertyId) {
return propertyId.startsWith(`${DynamicPropertySerializer.TendrockPropertyIdPrefix}`) && propertyId.split('-').length === 2;
}
getNonBlockDataId(propertyId) {
if (!this.validatePropertyId(propertyId)) {
return propertyId;
}
return propertyId.replace(DynamicPropertySerializer.TendrockPropertyIdPrefix, '');
}
getBlockDataId(block, propertyId) {
if (!this.validateBlockPropertyId(propertyId)) {
return propertyId;
}
const lid = typeof block === 'string' ? block : LocationUtils.getLocationId(block);
const blockDataIdentifier = this.getNonBlockDataId(propertyId);
return blockDataIdentifier.startsWith(lid) ? blockDataIdentifier.substring(lid.length + 2) : blockDataIdentifier;
}
serializeDataToPropertyValue(value) {
if (value === undefined)
return undefined;
if (Utils.isVector3(value)) {
return value;
}
const valueType = typeof value;
if (valueType === 'object') {
return '[tendrock object]' + JSON.stringify(value);
}
else if (valueType === 'string' || valueType === 'number' || valueType === 'boolean') {
return value;
}
else {
throw new Error(`Invalid data type: ${valueType}`);
}
}
deserializePropertyValueToData(value) {
if (typeof value === 'string' && value.startsWith('[tendrock object]')) {
return JSON.parse(value.substring(17));
}
else {
return value;
}
}
_getConstructorId(value) {
if (typeof value !== 'object' || Utils.isVector3(value)) {
return undefined;
}
const constructorId = value['tendrock:cid'];
if (typeof constructorId === 'string')
return constructorId;
// Adapter old data
// TODO: Need to deprecate in several versions
const { constructorName } = value;
if (typeof constructorName === 'string')
return constructorName;
return undefined;
}
deserializeDataToInstance(uniqueId, value, identifier, database) {
if (typeof value !== 'object' || Utils.isVector3(value)) {
return value;
}
const constructorId = this._getConstructorId(value);
if (!constructorId)
return value;
const constructor = ConstructorRegistryImpl.Instance.get(constructorId);
if (!constructor)
return value;
return new constructor(value, { uniqueId, identifier, database }, undefined);
}
deserializePropertyId(propertyId) {
if (!this.validatePropertyId(propertyId)) {
return {};
}
const dataIdentifier = this.getNonBlockDataId(propertyId);
const dataIdSplit = dataIdentifier.split('-');
if (dataIdSplit.length === 2) {
return { lid: dataIdSplit[0], dataIdentifier: dataIdSplit[1] };
}
else {
return { dataIdentifier };
}
}
putToWorld(identifier, value) {
world.setDynamicProperty(this.serializeNonBlockDataIdToPropertyId(identifier), this.serializeDataToPropertyValue(value));
}
putToBlock(blockOrLid, identifier, value) {
world.setDynamicProperty(this.serializeBlockIdToPropertyId(blockOrLid, identifier), this.serializeDataToPropertyValue(value));
}
putToEntity(entity, identifier, value) {
entity.setDynamicProperty(this.serializeNonBlockDataIdToPropertyId(identifier), this.serializeDataToPropertyValue(value));
}
putToItem(item, identifier, value) {
item.setDynamicProperty(this.serializeNonBlockDataIdToPropertyId(identifier), this.serializeDataToPropertyValue(value));
}
getFromWorld(identifier) {
return world.getDynamicProperty(this.serializeNonBlockDataIdToPropertyId(identifier));
}
getFromBlock(blockOrLid, identifier) {
return world.getDynamicProperty(this.serializeBlockIdToPropertyId(blockOrLid, identifier));
}
}
DynamicPropertySerializer.TendrockPropertyIdPrefix = '[tendrock]';
DynamicPropertySerializer.Instance = new DynamicPropertySerializer();