update 1.2

add new block: CCSystem and CCTextutils
Fixed some bug
This commit is contained in:
dharm pimsen 2024-07-28 23:50:52 +07:00
parent 218bb18b29
commit 5a4cbb455a
26 changed files with 3470 additions and 178 deletions

View File

@ -0,0 +1 @@
{"usedlibrary":["CCTextutils"],"content":{"blocks":{"languageVersion":0,"blocks":[{"type":"ide_start","id":"%k|1C%^t;XMrXr0{%gB|","x":330,"y":270,"inputs":{"DO":{"block":{"type":"variables_set","id":"NSMcwqhVU(1::#UWOflD","fields":{"VAR":{"id":"6z)4i^N`L0rGnHo}k6w~"}},"inputs":{"VALUE":{"block":{"type":"lists_create_with","id":"Rt}My_DC8m7QIYsmta-T","extraState":{"itemCount":3},"inputs":{"ADD0":{"block":{"type":"math_number","id":"7SKw2+Md2.{tznxyfe{T","fields":{"NUM":1}}},"ADD1":{"block":{"type":"math_number","id":"7UV1y^XFKM!,-6RK);`{","fields":{"NUM":2}}},"ADD2":{"block":{"type":"math_number","id":"MrfY2v6g)h3lj7e0jgqE","fields":{"NUM":3}}}}}}},"next":{"block":{"type":"text_print","id":"3+Z|78w,QkD{/[:jPv:e","inputs":{"TEXT":{"shadow":{"type":"text","id":"+OF[F($(eq]G$:h;Kt*w","fields":{"TEXT":"abc"}},"block":{"type":"textutils_serialize","id":"d{!#Az)#[M2rmGXXW,J,","fields":{"COMPACT":false,"ALLOWREPETI":true},"inputs":{"OBJECT":{"block":{"type":"lists_create_with","id":"W~HzfCNp_n@LA6c6fwp~","extraState":{"itemCount":2},"inputs":{"ADD0":{"block":{"type":"variables_get","id":"bVs`6KM30qehpXe901*:","fields":{"VAR":{"id":"6z)4i^N`L0rGnHo}k6w~"}}}},"ADD1":{"block":{"type":"variables_get","id":"@l4-(?lC]/$VetN_E!|^","fields":{"VAR":{"id":"6z)4i^N`L0rGnHo}k6w~"}}}}}}}}}}},"next":{"block":{"type":"text_print","id":"I^mHjxNqwwaU!Or,/m5@","inputs":{"TEXT":{"shadow":{"type":"text","id":"/!sl#s%!LHS,s5h05pQ;","fields":{"TEXT":"abc"}},"block":{"type":"textutils_serialize","id":"t7R?`7;1c%3!.jd.dW9F","fields":{"COMPACT":true,"ALLOWREPETI":false},"inputs":{"OBJECT":{"block":{"type":"variables_get","id":"!yZhT^MMVuSQ:[q|puo`","fields":{"VAR":{"id":"6z)4i^N`L0rGnHo}k6w~"}}}}}}}}}}}}}}}}]},"variables":[{"name":"test","id":"6z)4i^N`L0rGnHo}k6w~"}]}}

View File

@ -0,0 +1 @@
{"usedlibrary":["CCSystem","CCTextutils"],"content":{"blocks":{"languageVersion":0,"blocks":[{"type":"ide_start","id":"?udZVah+}|wlY2LCZ-bl","x":110,"y":150,"inputs":{"DO":{"block":{"type":"variables_set","id":"Q1no.e|r^Ds4Z(cOo6ks","fields":{"VAR":{"id":"|]HEFfXY)7GgpQb83nOc"}},"inputs":{"VALUE":{"block":{"type":"lists_create_with","id":"Qzp}4**d+m``G!B7ydBd","extraState":{"itemCount":0}}}},"next":{"block":{"type":"controls_repeat_ext","id":"h[fG-)EnPfn?;Dw,4JS;","inputs":{"TIMES":{"shadow":{"type":"math_number","id":"0,DMR{6Yro.qGGmsNI!m","fields":{"NUM":10}}},"DO":{"block":{"type":"sys_table_append_data","id":"_{Wr/]apCKw;wuLM!~tb","inputs":{"DATA":{"block":{"type":"math_random_int","id":"/dj{qRb:`dKxV-I6fB:c","inputs":{"FROM":{"shadow":{"type":"math_number","id":"6_%M8#LXu7~[op|p6@i+","fields":{"NUM":1}}},"TO":{"shadow":{"type":"math_number","id":"%dJUjQmbir}H?ZXa!Ghv","fields":{"NUM":10}}}}}},"TABLE":{"block":{"type":"variables_get","id":",7[Gq|+k;K=kAnpK0.dR","fields":{"VAR":{"id":"|]HEFfXY)7GgpQb83nOc"}}}}}}}},"next":{"block":{"type":"text_print","id":"bHx3OISYn{5x.-F2(|Y`","inputs":{"TEXT":{"shadow":{"type":"text","id":"jVr603(C3eOIz#G*N}UC","fields":{"TEXT":"abc"}},"block":{"type":"textutils_serialize","id":"}`]U9*1|Ev{J=[`ru9Q;","fields":{"COMPACT":false,"ALLOWREPETI":false},"inputs":{"OBJECT":{"block":{"type":"lists_sort","id":"EZpHsG`jZ.gBI;D?$b~L","fields":{"TYPE":"NUMERIC","DIRECTION":"1"},"inputs":{"LIST":{"block":{"type":"variables_get","id":"$Uf4s5MK,FWh^4jvKmFo","fields":{"VAR":{"id":"|]HEFfXY)7GgpQb83nOc"}}}}}}}}}}}}}}}}}}}]},"variables":[{"name":"mylist","id":"|]HEFfXY)7GgpQb83nOc"}]}}

View File

@ -2,8 +2,22 @@ local ws = assert(http.websocket("ws://127.0.0.1:5133"))
print("connected to server")
local id
local isrunning = true
while true do
function exitcheck()
while true do
local event = os.pullEventRaw("terminate")
if event == "terminate" then
print("Exiting...")
isrunning = false
ws.close()
break
end
end
end
function main()
while isrunning do
print("ready")
local message, error = ws.receive()
if message then
@ -29,6 +43,8 @@ while true do
print("WebSocket error:", error)
break
end
end
end
ws.close()
parallel.waitForAny(exitcheck, main)
print("Exited")

