Skip to content

Commit abce184

Browse files
Merge pull request #3 from Con-JS-Development/development
Release Beta 1.0.0
2 parents a49f831 + 3f1b0a0 commit abce184

File tree

9 files changed

+220
-55
lines changed

9 files changed

+220
-55
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
scriptevent con:terminal_disable
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
scriptevent con:terminal_enable

behavior_pack/manifest.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
"format_version": 2,
33
"header": {
44
"name": "Con JS Terminal",
5-
"description": "Terminal with JS input by ConMaster2112",
5+
"description": "Terminal with JS prompts by ConMaster2112",
66
"uuid": "4997eb94-8968-4158-864b-74f1999192f7",
7-
"version": "0.1.1-alpha",
8-
"min_engine_version": [1, 20, 0]
7+
"version": "1.0.0-beta",
8+
"min_engine_version": [1, 20, 10]
99
},
1010
"modules": [
1111
{
@@ -16,7 +16,7 @@
1616
}
1717
],
1818
"dependencies": [
19-
{"module_name": "@minecraft/server","version": "1.3.0-beta"},
19+
{"module_name": "@minecraft/server","version": "1.4.0-beta"},
2020
{"module_name": "@minecraft/server-ui","version": "1.1.0-beta"},
2121
{"module_name": "@minecraft/server-gametest","version": "1.0.0-beta"}
2222
],
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export declare enum OutputType {
2+
SyntaxError = 0,
3+
Error = 1,
4+
Successfull = 2
5+
}
6+
export declare enum LogTypes {
7+
log = 0,
8+
error = 1,
9+
warn = 2
10+
}
11+
export declare function TerminalInput<s>(source: s, message: string, scope?: never[], o?: (this: s, type: LogTypes, ...params: any[]) => void): Promise<{
12+
type: OutputType;
13+
value: any;
14+
formatView: string;
15+
multicommand: boolean;
16+
startTime: number;
17+
}>;

behavior_pack/scripts/con-terminal.js

