wip: Construct API
This commit is contained in:
@@ -0,0 +1,18 @@
|
|||||||
|
import { AddonAPI } from "../lib/AddonAPIKit/AddonAPIKit";
|
||||||
|
import { PACK_IDENTIFIER } from "../consts";
|
||||||
|
import { InstancesController } from "./controllers/InstancesController";
|
||||||
|
import { structureCollection } from "../classes/Structure/StructureCollection";
|
||||||
|
import { BuildersController } from "./controllers/BuildersController";
|
||||||
|
import { Builders } from "../classes/Builder/Builders";
|
||||||
|
|
||||||
|
class ConstructAPI extends AddonAPI {
|
||||||
|
constructor(version) {
|
||||||
|
super(PACK_IDENTIFIER, version);
|
||||||
|
const instancesController = new InstancesController(structureCollection);
|
||||||
|
this.setupController(instancesController);
|
||||||
|
const buildersController = new BuildersController(Builders);
|
||||||
|
this.setupController(buildersController);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const constructAPI = new ConstructAPI("1.0.0");
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { BuilderNotFoundError } from "../../classes/Errors/BuilderNotFoundError";
|
||||||
|
import { APICallerError } from "../../lib/AddonAPIKit/AddonAPIKit";
|
||||||
|
import { BuilderIdParameterModel } from "../models/BuildersModel";
|
||||||
|
|
||||||
|
export class BuildersController extends APIController {
|
||||||
|
#context;
|
||||||
|
|
||||||
|
constructor(context) {
|
||||||
|
super({
|
||||||
|
"builders:get": { callback: this.getBuilder, parameterModel: BuilderIdParameterModel, returnModel: InstanceModel },
|
||||||
|
"builders:edit": { callback: this.editBuilder, parameterModel: InstanceModel, returnModel: InstanceModel }
|
||||||
|
});
|
||||||
|
this.#context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
getBuilder(playerId) {
|
||||||
|
try {
|
||||||
|
const builder = this.#context.get(playerId);
|
||||||
|
return builder.asPacket();
|
||||||
|
} catch(error) {
|
||||||
|
if (error instanceof BuilderNotFoundErrors)
|
||||||
|
throw new APICallerError(error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
editBuilder(builderOptions) {
|
||||||
|
try {
|
||||||
|
const builder = this.#context.get(builderOptions.playerId);
|
||||||
|
builder.setOptions(builderOptions);
|
||||||
|
} catch(error) {
|
||||||
|
if (error instanceof BuilderNotFoundError)
|
||||||
|
throw new APICallerError(error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
import { InstanceExistsError } from "../../classes/Errors/InstanceExistsError";
|
||||||
|
import { InstanceNotFoundError } from "../../classes/Errors/InstanceNotFoundError";
|
||||||
|
import { StructureNotFoundError } from "../../classes/Errors/StructureNotFoundError";
|
||||||
|
import { APICallerError, VoidModel } from "../../lib/AddonAPIKit/AddonAPIKit";
|
||||||
|
import { AddInstanceParameterModel, InstanceModel, InstanceNameParameterModel, InstancesModel, StructureMaterialsModel } from "../models/InstancesModel";
|
||||||
|
|
||||||
|
export class InstancesController extends APIController {
|
||||||
|
#context;
|
||||||
|
|
||||||
|
constructor(context) {
|
||||||
|
super({
|
||||||
|
"instances": { callback: this.getInstances, parameterModel: VoidModel, returnModel: InstancesModel },
|
||||||
|
"instance:get": { callback: this.getInstance, parameterModel: InstanceNameParameterModel, returnModel: InstanceModel },
|
||||||
|
"instance:add": { callback: this.addInstance, parameterModel: AddInstanceParameterModel, returnModel: InstanceModel },
|
||||||
|
"instance:edit": { callback: this.editInstance, parameterModel: InstanceModel, returnModel: InstanceModel },
|
||||||
|
"instance:delete": { callback: this.deleteInstance, parameterModel: InstanceNameParameterModel, returnModel: VoidModel },
|
||||||
|
"instance:materials": { callback: this.getMaterials, parameterModel: InstanceNameParameterModel, returnModel: StructureMaterialsModel }
|
||||||
|
});
|
||||||
|
this.#context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
getInstances() {
|
||||||
|
return this.#context.getInstanceNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
getInstance(instanceName) {
|
||||||
|
try {
|
||||||
|
const instance = this.#context.get(instanceName);
|
||||||
|
return instance.asPacket();
|
||||||
|
} catch(error) {
|
||||||
|
if (error instanceof InstanceNotFoundError)
|
||||||
|
throw new APICallerError(error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addInstance(instanceName, structureId) {
|
||||||
|
try {
|
||||||
|
const instance = this.#context.add(instanceName, structureId);
|
||||||
|
return instance.asPacket();
|
||||||
|
} catch(error) {
|
||||||
|
if (error instanceof InstanceExistsError || error instanceof StructureNotFoundError)
|
||||||
|
throw new APICallerError(error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
editInstance(instanceName, instanceOptions) {
|
||||||
|
try {
|
||||||
|
const instance = this.#context.get(instanceName);
|
||||||
|
instance.setOptions(instanceOptions);
|
||||||
|
} catch(error) {
|
||||||
|
if (error instanceof InstanceNotFoundError || error instanceof InstanceExistsError || error instanceof StructureNotFoundError)
|
||||||
|
throw new APICallerError(error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteInstance(instanceName) {
|
||||||
|
try {
|
||||||
|
this.#context.delete(instanceName);
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof InstanceNotFoundError)
|
||||||
|
throw new APICallerError(error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getMaterials(instanceName) {
|
||||||
|
try {
|
||||||
|
const instance = this.#context.get(instanceName);
|
||||||
|
const structureMaterials = instance.getActiveMaterials();
|
||||||
|
return structureMaterials.allMaterials;
|
||||||
|
} catch(error) {
|
||||||
|
if (error instanceof InstanceNotFoundError)
|
||||||
|
throw new APICallerError(error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { PROTO } from "../../lib/AddonAPIKit/AddonAPIKit";
|
||||||
|
|
||||||
|
export const BuilderModel = PROTO.Object({
|
||||||
|
playerId: PROTO.String,
|
||||||
|
easyPlace: PROTO.Boolean,
|
||||||
|
fastEasyPlace: PROTO.Boolean,
|
||||||
|
materialGrabber: PROTO.Boolean,
|
||||||
|
materialInstanceName: PROTO.String
|
||||||
|
});
|
||||||
|
|
||||||
|
export const BuilderIdParameterModel = PROTO.Object({
|
||||||
|
playerId: PROTO.String
|
||||||
|
});
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import { PROTO } from '../../lib/AddonAPIKit/AddonAPIKit';
|
||||||
|
|
||||||
|
const LocationModel = PROTO.Object({
|
||||||
|
x: PROTO.Float64,
|
||||||
|
y: PROTO.Float64,
|
||||||
|
z: PROTO.Float64
|
||||||
|
});
|
||||||
|
|
||||||
|
export const InstanceModel = PROTO.Object({
|
||||||
|
name: PROTO.String,
|
||||||
|
structureId: PROTO.String,
|
||||||
|
isEnabled: PROTO.Boolean,
|
||||||
|
dimensionId: PROTO.Optional(PROTO.String),
|
||||||
|
location: PROTO.Optional(LocationModel),
|
||||||
|
bounds: PROTO.Optional(PROTO.Object({
|
||||||
|
min: LocationModel,
|
||||||
|
max: LocationModel
|
||||||
|
})),
|
||||||
|
currentLayer: PROTO.Int16,
|
||||||
|
maxLayer: PROTO.Int16,
|
||||||
|
verifier: PROTO.Object({
|
||||||
|
isEnabled: PROTO.Boolean,
|
||||||
|
trackPlayerDistance: PROTO.Int8,
|
||||||
|
particleLifetime: PROTO.Int32
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
export const InstancesModel = PROTO.Array(InstanceModel);
|
||||||
|
|
||||||
|
export const StructureMaterialsModel = PROTO.Map(PROTO.String, PROTO.Int32);
|
||||||
|
|
||||||
|
export const InstanceNameParameterModel = PROTO.Object({
|
||||||
|
instanceName: PROTO.String
|
||||||
|
});
|
||||||
|
|
||||||
|
export const AddInstanceParameterModel = PROTO.Object({
|
||||||
|
instanceName: PROTO.String,
|
||||||
|
structureId: PROTO.String
|
||||||
|
});
|
||||||
|
|
||||||
|
export const EditInstanceParameterModel = PROTO.Object({
|
||||||
|
instanceName: PROTO.String,
|
||||||
|
instance: InstanceModel
|
||||||
|
});
|
||||||
@@ -20,4 +20,21 @@ export class Builder {
|
|||||||
isFlexibleInstanceMoving() {
|
isFlexibleInstanceMoving() {
|
||||||
return this.flexibleInstanceMovement !== void 0;
|
return this.flexibleInstanceMovement !== void 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asPacket() {
|
||||||
|
return {
|
||||||
|
playerId: this.playerId,
|
||||||
|
easyPlace: this.isOptionEnabled('easyPlace'),
|
||||||
|
fastEasyPlace: this.isOptionEnabled('fastEasyPlace'),
|
||||||
|
materialGrabber: this.isOptionEnabled('materialGrabber'),
|
||||||
|
materialInstanceName: this.materialInstanceName
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
setOptions(builderOptions) {
|
||||||
|
this.setOption('easyPlace', builderOptions.easyPlace);
|
||||||
|
this.setOption('fastEasyPlace', builderOptions.fastEasyPlace);
|
||||||
|
this.setOption('materialGrabber', builderOptions.materialGrabber);
|
||||||
|
this.materialInstanceName = builderOptions.materialInstanceName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,29 +1,36 @@
|
|||||||
import { world } from "@minecraft/server";
|
import { world } from "@minecraft/server";
|
||||||
import { Builder } from "./Builder";
|
import { Builder } from "./Builder";
|
||||||
|
import { BuilderNotFoundError } from "../Errors/BuilderNotFoundError";
|
||||||
|
|
||||||
export class Builders {
|
export class Builders {
|
||||||
static builders = {};
|
static builders = {};
|
||||||
|
|
||||||
static add(playerId) {
|
static add(playerId) {
|
||||||
if (this.builders[playerId])
|
if (Builders.builders[playerId])
|
||||||
return;
|
return;
|
||||||
this.builders[playerId] = new Builder(playerId);
|
Builders.builders[playerId] = new Builder(playerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
static remove(playerId) {
|
static remove(playerId) {
|
||||||
delete this.builders[playerId];
|
delete Builders.builders[playerId];
|
||||||
}
|
}
|
||||||
|
|
||||||
static get(id) {
|
static get(id) {
|
||||||
return this.builders[id];
|
const builder = Builders.builders[id];
|
||||||
|
if (builder === void 0)
|
||||||
|
throw new BuilderNotFoundError(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static onJoin(playerId) {
|
static onJoin(playerId) {
|
||||||
this.add(playerId);
|
Builders.add(playerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
static onLeave(playerId) {
|
static onLeave(playerId) {
|
||||||
this.remove(playerId);
|
Builders.remove(playerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static getIds() {
|
||||||
|
return Object.keys(Builders.builders);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export class BuilderNotFoundError extends Error {
|
||||||
|
constructor(builderId) {
|
||||||
|
super(`§cBuilder "${builderId}" not found.`);
|
||||||
|
this.name = 'BuilderNotFoundError';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ export class CommandResponseError extends Error {
|
|||||||
throw new Error('getRawMessage() must be implemented by subclasses of CommandResponseError');
|
throw new Error('getRawMessage() must be implemented by subclasses of CommandResponseError');
|
||||||
}
|
}
|
||||||
|
|
||||||
sendTo(source) {
|
sendTo(origin) {
|
||||||
source.sendMessage(this.getRawMessage());
|
origin.sendMessage(this.getRawMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
import { PROTO } from '../../lib/MCBE-IPC/ipc'
|
|
||||||
|
|
||||||
export const Ready = PROTO.Void;
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import { system } from "@minecraft/server";
|
|
||||||
import { Ready } from "./Ready.ipc";
|
|
||||||
|
|
||||||
system.runTimeout(() => {
|
|
||||||
IPC.send(`constructExtension:ready`, Ready, void 0);
|
|
||||||
}, 1);
|
|
||||||
@@ -46,13 +46,8 @@ export class InstanceOptions extends Option {
|
|||||||
return world.getDimension(this.dimensionId);
|
return world.getDimension(this.dimensionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
enable() {
|
setEnabled(enable) {
|
||||||
this.isEnabled = true;
|
this.isEnabled = enable;
|
||||||
this.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
disable() {
|
|
||||||
this.isEnabled = false;
|
|
||||||
this.save();
|
this.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +64,7 @@ export class InstanceOptions extends Option {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setLayer(layer) {
|
setLayer(layer) {
|
||||||
this.currentLayer = layer;
|
this.currentLayer = layer.floor();
|
||||||
this.save();
|
this.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,4 +77,9 @@ export class InstanceOptions extends Option {
|
|||||||
this.verifier.trackPlayerDistance = distance;
|
this.verifier.trackPlayerDistance = distance;
|
||||||
this.save();
|
this.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setVerifierParticleLifetime(lifetime) {
|
||||||
|
this.verifier.particleLifetime = lifetime;
|
||||||
|
this.save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,8 @@ import { world, system, TicksPerSecond } from "@minecraft/server";
|
|||||||
import { InstanceNotPlacedError } from "../Errors/InstanceNotPlacedError";
|
import { InstanceNotPlacedError } from "../Errors/InstanceNotPlacedError";
|
||||||
import { StructureMaterials } from "../Materials/StructureMaterials";
|
import { StructureMaterials } from "../Materials/StructureMaterials";
|
||||||
import { VerificationRenderer } from "../Render/VerificationRenderer";
|
import { VerificationRenderer } from "../Render/VerificationRenderer";
|
||||||
|
import { structureCollection } from "../Structure/StructureCollection";
|
||||||
|
import { InstanceExistsError } from "../Errors/InstanceExistsError";
|
||||||
|
|
||||||
export class StructureInstance {
|
export class StructureInstance {
|
||||||
options;
|
options;
|
||||||
@@ -185,19 +187,26 @@ export class StructureInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enable() {
|
enable() {
|
||||||
this.options.enable();
|
this.options.setEnabled(true);
|
||||||
this.refreshBox();
|
this.refreshBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
disable() {
|
disable() {
|
||||||
this.options.disable();
|
this.options.setEnabled(false);
|
||||||
this.refreshBox();
|
this.refreshBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
rename(newName) {
|
rename(newName) {
|
||||||
|
if (structureCollection.has(newName))
|
||||||
|
throw new InstanceExistsError(newName);
|
||||||
this.options.rename(newName);
|
this.options.rename(newName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setStructure(structureId) {
|
||||||
|
this.options.structureId = structureId;
|
||||||
|
this.structure = new Structure(structureId);
|
||||||
|
}
|
||||||
|
|
||||||
place(dimensionId, worldLocation) {
|
place(dimensionId, worldLocation) {
|
||||||
this.enable();
|
this.enable();
|
||||||
this.move(dimensionId, worldLocation);
|
this.move(dimensionId, worldLocation);
|
||||||
@@ -277,4 +286,36 @@ export class StructureInstance {
|
|||||||
toStructureCoords(worldLocation) {
|
toStructureCoords(worldLocation) {
|
||||||
return Vector.from(worldLocation).subtract(this.options.worldLocation);
|
return Vector.from(worldLocation).subtract(this.options.worldLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asPacket() {
|
||||||
|
const dimensionLocation = this.getLocation();
|
||||||
|
return {
|
||||||
|
name: this.getName(),
|
||||||
|
structureId: this.getStructureId(),
|
||||||
|
isEnabled: this.isEnabled(),
|
||||||
|
dimensionId: dimensionLocation.dimensionId,
|
||||||
|
location: { x: dimensionLocation.location.x, y: dimensionLocation.location.y, z: dimensionLocation.location.z },
|
||||||
|
bounds: this.getBounds(),
|
||||||
|
currentLayer: this.getLayer(),
|
||||||
|
maxLayer: this.getMaxLayer(),
|
||||||
|
verifier: {
|
||||||
|
isEnabled: this.options.verifier.isEnabled,
|
||||||
|
trackPlayerDistance: this.options.verifier.trackPlayerDistance,
|
||||||
|
particleLifetime: this.options.verifier.particleLifetime
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
setOptions(newOptions) {
|
||||||
|
const newVerifierOptions = newOptions.verifier;
|
||||||
|
this.options.rename(newOptions.name);
|
||||||
|
this.options.setStructure(newOptions.structureId);
|
||||||
|
this.options.setEnabled(newOptions.isEnabled);
|
||||||
|
this.options.move(newOptions.dimensionId, newOptions.location);
|
||||||
|
this.options.setLayer(newOptions.currentLayer);
|
||||||
|
this.options.setVerifierEnabled(newVerifierOptions.isEnabled);
|
||||||
|
this.options.setVerifierDistance(newVerifierOptions.trackPlayerDistance);
|
||||||
|
this.options.setVerifierParticleLifetime(newVerifierOptions.particleLifetime);
|
||||||
|
this.options.save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -30,6 +30,10 @@ class StructureMaterials {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get materials() {
|
||||||
|
return this.materials;
|
||||||
|
}
|
||||||
|
|
||||||
get(itemType) {
|
get(itemType) {
|
||||||
return this.materials[itemType];
|
return this.materials[itemType];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import { IPC, PROTO } from "./MCBE-IPC/ipc";
|
||||||
|
import { APICallerError } from "./Errors/APICallerError";
|
||||||
|
import { APIErrorEnum } from "./Errors/APIErrorEnum";
|
||||||
|
import { APIServerError } from "./Errors/APIServerError";
|
||||||
|
import { APIVersionMismatchError } from "./Errors/APIVersionMismatchError";
|
||||||
|
import { ReturnModelShell } from "./APIModels";
|
||||||
|
|
||||||
|
export class AddonAPI {
|
||||||
|
#name;
|
||||||
|
#version;
|
||||||
|
|
||||||
|
constructor(name, version) {
|
||||||
|
this.#name = name;
|
||||||
|
this.#version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return this.#name;
|
||||||
|
}
|
||||||
|
|
||||||
|
get version() {
|
||||||
|
return this.#version;
|
||||||
|
}
|
||||||
|
|
||||||
|
get endpointBase() {
|
||||||
|
return this.#name + ':';
|
||||||
|
}
|
||||||
|
|
||||||
|
setupController(apiController) {
|
||||||
|
for (const [endpoint, features] of Object.entries(apiController.endpoints)) {
|
||||||
|
const {callback, parameterModel, returnModel} = features;
|
||||||
|
const boundCallback = callback.bind(apiController);
|
||||||
|
this.#setupEndpoint(endpoint, boundCallback, parameterModel, returnModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#setupEndpoint(endpoint, callback, parameterModel, returnDataModel) {
|
||||||
|
const returnPacketModel = this.#resolveReturnModel(returnDataModel);
|
||||||
|
const endpointPath = this.endpointBase + endpoint;
|
||||||
|
IPC.handle(endpointPath, parameterModel, returnPacketModel, (callPacket) => {
|
||||||
|
const apiVersion = callPacket.apiVersion;
|
||||||
|
const parameters = Object.values(callPacket.parameterMap);
|
||||||
|
return this.#handleCallback(apiVersion, callback, parameters);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#handleCallback(apiVersion, callback, parameters) {
|
||||||
|
try {
|
||||||
|
this.#assertVersionsMatch(apiVersion);
|
||||||
|
const returnValue = callback(...parameters);
|
||||||
|
return this.#bundleReturnPacket({ code: APIErrorEnum.Success }, returnValue);
|
||||||
|
} catch(error) {
|
||||||
|
if (error instanceof APICallerError)
|
||||||
|
const errorPacket = this.#resolveErrorPacket(error);
|
||||||
|
return this.#bundleReturnPacket(errorPacket);
|
||||||
|
console.error(error);
|
||||||
|
const apiError = new APIServerError(error);
|
||||||
|
const errorPacket = this.#resolveErrorPacket(apiError);
|
||||||
|
return this.#bundleReturnPacket(errorPacket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#assertVersionsMatch(versionToCheck) {
|
||||||
|
if (versionToCheck !== this.version) {
|
||||||
|
const apiVersionMismatchError = new APIVersionMismatchError(this.version, versionToCheck);
|
||||||
|
throw new APICallerError(apiVersionMismatchError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#resolveReturnModel(returnDataModel) {
|
||||||
|
let returnModel = { ...ReturnModelShell };
|
||||||
|
returnModel.data = returnDataModel;
|
||||||
|
returnModel = PROTO.Object(returnModel);
|
||||||
|
return returnModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bundleReturnPacket(errorPacket, returnValue = void 0) {
|
||||||
|
return {
|
||||||
|
apiVersion: this.version,
|
||||||
|
data: returnValue,
|
||||||
|
error: errorPacket
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#resolveErrorPacket(error) {
|
||||||
|
return {
|
||||||
|
code: error.errorCode,
|
||||||
|
name: error.thrownError.name,
|
||||||
|
message: error.thrownError.message
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
export class APIController {
|
||||||
|
#endpoints;
|
||||||
|
|
||||||
|
constructor(endpoints) {
|
||||||
|
if (this.constructor === APIController)
|
||||||
|
throw new Error("Cannot instantiate abstract class 'APIController'");
|
||||||
|
this.#endpoints = endpoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
get endpoints() {
|
||||||
|
return this.#endpoints;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { PROTO } from "./MCBE-IPC/ipc";
|
||||||
|
|
||||||
|
export const VoidModel = PROTO.Void;
|
||||||
|
|
||||||
|
export const ErrorModel = PROTO.Optional(PROTO.Object({
|
||||||
|
code: PROTO.Int8,
|
||||||
|
name: PROTO.Optional(PROTO.String),
|
||||||
|
message: PROTO.Optional(PROTO.String)
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const ReturnModelShell = {
|
||||||
|
apiVersion: PROTO.String,
|
||||||
|
data: void 0,
|
||||||
|
error: ErrorModel
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CallModelShell = {
|
||||||
|
apiVersion: PROTO.String,
|
||||||
|
parameterMap: void 0
|
||||||
|
};
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import { AddonAPI } from "./API";
|
||||||
|
import { APIController } from "./APIController";
|
||||||
|
import { VoidModel } from "./APIModels";
|
||||||
|
import { APICallerError } from "./Errors/APICallerError";
|
||||||
|
import { PROTO } from "./MCBE-IPC/ipc";
|
||||||
|
|
||||||
|
export { AddonAPI, APIController, VoidModel, APICallerError, PROTO };
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { APIErrorEnum } from "./APIErrorEnum";
|
||||||
|
|
||||||
|
export class APICallerError extends Error {
|
||||||
|
constructor(error) {
|
||||||
|
super(error.message);
|
||||||
|
this.errorName = error.name;
|
||||||
|
this.errorMessage = error.message;
|
||||||
|
this.errorCode = APIErrorEnum.Caller;
|
||||||
|
this.name = "APICallerError";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export const APIErrorEnum = Object.freeze({
|
||||||
|
Unknown: 0,
|
||||||
|
Success: 1,
|
||||||
|
Caller: 2,
|
||||||
|
Server: 3
|
||||||
|
});
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { APIErrorEnum } from "./APIErrorEnum";
|
||||||
|
|
||||||
|
export class APIServerError extends Error {
|
||||||
|
constructor(error) {
|
||||||
|
super(error.message);
|
||||||
|
this.thrownError = error;
|
||||||
|
this.errorCode = APIErrorEnum.Server;
|
||||||
|
this.name = "APIServerError";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export class APIVersionMismatchError extends Error {
|
||||||
|
constructor(serverApiVersion, callerApiVersion) {
|
||||||
|
super(`API version numbers do not match (${callerApiVersion} != ${serverApiVersion}). Please use API version ${serverApiVersion}.`);
|
||||||
|
this.name = 'APIVersionMismatchError';
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
@@ -28,6 +28,8 @@ import './commands/StatsCommand';
|
|||||||
import './commands/MaterialsCommand';
|
import './commands/MaterialsCommand';
|
||||||
import './commands/TagCommand';
|
import './commands/TagCommand';
|
||||||
|
|
||||||
|
// API
|
||||||
|
import './API/ConstructAPI';
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
import './classes/BlockInfo';
|
import './classes/BlockInfo';
|
||||||
import './classes/Extensions/Ready'
|
|
||||||
Reference in New Issue
Block a user