View File

@ -0,0 +1,249 @@
{
"sysos_pullevent": {
"message0": "Pull %1 event",
"args0": [
{
"type": "input_value",
"name": "EVENT",
"check": "String"
}
],
"output": "Multiple",
"colour": 0,
"tooltip": "Pause execution of the current thread and waits for any events matching filter.",
"helpUrl": "https://tweaked.cc/module/os.html#v:pullEvent"
},
"sysos_pullrawevent": {
"message0": "Pull raw %1 event",
"args0": [
{
"type": "input_value",
"name": "EVENT",
"check": "String"
}
],
"output": "Multiple",
"colour": 0,
"tooltip": "Pause execution of the current thread and waits for events, including the terminate event.",
"helpUrl": "https://tweaked.cc/module/os.html#v:pullEventRaw"
},
"sysos_version": {
"message0": "Get system version",
"output": "String",
"colour": 0,
"tooltip": "Get the current CraftOS version (for example, CraftOS 1.9)."
},
"sysos_run": {
"message0": "Run %1\nEnvironment %2\nArgs %3",
"args0": [
{
"type": "input_value",
"name": "RUN",
"check": "String"
},
{
"type": "input_value",
"name": "ENV",
"check": "Array"
},
{
"type": "input_value",
"name": "ARGS",
"check": "Multiple"
}
],
"previousStatement": null,
"nextStatement": null,
"colour": 0,
"tooltip": "Run the program at the given path with the specified environment and arguments.",
"helpUrl": "https://tweaked.cc/module/os.html#v:run"
},
"sysos_queue_event": {
"message0": "Add event %1 to queue with args %2",
"args0": [
{
"type": "input_value",
"name": "EVENT",
"check": "String"
},
{
"type": "input_value",
"name": "ARGS",
"check": "Multiple"
}
],
"previousStatement": null,
"nextStatement": null,
"colour": 0,
"tooltip": "Adds an event to the event queue. This event can later be pulled with os.pullEvent."
},
"sysos_start_timer": {
"message0": "Start timer at %1",
"args0": [
{
"type": "input_value",
"name": "TIME",
"check": "Number"
}
],
"output": "Number",
"colour": 0,
"tooltip": "Starts a timer that will run for the specified number of seconds. Once the timer fires, a timer event will be added to the queue with the ID returned from this function as the first parameter.",
"helpUrl": "https://tweaked.cc/module/os.html#v:startTimer"
},
"sysos_cancel_timer": {
"message0": "Stop timer id %1",
"args0": [
{
"type": "input_value",
"name": "ID",
"check": "Number"
}
],
"previousStatement": null,
"nextStatement": null,
"colour": 0,
"tooltip": "Cancels a timer previously started with startTimer. This will stop the timer from firing."
},
"sysos_set_alarm": {
"message0": "Set alarm to %1",
"args0": [
{
"type": "input_value",
"name": "TIME",
"check": "Number"
}
],
"output": "Number",
"colour": 0,
"tooltip": "Sets an alarm that will fire at the specified in-game time."
},
"sysos_cancel_alarm": {
"message0": "Stop alarm id %1",
"args0": [
{
"type": "input_value",
"name": "ID",
"check": "Number"
}
],
"previousStatement": null,
"nextStatement": null,
"colour": 0,
"tooltip": "Cancels an alarm previously started with setAlarm."
},
"sysos_shutdown": {
"message0": "Shutdown computer",
"previousStatement": null,
"colour": 0,
"tooltip": "Shuts down the computer immediately."
},
"sysos_reboot": {
"message0": "Restart computer",
"previousStatement": null,
"colour": 0,
"tooltip": "Reboots the computer immediately."
},
"sysos_get_computer_id": {
"message0": "Get computer id",
"output": "Number",
"colour": 0,
"tooltip": "Returns the ID of the computer."
},
"sysos_get_computer_label": {
"message0": "Get computer label",
"output": "String",
"colour": 0,
"tooltip": "Returns the label of the computer, or nil if none is set."
},
"sysos_set_computer_label": {
"message0": "Set computer label to %1",
"args0": [
{
"type": "input_value",
"name": "LABEL",
"check": "String"
}
],
"previousStatement": null,
"nextStatement": null,
"colour": 0,
"tooltip": "Set the label of this computer."
},
"sysos_clock": {
"message0": "Get Uptime",
"output": "String",
"colour": 0,
"tooltip": "Returns the number of seconds that the computer has been running."
},
"sysos_time": {
"message0": "Get time of %1",
"args0": [
{
"type": "field_dropdown",
"name": "LOCATE",
"options": [
["In Game World", "ingame"],
["UTC", "utc"],
["Local", "local"]
]
}
],
"output": null,
"colour": 0,
"tooltip": "Returns the current time depending on the string passed in. This will always be in the range [0.0, 24.0)."
},
"sysos_day": {
"message0": "Get day of %1",
"args0": [
{
"type": "field_dropdown",
"name": "LOCATE",
"options": [
["In Game World", "ingame"],
["UTC", "utc"],
["Local", "local"]
]
}
],
"output": null,
"colour": 0,
"tooltip": "Returns the day depending on the locale specified."
},
"sysos_epoch": {
"message0": "Get epoch of %1",
"args0": [
{
"type": "field_dropdown",
"name": "LOCATE",
"options": [
["In Game World", "ingame"],
["UTC", "utc"],
["Local", "local"]
]
}
],
"output": null,
"colour": 0,
"tooltip": "Returns the number of milliseconds since an epoch depending on the locale."
},
"sysos_date": {
"message0": "Format date with patten %1 from time %2",
"args0": [
{
"type": "input_value",
"name": "FORMAT",
"check": "String"
},
{
"type": "input_value",
"name": "TIME",
"check": "Number"
}
],
"output": null,
"colour": 0,
"tooltip": "Returns a date string (or table) using a specified format string and optional time to format.",
"helpUrl": "https://cplusplus.com/reference/ctime/strftime/"
}
}

View File

