);
diff --git a/app/silphius/ecs/components/label.js b/app/silphius/ecs/components/label.js
new file mode 100644
index 0000000..38b3d41
--- /dev/null
+++ b/app/silphius/ecs/components/label.js
@@ -0,0 +1,7 @@
+import Component from '@/silphius/ecs/component.js';
+
+export default class Label extends Component {
+ static properties = {
+ label: {type: 'string'},
+ };
+}
diff --git a/app/silphius/net/client.js b/app/silphius/net/client.js
index facebec..fd76cbc 100644
--- a/app/silphius/net/client.js
+++ b/app/silphius/net/client.js
@@ -1,5 +1,6 @@
import {CLIENT_LATENCY, CLIENT_INTERPOLATION, CLIENT_PREDICTION} from '@/lib/constants.js';
import EventEmitter from '@/lib/event-emitter.js';
+import {withResolvers} from '@/lib/promise.js';
import {decode, encode} from '@/silphius/net/packets/index.js';
import {Flow} from './constants.js';
@@ -97,6 +98,25 @@ export default class Client {
removePacketListener(type, listener) {
this.emitter.removeListener(type, listener);
}
+ async request(packet) {
+ // needs crypto strength
+ const id = Math.random();
+ const request = {
+ type: 'Request',
+ payload: {id, request: packet},
+ }
+ this.send(request);
+ const {promise, resolve} = withResolvers();
+ const listenForId = (payload) => {
+ if (id !== payload.id) {
+ return;
+ }
+ this.emitter.removeListener(listenForId);
+ resolve(payload.response);
+ }
+ this.emitter.addListener('Response', listenForId);
+ return promise;
+ }
send(packet) {
const transmitOrPredict = () => {
if (CLIENT_PREDICTION) {
diff --git a/app/silphius/net/packets/admin-action-response.js b/app/silphius/net/packets/admin-action-response.js
new file mode 100644
index 0000000..439abda
--- /dev/null
+++ b/app/silphius/net/packets/admin-action-response.js
@@ -0,0 +1,3 @@
+import Packet from '@/silphius/net/packet.js';
+
+export default class AdminActionResponse extends Packet {}
diff --git a/app/silphius/net/packets/request.js b/app/silphius/net/packets/request.js
new file mode 100644
index 0000000..50ccdf8
--- /dev/null
+++ b/app/silphius/net/packets/request.js
@@ -0,0 +1,3 @@
+import Packet from '@/silphius/net/packet.js';
+
+export default class Request extends Packet {}
diff --git a/app/silphius/net/packets/response.js b/app/silphius/net/packets/response.js
new file mode 100644
index 0000000..94c237e
--- /dev/null
+++ b/app/silphius/net/packets/response.js
@@ -0,0 +1,3 @@
+import Packet from '@/silphius/net/packet.js';
+
+export default class Response extends Packet {}
diff --git a/app/silphius/server/engine.js b/app/silphius/server/engine.js
index 6b107c9..384abec 100644
--- a/app/silphius/server/engine.js
+++ b/app/silphius/server/engine.js
@@ -106,14 +106,21 @@ export default class Engine {
if (!this.incomingActions.has(connection)) {
this.incomingActions.set(connection, []);
}
- this.incomingActions.get(connection).push(payload);
+ this.incomingActions.get(connection).push({payload});
});
this.server.addPacketListener('AdminAction', (connection, payload) => {
// check...
if (!this.incomingActions.has(connection)) {
this.incomingActions.set(connection, []);
}
- this.incomingActions.get(connection).push(payload);
+ this.incomingActions.get(connection).push({payload});
+ });
+ this.server.addPacketListener('Request', (connection, payload) => {
+ if (!this.incomingActions.has(connection)) {
+ this.incomingActions.set(connection, []);
+ }
+ const {request} = payload;
+ this.incomingActions.get(connection).push({payload: request.payload, respondTo: payload.id});
});
this.server.addPacketListener('Heartbeat', (connection) => {
const playerData = this.connectedPlayers.get(connection);
@@ -158,7 +165,7 @@ export default class Engine {
Wielder,
} = entity;
const ecs = this.ecses[Ecs.path];
- for (const payload of payloads) {
+ for (const {payload, respondTo} of payloads) {
switch (payload.type) {
case 'chat': {
if (payload.value.startsWith('/')) {
@@ -197,7 +204,20 @@ export default class Engine {
}
case 'createEntity': {
const {path} = payload.value;
- ecs.create({$$extends: path});
+ const id = ecs.create({$$extends: path});
+ if (respondTo) {
+ this.server.send(
+ connection,
+ {
+ type: 'Response',
+ payload: {
+ id: respondTo,
+ response: {type: 'AdminActionResponse', payload: {id}},
+ },
+ },
+ );
+ }
+
break;
}
case 'destroyEntity': {
diff --git a/resources/ambient/shrub.entity.json b/resources/ambient/shrub.entity.json
index 835350b..d59e4ab 100644
--- a/resources/ambient/shrub.entity.json
+++ b/resources/ambient/shrub.entity.json
@@ -1,4 +1,5 @@
{
+ "Label": {"label": "Shrub"},
"Position": {},
"Sprite": {
"anchorY": 0.7,