+121-21
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { system} from "@minecraft/server";
1+
import { system } from "@minecraft/server";
2+
const symbolError = Symbol("RunError");
23
const AsyncFunctionConstructor = (async function () { }).constructor;
34
const GeneratorFunctionConstructor = (function* () { }).constructor;
45
const AsyncGeneratorFunctionConstructor = (async function* () { }).constructor;
@@ -25,13 +26,13 @@ const MinecraftModules = [
2526
{ module_name: "@minecraft/server-editor", tag: "editor" },
2627
{ module_name: "@minecraft/server-editor-bindings", tag: "bindings" }
2728
];
28-
var OutputType;
29+
export var OutputType;
2930
(function (OutputType) {
3031
OutputType[OutputType["SyntaxError"] = 0] = "SyntaxError";
3132
OutputType[OutputType["Error"] = 1] = "Error";
3233
OutputType[OutputType["Successfull"] = 2] = "Successfull";
3334
})(OutputType || (OutputType = {}));
34-
var LogTypes;
35+
export var LogTypes;
3536
(function (LogTypes) {
3637
LogTypes[LogTypes["log"] = 0] = "log";
3738
LogTypes[LogTypes["error"] = 1] = "error";
@@ -45,19 +46,15 @@ function consoleLike(type, ...texts) {
4546
function formatView(type, object) {
4647
return getView[typeof object](ViewStyle.Full, object);
4748
}
48-
export async function TerminalInput(source, message, o = consoleLike) {
49-
const a = await RunCode(message, true, { console: { log: o.bind(source, LogTypes.log), warn: o.bind(source, LogTypes.warn), error: o.bind(source, LogTypes.error) }, print: o.bind(source, LogTypes.log), self: source, setTimeout, setInterval, clearInterval: clearRun, clearTimeout: clearRun });
50-
const multicommand = a.multicommand;
49+
export async function TerminalInput(source, message, scope = [], o = consoleLike) {
50+
const a = await RunCode(message, true, { console: { log: o.bind(source, LogTypes.log), Map, Set, warn: o.bind(source, LogTypes.warn), error: o.bind(source, LogTypes.error) }, print: o.bind(source, LogTypes.log), self: source, setTimeout, setInterval, clearInterval: clearRun, clearTimeout: clearRun }, ...scope);
51+
const { multicommand, startTime } = a;
5152
if (a.syntaxError)
52-
return { type: OutputType.SyntaxError, value: a.syntaxError, formatView: formatView(OutputType.SyntaxError, a.syntaxError), multicommand };
53-
try {
54-
const output = await a.promise;
55-
return { type: OutputType.Successfull, value: output, formatView: formatView(OutputType.Successfull, output), multicommand };
56-
}
57-
catch (error) {
58-
console.warn("It was handled xd, but after the promise returns");
59-
return { type: OutputType.Error, value: error, formatView: formatView(OutputType.Error, error), multicommand };
60-
}
53+
return { type: OutputType.SyntaxError, value: a.syntaxError, formatView: formatView(OutputType.SyntaxError, a.syntaxError), multicommand, startTime };
54+
const output = await a.promise;
55+
if (typeof output === "object" && output !== null && symbolError in output)
56+
return { type: OutputType.Error, value: output[symbolError], formatView: formatView(OutputType.Error, output[symbolError]), multicommand, startTime };
57+
return { type: OutputType.Successfull, value: output, formatView: formatView(OutputType.Successfull, output), multicommand, startTime };
6158
}
6259
async function RunCode(code, useModules = true, ...scopes) {
6360
let func, output = { syntaxError: undefined, promise: undefined, multicommand: false };
@@ -71,12 +68,13 @@ async function RunCode(code, useModules = true, ...scopes) {
7168
return output;
7269
}
7370
output.multicommand = func.multicommand ?? false;
74-
output.promise = func();
71+
output.startTime = Date.now();
72+
output.promise = Promise.resolve(func()).catch(er => ({ [symbolError]: er }));
7573
return output;
7674
}
7775
async function BuildAPIScope(...modules) {
7876
let promises = [];
79-
modules.forEach(m => promises.push(import(m.module_name).catch(() => ({}))));
77+
modules.forEach(m => promises.push(import(m.module_name).catch(() => null)));
8078
const dlls = await Promise.all(promises);
8179
return dlls.map((m, i) => ({ [modules[i].tag]: m }));
8280
}
@@ -115,7 +113,22 @@ const getView = {
115113
else if (style === ViewStyle.Short) {
116114
const names = Object.getOwnPropertyNames(any), symbols = Object.getOwnPropertySymbols(any);
117115
//@ts-ignore
118-
const keys = names.map(k => `§7${k}§r§7: ${getView[typeof any[k]](ViewStyle.Primitive, any[k])}§r`).concat(symbols.map(s => `§r${getView["symbol"](ViewStyle.Primitive, s)}§r§7: ${getView[typeof any[s]](ViewStyle.Primitive, any[s])}`));
116+
const keys = names.map(k => {
117+
try {
118+
return `§7${k}§r§7: ${getView[typeof any[k]](ViewStyle.Primitive, any[k])}§r`;
119+
}
120+
catch (error) {
121+
return `§7${k}§r§7: §o(...)§r`;
122+
}
123+
}).concat(symbols.map(s => {
124+
try {
125+
return `§r${getView["symbol"](ViewStyle.Primitive, s)}§r§7: ${getView[typeof any[s]](ViewStyle.Primitive, any[s])}`;
126+
}
127+
catch (error) {
128+
return `§r${getView["symbol"](ViewStyle.Primitive, s)}§r§7: §o(...)§r`;
129+
}
130+
}));
131+
Object.getOwnPropertyDescriptor;
119132
const realKeys = keys.slice(0, 5), typeOf = getTypeOfObject(any);
120133
return `§7${(typeOf == "Object" || typeOf == '') ? "" : typeOf + " "}{${realKeys.join("§7, ")}${keys.length > 5 ? "§r§7, ..." : "§r§7"}}`;
121134
}
@@ -165,11 +178,17 @@ function buildCompoudView(array, base, object, offSet = " ", func = false, deep
165178
}
166179
else {
167180
if (get != undefined) {
168-
const v = get.call(base);
169-
array.push(`${off}§r§7get§r ${typeof key == "string" ? key : getView["symbol"](ViewStyle.Primitive, key)}§7: §r${getView[typeof v](ViewStyle.Short, v)}§r`);
181+
let v;
182+
try {
183+
v = get.call(base);
184+
array.push(`${off}§r§7get§r ${typeof key == "string" ? key : getView["symbol"](ViewStyle.Primitive, key)}§7: §r${getView[typeof v](ViewStyle.Short, v)}§r`);
185+
}
186+
catch (error) {
187+
array.push(`${off}§r§7get§r ${typeof key == "string" ? key : getView["symbol"](ViewStyle.Primitive, key)}§7: §o(...)§r`);
188+
}
170189
}
171190
if (set != undefined)
172-
array.push(`${off}§r§7set§r ${typeof key == "string" ? key : getView["symbol"](ViewStyle.Primitive, key)}§7: (...)§r`);
191+
array.push(`${off}§r§7set§r ${typeof key == "string" ? key : getView["symbol"](ViewStyle.Primitive, key)}§7: §o(...)§r`);
173192
}
174193
}
175194
if (func)
@@ -182,6 +201,87 @@ function buildCompoudView(array, base, object, offSet = " ", func = false, deep
182201
buildCompoudView(array, base, prototype, offSet, typeof prototype === 'function', deepth + 1);
183202
return array;
184203
}
204+
/*
205+
export function toStringPrimitiveFull(any){
206+
switch (typeof any) {
207+
case 'object':
208+
if(any === null){
209+
return "§7§onull";
210+
}else if (any instanceof Error) {
211+
return `§6${any}\n${any.stack}`;
212+
}else{
213+
const base = any, names = Object.getOwnPropertyNames(base), symbols = Object.getOwnPropertySymbols(base);
214+
const keys = names.filter(a=>(base.__lookupGetter__?.(a) == undefined && base.__lookupSetter__?.(a) == undefined)).map(k=>`§7${k}§r§7: ${toStringPrimitiveShort(base[k])}§r`).concat(symbols.map(s=>`§r${toStringPrimitiveShort(s)}§r§7: ${toStringPrimitiveShort(base[s])}`));
215+
const realKeys = keys.slice(0,5), typeOf = getTypeOfObject(base);
216+
let output = `§7${(typeOf == "Object" || typeOf == '')?"":typeOf + " "}{${realKeys.join("§7, ")}${keys.length>5?"§r§7, ...":"§r§7"}}§r`;
217+
function buildLines(base, offSet = " "){
218+
const prototype = Object.getPrototypeOf(base);
219+
for (const keyName of Object.getOwnPropertyNames(base)) {
220+
let getter = base.__lookupGetter__?.(keyName);
221+
let setter = base.__lookupSetter__?.(keyName);
222+
if(getter == undefined&&setter == undefined){
223+
output += `\n${offSet}§r${keyName}§7: §r${toStringPrimitive(base[keyName])}`;
224+
} else {
225+
if(getter != undefined) output += `\n${offSet}§7get§r ${keyName}§7: (...)`;
226+
if(setter != undefined) output += `\n${offSet}§7set§r ${keyName}§7: (...)`;
227+
}
228+
}
229+
for (const keySymbol of Object.getOwnPropertySymbols(base)){
230+
let getter = base.__lookupGetter__?.(keySymbol);
231+
let setter = base.__lookupSetter__?.(keySymbol);
232+
if(getter == undefined&&setter == undefined){
233+
output += `\n${offSet}§r${toStringPrimitiveShort(keySymbol)}§7: §r${toStringPrimitive(base[keySymbol])}`;
234+
} else {
235+
if(getter != undefined) output += `\n${offSet}§7get§r ${toStringPrimitiveShort(keySymbol)}§7: (...)`;
236+
if(setter != undefined) output += `\n${offSet}§7set§r ${toStringPrimitiveShort(keySymbol)}§7: (...)`;
237+
}
238+
}
239+
if(prototype != null){
240+
const typOf = getTypeOfObject(prototype);
241+
output += `\n${offSet}§r[[Prototype]]§r§7: ` + (typOf==""?"Object":typOf)
242+
if(prototype != Object.prototype && prototype != Array.prototype && prototype != Map.prototype){
243+
buildLines(prototype, offSet + " ");
244+
}
245+
}
246+
}
247+
buildLines(base);
248+
return output;
249+
}
250+
case 'function': return any.toString();
251+
case 'symbol': return `§7Symbol(${any.description})`;
252+
case 'bigint':
253+
case 'number':
254+
case 'boolean': return `§3${any.toString()}§r`;
255+
case 'undefined': return "§7§oundefined";
256+
case 'string': return `§3"${any}"§r`;
257+
default:
258+
break;
259+
}
260+
}
261+
export function toStringPrimitive(any: any){
262+
switch (typeof any) {
263+
case 'object':
264+
if(any === null){
265+
return "§7§onull§r";
266+
}else if (any instanceof Error) {
267+
return `§6${any}§r`;
268+
}else{
269+
const base = any, names = Object.getOwnPropertyNames(base), symbols = Object.getOwnPropertySymbols(base);
270+
const keys = names.map(k=>`§7${k}§r§7: ${toStringPrimitiveShort(base[k])}§r`).concat(symbols.map(s=>`§r${toStringPrimitiveShort(s)}§r§7: ${toStringPrimitiveShort(base[s])}`));
271+
const realKeys = keys.slice(0,5), typeOf = getTypeOfObject(base);
272+
return `§7${(typeOf == "Object" || typeOf == '')?"":typeOf + " "}{${realKeys.join("§7, ")}${keys.length>5?"§r§7, ...":"§r§7"}}`;
273+
}
274+
case 'function': return toFunctionString(any);
275+
case 'symbol': return `Symbol(${any.description})`;
276+
case 'bigint':
277+
case 'number':
278+
case 'boolean': return `§3${any.toString()}§r`;
279+
case 'undefined': return "§7§oundefined";
280+
case 'string': return `§6"${any}"§r`;
281+
default:
282+
break;
283+
}
284+
}*/
185285
function getTypeOfObject(obj) { return (obj[Symbol.toStringTag] ?? ((typeof obj === "function" ? obj.name : undefined) ?? ((obj.constructor?.prototype == obj ? obj.constructor?.name : obj.__proto__?.constructor?.name) ?? ""))); }
186286
//@ts-ignore
187287
globalThis[Symbol.toStringTag] = 'GlobalThis';

behavior_pack/scripts/index.js

+36-8
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,40 @@
1-
import { world } from "@minecraft/server";
2-
import { TerminalInput } from "./con-terminal";
1+
import { DynamicPropertiesDefinition, MessageSourceType, MinecraftEntityTypes, system, world } from "@minecraft/server";
2+
import { OutputType, TerminalInput } from "./con-terminal";
3+
4+
const propertyName = "allow_terminal";
35

46
world.beforeEvents.chatSend.subscribe(async (ev) => {
5-
const { sender, message } = ev;
6-
if (message.startsWith('>') && sender.isOp()) {
7+
const { sender, message } = ev, reg = message.match(/^( +|)>( +|)/g);
8+
if (reg !== null && sender.isOp() && sender.getDynamicProperty(propertyName)) {
79
ev.cancel = true;
8-
await null;
9-
const out = await TerminalInput(sender, message.substring(1));
10-
sender.sendMessage(out.formatView);
10+
const code = message.substring(reg[0].length);
11+
const task = TerminalInput(sender, code,[{system,world,beforeEvents:world.beforeEvents,afterEvents:world.afterEvents,systemEvents:system.events}]).catch(er=>console.error(er,er.stack));
12+
sender.sendMessage(" §l§h> §r§7" + code);
13+
const out = await task;
14+
switch (out.type) {
15+
case OutputType.Successfull:
16+
case 2:
17+
return sender.sendMessage(" §l§q< §r" + out.formatView.replaceAll("\n", "\n "));
18+
case OutputType.SyntaxError:
19+
case 0:
20+
return sender.sendMessage(" §l§4> §6" + out.value.message);
21+
case OutputType.Error:
22+
case 1:
23+
return sender.sendMessage(" §l§6< §7" + out.value);
24+
default:
25+
break;
26+
}
27+
}
28+
});
29+
world.afterEvents.worldInitialize.subscribe(ev=>ev.propertyRegistry.registerEntityTypeDynamicProperties(new DynamicPropertiesDefinition().defineBoolean(propertyName,false),MinecraftEntityTypes.player))
30+
system.events.scriptEventReceive.subscribe(ev=>{
31+
if(ev.sourceType !== MessageSourceType.clientScript || ev.sourceEntity == null) return;
32+
if(ev.id === "con:terminal_enable") {
33+
ev.sourceEntity.setDynamicProperty(propertyName, true);
34+
ev.sourceEntity.sendMessage("You are now able to use terminal.");
35+
}
36+
if(ev.id === "con:terminal_disable") {
37+
ev.sourceEntity.setDynamicProperty(propertyName, false);
38+
ev.sourceEntity.sendMessage("You are no longer able to use terminal.");
1139
}
12-
});
40+
},{namespaces:["con"]});

0 commit comments

Comments
 (0)