@ -0,0 +1,130 @@
// this file not for generator only
const { luaGenerator } = require('blockly/lua');
// Check if luaGenerator.forBlock is defined and initialize if necessary
if (!luaGenerator.forBlock) {
luaGenerator.forBlock = {};
}
luaGenerator.forBlock['sysos_pullevent'] = function(block, generator) {
var event = generator.valueToCode(block, 'EVENT', generator.ORDER_ATOMIC);
if (event == "") {
return [`os.pullevent()`, luaGenerator.ORDER_NONE];
} else {
return [`os.pullevent(${event})`, luaGenerator.ORDER_NONE];
}
};
luaGenerator.forBlock['sysos_pullrawevent'] = function(block, generator) {
var event = generator.valueToCode(block, 'EVENT', generator.ORDER_ATOMIC);
if (event == "") {
return [`os.pullEventRaw()`, luaGenerator.ORDER_NONE];
} else {
return [`os.pullEventRaw(${event})`, luaGenerator.ORDER_NONE];
}
};
luaGenerator.forBlock['sysos_version'] = function(block, generator) {
return [`os.version()`, luaGenerator.ORDER_NONE];
};
luaGenerator.forBlock['sysos_run'] = function(block, generator) {
var env = generator.valueToCode(block, 'ENV', generator.ORDER_ATOMIC) || "{}";
var run = generator.valueToCode(block, 'RUN', generator.ORDER_ATOMIC);
var args = generator.valueToCode(block, 'ARGS', generator.ORDER_ATOMIC);
if (args == "") {
return `os.run(${env}, ${run})\n`;
} else {
return `os.run(${env}, ${run}, ${args})\n`;
}
};
luaGenerator.forBlock['sysos_queue_event'] = function(block, generator) {
var event = generator.valueToCode(block, 'EVENT', generator.ORDER_ATOMIC);
var args = generator.valueToCode(block, 'ARGS', generator.ORDER_ATOMIC);
if (args == "") {
return `os.queueEvent(${event})\n`;
} else {
return `os.queueEvent(${event}, ${args})\n`;
}
};
luaGenerator.forBlock['sysos_start_timer'] = function(block, generator) {
var time = generator.valueToCode(block, 'TIME', generator.ORDER_ATOMIC);
return [`os.queueEvent(${time})`, luaGenerator.ORDER_NONE];
};
luaGenerator.forBlock['sysos_cancel_timer'] = function(block, generator) {
var id = generator.valueToCode(block, 'ID', generator.ORDER_ATOMIC);
return `os.cancelTimer(${id}\n`;
};
luaGenerator.forBlock['sysos_set_alarm'] = function(block, generator) {
var time = generator.valueToCode(block, 'TIME', generator.ORDER_ATOMIC);
return [`os.setAlarm(${time})`, luaGenerator.ORDER_NONE];
};
luaGenerator.forBlock['sysos_cancel_alarm'] = function(block, generator) {
var id = generator.valueToCode(block, 'ID', generator.ORDER_ATOMIC);
return `os.cancelAlarm(${id})\n`;
};
luaGenerator.forBlock['sysos_shutdown'] = function(block, generator) {
return `os.shutdown()`
};
luaGenerator.forBlock['sysos_reboot'] = function(block, generator) {
return `os.reboot()`
};
luaGenerator.forBlock['sysos_get_computer_id'] = function(block, generator) {
return [`os.getComputerID()`, luaGenerator.ORDER_NONE];
};
luaGenerator.forBlock['sysos_get_computer_label'] = function(block, generator) {
return [`os.getComputerLabel()`, luaGenerator.ORDER_NONE];
};
luaGenerator.forBlock['sysos_set_computer_label'] = function(block, generator) {
var label = generator.valueToCode(block, 'LABEL', generator.ORDER_ATOMIC);
return `os.setComputerLabel(${label})\n`;
};
luaGenerator.forBlock['sysos_clock'] = function(block, generator) {
return [`os.clock()`, luaGenerator.ORDER_NONE];
};
luaGenerator.forBlock['sysos_time'] = function(block, generator) {
var locate = block.getFieldValue('LOCATE');
return [`os.time("${locate}")`, generator.ORDER_ATOMIC];
};
luaGenerator.forBlock['sysos_day'] = function(block, generator) {
var locate = block.getFieldValue('LOCATE');
return [`os.day("${locate}")`, generator.ORDER_ATOMIC];
};
luaGenerator.forBlock['sysos_epoch'] = function(block, generator) {
var locate = block.getFieldValue('LOCATE');
return [`os.epoch("${locate}")`, generator.ORDER_ATOMIC];
};
luaGenerator.forBlock['sysos_date'] = function(block, generator) {
var format = generator.valueToCode(block, 'FORMAT', generator.ORDER_ATOMIC);
var time = generator.valueToCode(block, 'TIME', generator.ORDER_ATOMIC);
return [`os.date(${format}, ${time})`, luaGenerator.ORDER_NONE];
};

View File

@ -0,0 +1,22 @@
{
"name": "CC: System (OS)",
"author": "DPSoftware Foundation",
"description": "The os API allows interacting with the current computer.",
"version": "1.0.0",
"category": "System",
"keyword": "System, OS",
"license": "GPL-3.0-or-later",
"peripherals": false,
"library": true,
"require_network": false,
"dependencies": {},
"design_for_computer": {
"basic": true,
"adv": true,
"command": true,
"pocket": true,
"advpocket": true,
"turtle": true,
"advturtle": true
}
}

View File

@ -0,0 +1,56 @@
<xml id="toolbox" style="display: none;">
<category name="System" colour="0">
<block type="sysos_pullevent">
<value name="EVENT">
<shadow type="text">
<field name="TEXT">All</field>
</shadow>
</value>
</block>
<block type="sysos_pullrawevent">
<value name="EVENT">
<shadow type="text">
<field name="TEXT">All</field>
</shadow>
</value>
</block>
<block type="sysos_version"></block>
<block type="sysos_run"></block>
<block type="sysos_queue_event"></block>
<block type="sysos_start_timer">
<value name="TIME">
<shadow type="math_number">
<field name="NUM">0</field>
</shadow>
</value>
</block>
<block type="sysos_cancel_timer"></block>
<block type="sysos_set_alarm">
<value name="TIME">
<shadow type="math_number">
<field name="NUM">0</field>
</shadow>
</value>
</block>
<block type="sysos_cancel_alarm"></block>
<block type="sysos_shutdown"></block>
<block type="sysos_reboot"></block>
<block type="sysos_get_computer_id"></block>
<block type="sysos_get_computer_label"></block>
<block type="sysos_set_computer_label"></block>
<block type="sysos_clock"></block>
<block type="sysos_time"></block>
<block type="sysos_day"></block>
<block type="sysos_epoch"></block>
<block type="sysos_date">
<value name="FORMAT">
<shadow type="text">
<field name="TEXT">%A %d %B %Y</field>
</shadow>
</value>
<value name="TIME">
<shadow type="sysos_time"></shadow>
</value>
</block>
</category>
</xml>

View File

@ -0,0 +1,237 @@
{
"textutils_slow_write": {
"message0": "Write %1 with rate %2",
"args0": [
{
"type": "input_value",
"name": "TEXT",
"check": "String"
},
{
"type": "input_value",
"name": "RATE",
"check": "Number"
}
],
"previousStatement": null,
"nextStatement": null,
"colour": 32,
"tooltip": "Slowly writes string text at current cursor position, character-by-character."
},
"textutils_slow_print": {
"message0": "Print %1 with rate %2",
"args0": [
{
"type": "input_value",
"name": "TEXT",
"check": "String"
},
{
"type": "input_value",
"name": "RATE",
"check": "Number"
}
],
"previousStatement": null,
"nextStatement": null,
"colour": 32,
"tooltip": "Slowly prints string text at current cursor position, character-by-character."
},
"textutils_format_time": {
"message0": "Format time from %1\n24-Hour %2",
"args0": [
{
"type": "input_value",
"name": "TIME",
"check": "Number"
},
{
"type": "field_checkbox",
"name": "24H"
}
],
"output": "String",
"colour": 32,
"tooltip": "Takes input time and formats it in a more readable format such as 6:30 PM."
},
"textutils_paged_print": {
"message0": "Print %1\nlimit %2 lines",
"args0": [
{
"type": "input_value",
"name": "TEXT",
"check": "String"
},
{
"type": "input_value",
"name": "FREELINES",
"check": "Number"
}
],
"previousStatement": null,
"nextStatement": null,
"colour": 32,
"tooltip": "Prints a given string to the display.",
"helpUrl": "https://tweaked.cc/module/textutils.html#v:pagedPrint"
},
"textutils_tabulate": {
"message0": "Print table %1",
"args0": [
{
"type": "input_value",
"name": "ARGS",
"check": "Multiple"
}
],
"previousStatement": null,
"nextStatement": null,
"colour": 32,
"tooltip": "Prints tables in a structured form.",
"helpUrl": "https://tweaked.cc/module/textutils.html#v:tabulate"
},
"textutils_paged_tabulate": {
"message0": "Print table %1 with paged",
"args0": [
{
"type": "input_value",
"name": "ARGS",
"check": "Multiple"
}
],
"previousStatement": null,
"nextStatement": null,
"colour": 32,
"tooltip": "Prints tables in a structured form, stopping and prompting for input should the result not fit on the terminal."
},
"textutils_empty_json_array": {
"message0": "Empty json array",
"output": "Array",
"colour": 32,
"tooltip": "Prints tables in a structured form, stopping and prompting for input should the result not fit on the terminal."
},
"textutils_json_null": {
"message0": "Json null",
"output": "Array",
"colour": 32,
"tooltip": "A table representing the JSON null value."
},
"textutils_serialize": {
"message0": "Serialize %1\nCompact %2\nAllow repetitions %3",
"args0": [
{
"type": "input_value",
"name": "OBJECT",
"check": "Array"
},
{
"type": "field_checkbox",
"name": "COMPACT"
},
{
"type": "field_checkbox",
"name": "ALLOWREPETI"
}
],
"output": "String",
"colour": 32,
"tooltip": "Prints tables in a structured form, stopping and prompting for input should the result not fit on the terminal.",
"helpUrl": "https://tweaked.cc/module/textutils.html#v:serialize"
},
"textutils_unserialize": {
"message0": "UnSerialize %1",
"args0": [
{
"type": "input_value",
"name": "OBJECT",
"check": "String"
}
],
"output": "Array",
"colour": 32,
"tooltip": "Converts a serialised string back into a reassembled Lua object."
},
"textutils_serialize_json": {
"message0": "Serialize %1 to json\nNBT style %2\nUnicode %3\nAllow repetitions %4",
"args0": [
{
"type": "input_value",
"name": "OBJECT",
"check": "String"
},
{
"type": "field_checkbox",
"name": "NBT"
},
{
"type": "field_checkbox",
"name": "UNICODE"
},
{
"type": "field_checkbox",
"name": "ALLOWREPETI"
}
],
"output": "String",
"colour": 32,
"tooltip": "Returns a JSON representation of the given data.",
"helpUrl": "https://tweaked.cc/module/textutils.html#v:serializeJSON"
},
"textutils_unserialize_json": {
"message0": "UnSerialize %1 to json\nNBT style %2\nParse null %3\nParse empty array %4",
"args0": [
{
"type": "input_value",
"name": "OBJECT",
"check": "String"
},
{
"type": "field_checkbox",
"name": "NBT"
},
{
"type": "field_checkbox",
"name": "PARSENULL"
},
{
"type": "field_checkbox",
"name": "PARSEEA"
}
],
"output": ["Array", "Multiple"],
"colour": 32,
"tooltip": "Converts a serialised JSON string back into a reassembled Lua object.",
"helpUrl": "https://tweaked.cc/module/textutils.html#v:unserializeJSON"
},
"textutils_url_encode": {
"message0": "Encode URL %1",
"args0": [
{
"type": "input_value",
"name": "URL",
"check": "String"
}
],
"output": "String",
"colour": 32,
"tooltip": "Replaces certain characters in a string to make it safe for use in URLs or POST data."
},
"textutils_complete": {
"message0": "Complete %1 in table %2",
"args0": [
{
"type": "input_value",
"name": "SEARCH_TEXT",
"check": "String"
},
{
"type": "input_value",
"name": "SEARCH_TABLE",
"check": "Table"
}
],
"output": "Array",
"colour": 32,
"tooltip": "Provides a list of possible completions for a partial Lua expression.",
"helpUrl": "https://tweaked.cc/module/textutils.html#v:complete"
}
}

View File

@ -0,0 +1,107 @@
// this file not for generator only
const { luaGenerator } = require('blockly/lua');
// Check if luaGenerator.forBlock is defined and initialize if necessary
if (!luaGenerator.forBlock) {
luaGenerator.forBlock = {};
}
luaGenerator.forBlock['textutils_slow_write'] = function(block, generator) {
var text = generator.valueToCode(block, 'TEXT', generator.ORDER_ATOMIC);
var rate = generator.valueToCode(block, 'RATE', generator.ORDER_ATOMIC);
return `textutils.slowWrite(${text}, ${rate})\n`;
};
luaGenerator.forBlock['textutils_slow_print'] = function(block, generator) {
var text = generator.valueToCode(block, 'TEXT', generator.ORDER_ATOMIC);
var rate = generator.valueToCode(block, 'RATE', generator.ORDER_ATOMIC);
return `textutils.slowPrint(${text}, ${rate})\n`;
};
luaGenerator.forBlock['textutils_format_time'] = function(block, generator) {
var time = generator.valueToCode(block, 'TIME', generator.ORDER_ATOMIC);
var is24hour = generator.valueToCode(block, '24H', generator.ORDER_ATOMIC);
return [`textutils.formatTime(${time}, ${is24hour})`, luaGenerator.ORDER_NONE];
};
luaGenerator.forBlock['textutils_paged_print'] = function(block, generator) {
var text = generator.valueToCode(block, 'TEXT', generator.ORDER_ATOMIC);
var freeline = generator.valueToCode(block, 'FREELINES', generator.ORDER_ATOMIC);
return `textutils.pagedPrint(${text}, ${freeline})\n`;
};
luaGenerator.forBlock['textutils_tabulate'] = function(block, generator) {
var args = generator.valueToCode(block, 'ARGS', generator.ORDER_ATOMIC);
return `textutils.tabulate(${args})\n`;
};
luaGenerator.forBlock['textutils_paged_tabulate'] = function(block, generator) {
var args = generator.valueToCode(block, 'ARGS', generator.ORDER_ATOMIC);
return `textutils.pagedTabulate(${args})\n`;
};
luaGenerator.forBlock['textutils_empty_json_array'] = function(block, generator) {
return [`textutils.textutils_empty_json_array`, luaGenerator.ORDER_NONE];
};
luaGenerator.forBlock['textutils_json_null'] = function(block, generator) {
return [`textutils.json_null`, luaGenerator.ORDER_NONE];
};
luaGenerator.forBlock['textutils_serialize'] = function(block, generator) {
var object = generator.valueToCode(block, 'OBJECT', generator.ORDER_ATOMIC);
var compact = block.getFieldValue('COMPACT') == 'TRUE';
var repetitions = block.getFieldValue('ALLOWREPETI') == 'TRUE';
return [`textutils.serialize(${object}, {compact=${compact}, allow_repetitions=${repetitions}})`, luaGenerator.ORDER_NONE];
};
luaGenerator.forBlock['textutils_unserialize'] = function(block, generator) {
var object = generator.valueToCode(block, 'OBJECT', generator.ORDER_ATOMIC);
return [`textutils.unserialize(${object})`, luaGenerator.ORDER_NONE];
};
luaGenerator.forBlock['textutils_serialize_json'] = function(block, generator) {
var object = generator.valueToCode(block, 'OBJECT', generator.ORDER_ATOMIC);
var nbt = block.getFieldValue('NBT') == 'TRUE';
var unicode = block.getFieldValue('UNICODE') == 'TRUE';
var repetitions = block.getFieldValue('ALLOWREPETI') == 'TRUE';
return [`textutils.serializeJSON(${object}, {nbt_style=${nbt}, unicode_strings=${unicode}, allow_repetitions=${repetitions}})`, luaGenerator.ORDER_NONE];
};
luaGenerator.forBlock['textutils_unserialize_json'] = function(block, generator) {
var object = generator.valueToCode(block, 'OBJECT', generator.ORDER_ATOMIC);
var nbt = block.getFieldValue('NBT') == 'TRUE';
var parse_null = block.getFieldValue('PARSENULL') == 'TRUE';
var parse_empty_array = block.getFieldValue('PARSEEA') == 'TRUE';
return [`textutils.unserializeJSON(${object}, {nbt_style=${nbt}, parse_null=${parse_null}, parse_empty_array=${parse_empty_array}})`, luaGenerator.ORDER_NONE];
};
luaGenerator.forBlock['textutils_url_encode'] = function(block, generator) {
var url = generator.valueToCode(block, 'URL', generator.ORDER_ATOMIC);
return [`textutils.urlEncode(${url})`, luaGenerator.ORDER_NONE];
};
luaGenerator.forBlock['textutils_complete'] = function(block, generator) {
var value_search_text = generator.valueToCode(block, 'SEARCH_TEXT', Blockly.Lua.ORDER_ATOMIC) || '""';
var value_search_table = generator.valueToCode(block, 'SEARCH_TABLE', Blockly.Lua.ORDER_ATOMIC) || '_G';
if (value_search_table == "") {
return [`textutils.complete(${value_search_text})`];
} else {
return [`textutils.complete(${value_search_text}, ${value_search_table})`];
}
};

View File

@ -0,0 +1,22 @@
{
"name": "CC: Textutils",
"author": "DPSoftware Foundation",
"description": "Helpful utilities for formatting and manipulating strings.",
"version": "1.0.0",
"category": "utils",
"keyword": "utils",
"license": "GPL-3.0-or-later",
"peripherals": false,
"library": true,
"require_network": false,
"dependencies": {},
"design_for_computer": {
"basic": true,
"adv": true,
"command": true,
"pocket": true,
"advpocket": true,
"turtle": true,
"advturtle": true
}
}

View File

@ -0,0 +1,37 @@
<xml id="toolbox" style="display: none;">
<category name="Textutils" colour="32">
<block type="textutils_slow_write">
<value name="RATE">
<shadow type="math_number">
<field name="NUM">20</field>
</shadow>
</value>
</block>
<block type="textutils_slow_print">
<value name="RATE">
<shadow type="math_number">
<field name="NUM">20</field>
</shadow>
</value>
</block>
<block type="textutils_paged_print">
<value name="FREELINES">
<shadow type="math_number">
<field name="NUM">20</field>
</shadow>
</value>
</block>
<block type="textutils_tabulate"></block>
<block type="textutils_paged_tabulate"></block>
<block type="textutils_empty_json_array"></block>
<block type="textutils_json_null"></block>
<block type="textutils_serialize"></block>
<block type="textutils_unserialize"></block>
<block type="textutils_serialize_json"></block>
<block type="textutils_unserialize_json"></block>
<block type="textutils_url_encode"></block>
<block type="textutils_complete"></block>
<block type="textutils_format_time"></block>
</category>
</xml>

Binary file not shown.

View File

@ -16,6 +16,22 @@ let isopennewproject = false;
app.whenReady().then(() => {
reloadall(false);
var splash = new BrowserWindow({
width: 600,
height: 300,
icon: path.join(__dirname, 'assets', 'ccIDEIcon.ico'),
transparent: true,
frame: false,
center: true,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
}
});
splash.loadFile('src/splash.html');
splash.webContents.send("change-status", "Initializing...")
const win = new BrowserWindow({
width: 1280,
height: 720,
@ -30,20 +46,17 @@ app.whenReady().then(() => {
center: true,
})
var splash = new BrowserWindow({
width: 600,
height: 300,
icon: path.join(__dirname, 'assets', 'ccIDEIcon.ico'),
transparent: true,
frame: false,
center: true
});
try {
win.loadFile('src/index.html');
splash.loadFile('src/splash.html');
} catch {
try {
win.loadFile('dist_src/index.html');
} catch {
dialog.showErrorBox("Error on startup", "Can't find index.html");
}
}
win.setTitle(`ccIDE`)
ipc.once('ready', () => {
console.log("ready")
if (splash) {
@ -58,7 +71,9 @@ app.whenReady().then(() => {
//win.openDevTools();
});
ipc.on('update-startup-status', (event, status) => {
splash.webContents.send("change-status", status)
});
//app.on('activate', () => {
// if (BrowserWindow.getAllWindows().length === 0) {
@ -80,7 +95,6 @@ app.whenReady().then(() => {
}
}
// Define a custom menu template
const menuTemplate = [
{

2270
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -5,14 +5,19 @@
"main": "index.js",
"scripts": {
"dev": "electron .",
"build": "electron-packager . ccIDE --platform=win32 --arch=x64 --icon=assets/ccIDEIcon.ico --out=dist --overwrite"
"build": "electron-packager . ccIDE --platform=win32 --arch=x64 --icon=assets/ccIDEIcon.ico --out=dist --overwrite",
"full_build": "webpack --mode production && electron-packager . ccIDE --platform=win32 --arch=x64 --icon=assets/ccIDEIcon.ico --out=dist --overwrite"
},
"author": "DPSoftware Foundation",
"license": "GPL-3.0-or-later",
"devDependencies": {
"electron": "^31.1.0"
"electron": "^31.1.0",
"webpack": "^5.93.0",
"webpack-cli": "^5.1.4",
"webpack-node-externals": "^3.0.0"
},
"dependencies": {
"@blockly/plugin-workspace-search": "^9.0.5",
"@electron/remote": "^2.1.2",
"blockly": "^11.1.1",
"bootstrap": "^5.3.3",

View File

@ -2,8 +2,22 @@ local ws = assert(http.websocket("ws://127.0.0.1:5133"))
print("connected to server")
local id
local isrunning = true
while true do
function exitcheck()
while true do
local event = os.pullEventRaw("terminate")
if event == "terminate" then
print("Exiting...")
isrunning = false
ws.close()
break
end
end
end
function main()
while isrunning do
print("ready")
local message, error = ws.receive()
if message then
@ -27,6 +41,8 @@ while true do
print("WebSocket error:", error)
break
end
end
end
ws.close()
parallel.waitForAny(exitcheck, main)
print("Exited")

View File

@ -10,19 +10,61 @@ class CCRemote {
console.log("Server is started");
this.socket.on('connection', (ws) => {
document.getElementById("navbar-button-computer-disconnect").disabled = false;
document.getElementById("navbar-button-computer-run").disabled = false;
document.getElementById('statusMessage').textContent = "Computer connected";
setTimeout(() => {
document.getElementById('statusMessage').textContent = `Ready`;
}, 1000);
console.log('WebSocket connection established.');
// Set up heartbeat
ws.isAlive = true;
ws.on('pong', () => {
ws.isAlive = true;
});
ws.on('message', (message) => {
console.log(`Received message => ${message}`);
});
ws.on('close', () => {
document.getElementById("navbar-button-computer-disconnect").disabled = true;
document.getElementById("navbar-button-computer-run").disabled = true;
document.getElementById('statusMessage').textContent = "Computer disconnected";
setTimeout(() => {
document.getElementById('statusMessage').textContent = `Ready`;
}, 1000);
});
ws.on('error', (error) => {
console.error('Client error:', error);
});
});
// Ping clients every 30 seconds to check if they are alive
const interval = setInterval(() => {
this.socket.clients.forEach((ws) => {
if (ws.isAlive === false) {
console.log('Client did not respond to ping, terminating connection.');
return ws.terminate();
}
ws.isAlive = false;
ws.ping();
});
}, 1000);
this.socket.on('close', () => {
console.log('WebSocket connection closed.');
clearInterval(interval);
console.log('WebSocket server closed.');
});
this.socket.on('error', (error) => {
console.error('WebSocket error:', error);
console.error('WebSocket server error:', error);
});
}
@ -36,7 +78,6 @@ class CCRemote {
}
sendCommand(command) {
// Iterate over each connected client and send the command
this.socket.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(command);
@ -45,27 +86,20 @@ class CCRemote {
}
sendCode(Code) {
// Iterate over each connected client and send the command
this.socket.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send("sendcode");
setTimeout(() => {
client.send(Code);
return true
}, 500);
} else {
return false
}
});
}
runCode() {
// Iterate over each connected client and send the command
this.socket.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send("runcode");
return true;
} else {
return false;
}
});
}
@ -77,7 +111,6 @@ class CCRemote {
}
});
}
}
module.exports = { CCRemote };

View File

@ -21,13 +21,15 @@
<button class="navbar-button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Packages Managers" style="background-color: #0087bd;" onclick="openlibraryselect()">
<svg viewBox="0 0 24 24"><path d="M21 16.5c0 .38-.21.71-.53.88l-7.9 4.44c-.16.12-.36.18-.57.18-.21 0-.41-.06-.57-.18l-7.9-4.44A.991.991 0 0 1 3 16.5v-9c0-.38.21-.71.53-.88l7.9-4.44c.16-.12.36-.18.57-.18.21 0 .41.06.57.18l7.9 4.44c.32.17.53.5.53.88v9M12 4.15l-1.89 1.07L16 8.61l1.96-1.11L12 4.15M6.04 7.5 12 10.85l1.96-1.1-5.88-3.4L6.04 7.5M5 15.91l6 3.38v-6.71L5 9.21v6.7m14 0v-6.7l-6 3.37v6.71l6-3.38z" /></svg>
</button>
<button class="navbar-button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Preview code" style="background-color: #0087bd; margin-left: auto; position: absolute; right: 115px;" onclick="clientexit()">
<!--
<button class="navbar-button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Preview code" style="background-color: #0087bd; margin-left: auto; position: absolute; right: 115px;">
<svg viewBox="0 0 24 24"><path d="M12 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0 8a5 5 0 0 1-5-5 5 5 0 0 1 5-5 5 5 0 0 1 5 5 5 5 0 0 1-5 5m0-12.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5z" /></svg>
</button>
<button class="navbar-button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Disconnect Client" style="background-color: #bd0000; margin-left: auto; position: absolute; right: 65px;" onclick="clientexit()">
-->
<button class="navbar-button" id="navbar-button-computer-disconnect" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Disconnect Client" style="background-color: #bd0000; margin-left: auto; position: absolute; right: 65px;" onclick="clientexit()" disabled>
<svg viewBox="0 0 24 24"><path d="M19 3H5c-1.11 0-2 .89-2 2v4h2V5h14v14H5v-4H3v4a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2m-8.92 12.58L11.5 17l5-5-5-5-1.42 1.41L12.67 11H3v2h9.67l-2.59 2.58z" /></svg>
</button>
<button class="navbar-button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Run" style="background-color: #10bd00; margin-left: auto;" onclick="gencode()">
<button class="navbar-button" id="navbar-button-computer-run" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Run" style="background-color: #10bd00; margin-left: auto;" onclick="gencode()" disabled>
<svg viewBox="0 0 24 24"><path d="M8 5.14v14l11-7-11-7z" /></svg>
</button>
</nav>
@ -131,12 +133,8 @@
</div>
</div>
<script src="frontend.js"></script>
<script src="virtualcode.js"></script>
<script src="index.js"></script>
<script src="codegen.js"></script>
</body>
</html>

View File

@ -1,38 +1,29 @@
const { ipcRenderer } = require("electron");
const ipc = ipcRenderer;
// override prompt command
window.prompt = function(promptText, defaultValue) {
return ipc.sendSync("prompt", promptText, defaultValue);
};
ipc.send("update-startup-status", "Importing module...")
const fs = require('fs');
const path = require('path');
const { ipcRenderer } = require("electron");
const { loadperipheral, scanindex } = require("./blocksmanager");
const Blockly = require('blockly');
const ipc = ipcRenderer;
const { WorkspaceSearch } = require("@blockly/plugin-workspace-search")
let isprojectsaved = false;
let isprojectopened = false;
let usedlibinproject = []
ipc.send("update-startup-status", "Initializing blockly workspace...")
Blockly.utils.colour.setHsvSaturation(0.9)
let originaltoolbar = fs.readFileSync(path.join(__dirname, "toolbox.xml"), 'utf8');
// load some system library
const sysmodulejson = fs.readFileSync(path.join(__dirname, "module_block_design.json"), 'utf8');
const blocksJson = JSON.parse(sysmodulejson);
for (const blockId in blocksJson) {
if (blocksJson.hasOwnProperty(blockId)) {
Blockly.Blocks[blockId] = {
init: function() {
this.jsonInit(blocksJson[blockId]);
}
};
}
}
require("./module_generator")
var workspace = Blockly.inject('blocklyDiv', {
try {
var workspace = Blockly.inject('blocklyDiv', {
toolbox: originaltoolbar,
trashcan: true,
grid: {
@ -50,14 +41,38 @@ var workspace = Blockly.inject('blocklyDiv', {
scaleSpeed: 1.1,
pinch: true
}
});
});
const workspaceSearch = new WorkspaceSearch(workspace);
workspaceSearch.init();
workspace.getToolbox().getFlyout().autoClose = false;
} catch (e) {
ipc.send("erroronstart", `Error on initializing workspace: ${e}`)
}
try {
ipc.send("update-startup-status", "Importing system library...")
const sysmodulejson = fs.readFileSync(path.join(__dirname, "module_block_design.json"), 'utf8');
const blocksJson = JSON.parse(sysmodulejson);
for (const blockId in blocksJson) {
if (blocksJson.hasOwnProperty(blockId)) {
Blockly.Blocks[blockId] = {
init: function() {
this.jsonInit(blocksJson[blockId]);
}
};
}
}
require("./module_generator")
ipc.send("update-startup-status", "Scanning library...")
scanindex();
} catch (e) {
ipc.send("erroronstart", `Error on loading block: ${e}`)
}
workspace.getToolbox().getFlyout().autoClose = false;
ipc.send("update-startup-status", "Initializing event...")
ipc.on('export-lua-request', (event) => {
console.log("exporting lua")
@ -111,6 +126,21 @@ ipc.on('load-workspace', (event, json) => {
}, 1000);
})
ipc.on('workspace-saved', (event, success) => {
isprojectsaved = success
if (!isprojectopened) {
isprojectopened = true;
}
document.getElementById('statusMessage').textContent = `Project Saved`;
setTimeout(() => {
document.getElementById('statusMessage').textContent = `Ready`;
}, 1000);
});
ipc.on("open-about", () => {
document.getElementById('about-popup').style.display = 'block';
})
workspace.addChangeListener(function(event) {
if ([Blockly.Events.UI,
Blockly.Events.VIEWPORT_CHANGE,
@ -149,24 +179,15 @@ document.getElementById("packageman-import-btn").addEventListener('click', () =>
document.getElementById('statusMessage').textContent = `Ready`;
}, 1000);
});
});
ipc.on('workspace-saved', (event, success) => {
isprojectsaved = success
if (!isprojectopened) {
isprojectopened = true;
}
document.getElementById('statusMessage').textContent = `Project Saved`;
setTimeout(() => {
document.getElementById('statusMessage').textContent = `Ready`;
}, 1000);
});
ipc.on("open-about", () => {
document.getElementById('about-popup').style.display = 'block';
})
// Ensure Blockly container is shown after the workspace is injected
document.getElementById('statusMessage').textContent = `Ready`;
ipc.send("ready")
ipc.send("update-startup-status", "Finished")
setTimeout(() => {
ipc.send("ready")
}, 500);
document.getElementById('statusMessage').textContent = "Computer isn't connect";
setTimeout(() => {
document.getElementById('statusMessage').textContent = `Ready`;
}, 10000);

View File

@ -67,7 +67,7 @@
"colour": 260
},
"sys_table_add_key_value": {
"message0": "Add key %1 with data %2",
"message0": "Add key %1 with data %2\nShorthand %3",
"args0": [
{
"type": "input_value",
@ -77,6 +77,10 @@
{
"type": "input_value",
"name": "VALUE"
},
{
"type": "field_checkbox",
"name": "SHORT"
}
],
"output": "Array_Pair",
@ -95,7 +99,8 @@
"check": "Array"
}
],
"output": "Array",
"previousStatement": null,
"nextStatement": null,
"colour": 260
},
"ide_addcode": {
@ -121,5 +126,37 @@
],
"colour": 220,
"tooltip": "Not require but make your code easy to read."
},
"sys_exit": {
"message0": "Exit the code",
"previousStatement": null,
"colour": 38
},
"sys_write": {
"message0": "Write %1",
"args0": [
{
"type": "input_value",
"name": "TEXT",
"check": "String"
}
],
"previousStatement": null,
"nextStatement": null,
"colour": 110,
"tooltip": "Writes a line of text to the screen without a newline at the end, wrapping text if necessary."
},
"sys_print_error": {
"message0": "Print error %1",
"args0": [
{
"type": "input_value",
"name": "ERROR"
}
],
"previousStatement": null,
"nextStatement": null,
"colour": 110,
"tooltip": "Prints the specified values to the screen in red, separated by spaces, wrapping if necessary. After printing, the cursor is moved to the next line."
}
}

View File

@ -41,8 +41,12 @@ luaGenerator.forBlock['sys_table_unpack_to_args'] = function(block, generator) {
luaGenerator.forBlock['sys_table_add_key_value'] = function(block, generator) {
var key = generator.valueToCode(block, 'KEY', generator.ORDER_NONE);
var value = generator.valueToCode(block, 'VALUE', generator.ORDER_NONE);
var shorted = block.getFieldValue('SHORT') == 'TRUE';
if (!shorted) {
return [`[${key}] = ${value}`, luaGenerator.ORDER_NONE];
} else {
return [`${key} = ${value}`, luaGenerator.ORDER_NONE];
}
};
luaGenerator.forBlock['sys_table_append_data'] = function(block, generator) {
@ -81,3 +85,20 @@ main()
`
return code;
};
luaGenerator.forBlock['sys_exit'] = function(block, generator) {
return `exit()\n`;
};
luaGenerator.forBlock['sys_write'] = function(block, generator) {
var text = generator.valueToCode(block, 'TEXT', generator.ORDER_NONE);
return `write(${text})\n`;
};
luaGenerator.forBlock['sys_print_error'] = function(block, generator) {
var error = generator.valueToCode(block, 'ERROR', generator.ORDER_NONE);
return `printError(${error})\n`;
};

View File

@ -64,9 +64,18 @@
<div class="progress-bar">
<div class="progress-bar-value"></div>
</div>
<h6 id="status">Initializing...</h6>
</div>
<div id="copyright">
&copy; 2024 DPSoftware Foundation. Licensed under GPL v3.
</div>
<script>
const { ipcRenderer } = require("electron");
const ipc = ipcRenderer;
ipc.on('change-status', (event, status) => {
document.getElementById('status').textContent = status;
});
</script>
</body>
</html>

View File

@ -37,6 +37,16 @@ body {
font-size: 1.5em; /* Adjust size as needed */
}
.navbar-button:disabled {
background-color: #7f8c8d; /* Gray color for disabled state */
cursor: not-allowed;
opacity: 0.6; /* Makes the button look disabled */
}
.navbar-button:disabled svg {
fill: #ffffff; /* Change icon color if needed */
}
.navbar-button:hover {
background-color: #0066cc; /* Darken color on hover */
z-index: 99;

View File

@ -3,14 +3,28 @@
<block type="text_print">
<value name="TEXT">
<shadow type="text">
<field name="TEXT">abc</field>
<field name="TEXT">Hello World!</field>
</shadow>
</value>
</block>
<block type="text_prompt_ext">
<value name="TEXT">
<shadow type="text">
<field name="TEXT">abc</field>
<field name="TEXT">Hello World!</field>
</shadow>
</value>
</block>
<block type="sys_write">
<value name="TEXT">
<shadow type="text">
<field name="TEXT">Hello World!</field>
</shadow>
</value>
</block>
<block type="sys_print_error">
<value name="ERROR">
<shadow type="text">
<field name="TEXT">Hello World!</field>
</shadow>
</value>
</block>
@ -60,9 +74,7 @@
</block>
<block type="controls_forEach"></block>
<block type="controls_flow_statements"></block>
</category>
<category name="Events" colour="45">
<block type="sys_exit"></block>
</category>
<category name="Math" colour="230">
<block type="math_number" gap="32">
@ -176,7 +188,7 @@
<block type="text_length">
<value name="VALUE">
<shadow type="text">
<field name="TEXT">abc</field>
<field name="TEXT">Hello World!</field>
</shadow>
</value>
</block>
@ -195,7 +207,7 @@
</value>
<value name="FIND">
<shadow type="text">
<field name="TEXT">abc</field>
<field name="TEXT">Hello World!</field>
</shadow>
</value>
</block>
@ -216,7 +228,7 @@
<block type="text_changeCase">
<value name="TEXT">
<shadow type="text">
<field name="TEXT">abc</field>
<field name="TEXT">Hello World!</field>
</shadow>
</value>
</block>

30
webpack.config.js Normal file
View File

@ -0,0 +1,30 @@
const path = require('path');
const nodeExternals = require('webpack-node-externals');
module.exports = {
mode: 'development',
entry: './index.js',
target: 'electron-main',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
externals: [nodeExternals()],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
},
resolve: {
extensions: ['.js', '.json']
},
};